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