How to attach a secret to running pod?
I have a pod running and i want to attach a secret.
I don't want to terminate the running pod instance.
I know pod are meant to run as stateless.
According to the documentation:
Secrets can be mounted as data volumes or be exposed as environment variables to be used by a container in a pod.
This is an example of a pod that mounts a secret in a volume:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
Mounted Secrets are updated automatically
When a secret being already consumed in a volume is updated, projected keys are eventually updated as well. Kubelet is checking whether the mounted secret is fresh on every periodic sync. However, it is using its local cache for getting the current value of the Secret. The type of the cache is configurable using the (ConfigMapAndSecretChangeDetectionStrategy field in KubeletConfiguration struct). It can be either propagated via watch (default), ttl-based, or simply redirecting all requests to directly kube-apiserver. As a result, the total delay from the moment when the Secret is updated to the moment when new keys are projected to the Pod can be as long as kubelet sync period + cache propagation delay, where cache propagation delay depends on the chosen cache type (it equals to watch propagation delay, ttl of cache, or zero corespondingly).
Note: A container using a Secret as a subPath volume mount will not receive Secret updates.
This is an example of a pod that uses secrets from environment variables:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
For both cases you need to change pod specification. You can do it by editing Pod or Deployment with kubectl edit:
$ kubectl edit pod <pod_name> -n <namespace_name>
$ kubectl edit deployment <deployment_name> -n <namespace_name>
Alternatively you can make changes in YAML file and apply it:
$ vi MyPod.yaml
$ kubectl apply -f MyPod.yaml
The most important thing you need to know, if you change the Pod specification, your Pod will be restarted to apply changes. In case of Deployment rolling update will happen. In most cases it is okay. If you need to save state of your application, the best way is to store valuable information using Volumes.
If you still want to add secrets without Pod restarts, you can use shared storage like NFS. When you change the content of NFS volume that already mounted into the Pod, the changes will be visible inside the pod instantly. In certain cases you can exec shell inside the pod and mount NFS volume manually.
Alternatively, you can export the content of the secret to the file using the ksd program
(or base64 -d
) to decode base64 encoded values in the Secret:
kubectl get secret mysecret -o yaml | ksd > filename.yaml
and copy it to the pod using the following command:
kubectl cp filename.yaml <some-namespace>/<some-pod>:/tmp/secret.yaml
Secret - is a volume. So, you cannot mount volume to running pod. You could run pod in privileged mode and mount whatever you want via command mount
within the container. It's crazy, though...