Optional Secrets as Volumes or Environment variables

kubernetes secret optional volume envirnment variable

3 min read | by Jordi Prats

Secrets contain sensitive data such as passwords, tokens, and certificates. They can be used by Kubernetes pods to authenticate with other systems. However, some of them might be optional so we'll want to be able to create the Pod without having to use some template engine to handle whether the secret is present or not.

Optional secret as an environment variable

If we try to create a Pod using a secret that doesn't exists it won't start until the secret is created:

$ kubectl get pods
NAME   READY   STATUS                       RESTARTS   AGE
demo   0/1     CreateContainerConfigError   0          3s
$ kubectl describe pod demo
Name:             demo
Namespace:        test
(...)
Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  10s               default-scheduler  Successfully assigned test/demo to kind-control-plane
  Normal   Pulled     9s                kubelet            Successfully pulled image "alpine:latest" in 801.015959ms
  Normal   Pulling    8s (x2 over 10s)  kubelet            Pulling image "alpine:latest"
  Warning  Failed     8s (x2 over 9s)   kubelet            Error: secret "some-secret" not found
  Normal   Pulled     8s                kubelet            Successfully pulled image "alpine:latest" in 799.1035ms

We can add the optional flag in order to tell Kubernetes to do not set the variable if the Secret is missing:

apiVersion: v1
kind: Pod
metadata:
  name: demo
spec:
  containers:
  - name: container
    image: alpine:latest
    command:
    - sh
    - '-c'
    - "while true; do echo $ENV_NAME; sleep 1; done"
    env:
    - name: ENV_NAME
      valueFrom:
        secretKeyRef:
          name: some-secret
          key: key
          optional: true

So this way the Pod will start without setting the variable:

$ kubectl get pods
NAME   READY   STATUS              RESTARTS   AGE
demo   0/1     ContainerCreating   0          3s
$ kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
demo   1/1     Running   0          4s

Optional secret as a volume

Similarly, we can do the same mounting the optional secret as a volume:

apiVersion: v1
kind: Pod
metadata:
  name: demo
spec:
  containers:
  - name: container
    image: alpine:latest
    command:
    - sh
    - '-c'
    - "while true; do ls /etc/some-secret; echo ; cat /etc/some-secret/*; echo; sleep 1; done"
    volumeMounts:
      - name: some-secret
        mountPath: /etc/some-secret
  volumes:
    - name: some-secret
      secret:
        secretName: some-secret
        optional: true

If we tail the container we'll be able to see how it cannot find any file (Secret):

$ kubectl logs -f demo


cat: can't open '/etc/some-secret/*': No such file or directory

(...)

Without having to restart the container, we can create the Secret:

$ kubectl create secret generic some-secret --from-literal=key=value

Then, as soon as Kubernetes converge, the file will show up with the Secret:

cat: can't open '/etc/some-secret/*': No such file or directory

value
key

(...)

Posted on 06/03/2023

Categories