The style for this post is tabled by Terminal CSS
⌂ Home

Mounting single Files as a Volume

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