Mounting single Files as a Volume

Feb 23, 2019 00:00 · 363 words · 2 minute read kubernetes

Kubernetes Volumes represent directories on the Hostmachine which are used as storage (either read or write) by containers running on the host. When mounted, however, volumes hide directories that already exist inside the container. So, a Volume mounted at /etc/config would hide the container’s already present directory under /etc/config with all its containing data beeing invisible to the container.

This should not be too much of a problem (we can choose any mount point), until we want to make a single file available to containers by mounting it into the container’s filesystem right into an already present directory.

An example taken from the real world would be providing Nginx with a configuration. The setup consists of the actual deployment along with a configmap providing the contents of the config file.

The goal is to inject the configmap, as a single file containing the contents of the configmap, into the container running Nginx.

The first, naive, approach would be to set the mountpoint at /etc/nginx/nginx.conf,

This whole discussion assumes that the ConfigMap contains a single key

However, when we use the official nginx image, Kubernetes will complain that there is already a regular file in the container’s file system which is not a directory (and therefore is not a valid mount point).

Injecting a single file

Given the key nginx.conf in the configmap having the config as its value, we want Kubernetes to add a single file nginx.conf into /etc/nginx, retaining already present data inside the container.

The solution is to tell nginx not to mount the whole volume (which will be mounted as a directory) but to only inject a specific part of it.

Given the ConfigMap my-config-map

kind: ConfigMap
data:
    nginx.conf: |
        {
            // config
        }

We use the field subpath to tell Kubernetes to mount the contents of the key config under /etc/nginx/nginx.conf into the container. In a more general way, subpath refers to a path inside the mounted volume (not to a path inside the container).

apiVersion: apps/v1
kind: Deployment
metadata:
    name: foo
    labels:
        app: foo
spec:
    template:
        spec:
            containers:
                - name: container-name
                  image: imagename
                  volumeMounts:
                      - name: cfg-volume
                        mountPath: /etc/nginx/nginx.conf
                        subpath: nginx.conf
            volumes:
                - name: cfg-volume
                  configMap:
                      name: my-config-map

If you want to get in touch with me, send me an email

longo.tomas@googlemail.com