Here’s a quick and simple explanation on how to mount Kubernetes Secrets
and ConfigMaps
in a Pod as files. Imagine you have the following Kubernetes Secret
:
apiVersion: v1
kind: Secret
metadata:
name: my-secrets
stringData:
username: admin
password: password
"config.toml": |
[settings]
enable-health-checks = true
Mounting specific secrets by key
There are two ways to mount a Secret
in a Kubernetes Pod
. The first one is to mount the entire Secret
as multiple files, where each key creates a single file. The second one is to mount specific keys in the Secret
declaratively.
Mounting all secrets individually
Imagine now you want to mount the username
field to /app/username
, the password
field to /app/password
and the config.toml
to /app/config.toml
, or, in different words, using a format like /app/{secretKey}
where {secretKey}
is the key of the secret inside the manifest.
To mount these files explicitly, you would write the following Pod
:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: nginx-container
image: nginx:latest
volumeMounts:
- name: my-secrets
mountPath: /app
readOnly: true
volumes:
- name: my-secrets
secret:
secretName: my-secrets
items:
- key: username
path: username
- key: password
path: password
- key: config.toml
path: config.toml
Accessing the pod and checking all the files in the /app
directory shows the correct files:
$ kubectl exec -it my-pod -- ls -l /app
total 0
lrwxrwxrwx 1 root root 18 Apr 7 03:38 config.toml -> ..data/config.toml
lrwxrwxrwx 1 root root 15 Apr 7 03:38 password -> ..data/password
lrwxrwxrwx 1 root root 15 Apr 7 03:38 username -> ..data/username
The files are symbolic links to the actual files mounted from the Secret
. This is so Kubernetes can update the files when the Secret
changes and avoid restarting the Kubernetes Pod
to have the pod pick up the changes.
Mounting all secrets inside the Secret
You can also avoid specifying each key and have Kubernetes load all the keys in the Secret
:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: nginx-container
image: nginx:latest
volumeMounts:
- name: my-secrets
mountPath: /app
readOnly: true
volumes:
- name: my-secrets
secret:
secretName: my-secrets
This has the benefit that any new key added to the Secret
will be automatically mounted in the Pod
without having to update the Pod
manifest. The outcome is the same as the previous example: all the files are mounted in the /app
directory as symlinks to the actual files.
Using subPath
Mounting Secrets
or ConfigMaps
as described before means that the folder, /app
, must not exist in the container image. If it does, the contents of that folder will be removed and replaced with the contents of the Secret
or ConfigMap
.
To perform a more incisive mount without deleting existing files, you can use the subPath
option. This option allows you to mount a Secret
or ConfigMap
in a subdirectory of the container image.
For example, if you want to mount the username
field to /app/username
, the password
field to /app/password
and the config.toml
to /app/config.toml
, you would write the following Pod
:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: nginx-container
image: nginx:latest
volumeMounts:
- name: my-secrets
mountPath: /app/username
subPath: username
readOnly: true
- name: my-secrets
mountPath: /app/password
subPath: password
readOnly: true
- name: my-secrets
mountPath: /app/config.toml
subPath: config.toml
readOnly: true
volumes:
- name: my-secrets
secret:
secretName: my-secrets
This solution is more verbose, and you will have to define your volumeMounts
for each key in the Secret
or ConfigMap
. However, it allows you to mount the Secret
or ConfigMap
in a subdirectory of the container image without deleting the existing files. You can verify this by checking the Pod
:
$ kubectl exec -it my-pod -- ls -l /app
total 12
-rw-r--r-- 1 root root 39 Apr 7 03:51 config.toml
-rw-r--r-- 1 root root 8 Apr 7 03:51 password
-rw-r--r-- 1 root root 5 Apr 7 03:51 username
Note how the files are not symbolic links anymore, but actual files.