Projecting Files into Existing Directories in Kubernetes Containers
Introduction
One standard method of "injecting" ConfigMap items is to mount the ConfigMap as a volume. This either creates a brand new directory with ConfigMap items as files in this directory, or overwrites an existing directory leaving only the ConfigMap items.
But what if you want the directory to contain BOTH the existing files as well as the ConfigMap files?
We will use the alpine Docker container to illustrate a couple of ways
to mount ConfigMap items as files into a directory that already exists in
the container.
Note: we use the abbreviation k in place of kubectl.
Note the contents of the existing directory /etc/ssl/misc before
adding any volumeMounts into it:
# file-mapping-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: file-mapping
spec:
containers:
- name: test-container
image: alpine
command: [ "sleep", "10000" ]
$ k apply -f file-mapping-pod.yml
$ k exec file-mapping -- ls -l /etc/ssl/misc
total 16
-rwxr-xr-x 1 root root 7598 Sep 13 05:48 CA.pl
lrwxrwxrwx 1 root root 8 Oct 21 13:39 tsget -> tsget.pl
-rwxr-xr-x 1 root root 6579 Sep 13 05:48 tsget.pl
Map a ConfigMap onto a file in an existing directory: only ConfigMap items remain
# file-mapping-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: file-mapping
spec:
containers:
- name: test-container
image: alpine
command: [ "sleep", "10000" ]
volumeMounts:
- name: file-mapping-volume
mountPath: /etc/ssl/misc
volumes:
- name: file-mapping-volume
configMap:
name: file-mapping-cm
$ k delete pod file-mapping
$ k apply -f file-mapping-pod.yml
$ k exec file-mapping -- ls -l /etc/ssl/misc
lrwxrwxrwx 1 root root 10 Nov 28 20:58 cm1 -> ..data/cm1
lrwxrwxrwx 1 root root 10 Nov 28 20:58 cm2 -> ..data/cm2
Note that all the existing files that were in the alpine Docker image
are gone and the only files that remain are the ConfigMap files.
If you describe the pod you will see how the mapping works:
$ k describe pod file-mapping
...
Mounts:
/etc/ssl/misc from file-mapping-volume (rw)
...
Map a ConfigMap onto a file in an existing directory: original directory items remain
Use the subPath attribute.
# file-mapping-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: file-mapping
spec:
containers:
- name: test-container
image: alpine
command: [ "sleep", "10000" ]
volumeMounts:
- name: file-mapping-volume
mountPath: /etc/ssl/misc/cm1.txt
subPath: cm1
- name: file-mapping-volume
mountPath: /etc/ssl/misc/cm2.txt
subPath: cm2
volumes:
- name: file-mapping-volume
configMap:
name: file-mapping-cm
$ k delete pod file-mapping
$ k apply -f file-mapping-pod.yml
$ k exec file-mapping -- ls -l /etc/ssl/misc
total 36
-rwxr-xr-x 1 root root 7598 Sep 13 05:48 CA.pl
-rw-r--r-- 1 root root 2114 Dec 2 17:35 cm1.txt
-rw-r--r-- 1 root root 15118 Dec 2 17:35 cm2.txt
lrwxrwxrwx 1 root root 8 Oct 21 13:39 tsget -> tsget.pl
-rwxr-xr-x 1 root root 6579 Sep 13 05:48 tsget.pl
Note that the original files from the alpine Docker container remain
and the additional files cm1.txt and cm2.txt from the ConfigMap are added.
If you describe the pod you will see how the mapping works:
$ k describe pod file-mapping
...
Mounts:
/etc/ssl/misc/cm1.txt from file-mapping-volume (rw,path="cm1")
/etc/ssl/misc/cm2.txt from file-mapping-volume (rw,path="cm2")
...
How to reproduce the above results
Install
jq(JSON query utility).Create a
file-mappingKubernetes namespace and set it as the default:$ k apply -f namespace.yml $ k describe ns file-mapping $ CURRENT_CONTEXT=`kubectl config -o=json view | jq -r '."current-context"'` $ k config set-context $CURRENT_CONTEXT --namespace=file-mapping $ k config -o=json view | jq ".contexts[]|select(.name==\"$CURRENT_CONTEXT\")"Create some configmap items:
$ ls /etc > /tmp/cm1.txt $ ls /bin > /tmp/cm2.txt $ k create cm file-mapping-cm --from-file=cm1=/tmp/cm1.txt --from-file=cm2=/tmp/cm2.txt $ k get cm file-mapping-cm -o=json | jq '.data|keys'