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