can two kubernetes volumes mount to the same place

6/9/2018

I'm pretty new to Kubernetes, trying to figure it out. I haven't been able to google this answer tho, so I'm stumped. Can Kubernetes mount two secrets to the same path? say given the following deployment:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-deployment
    version: v1
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      volumes:
      - name: nginxlocal
        hostPath:
          path: /srv/docker/nginx
      - name: requestcert
        secret:
          secretName: requests-certificate
      - name: mysitecert
        secret:
          secretName: mysitecert
      containers:
      - name: nginx
        image: nginx:mainline-alpine # Use 1.15.0
        volumeMounts:
        - name: nginxlocal
          subPath: config/nginx.conf
          mountPath: /etc/nginx/nginx.conf
        - name: requestcert
          mountPath: /etc/nginx/ssl
        - name: mysitecert
          mountPath: /etc/nginx/ssl
        - name: nginxlocal
          subPath: logs
          mountPath: /etc/nginx/logs
        ports:
        - containerPort: 443

would it be possible to mount both SSL certs to the same directory (/etc/nginx/ssl/*)?

If not, can storing the TLS cert+key as "Opaque" instead of kubernetes.io/tls type work? I tried to combine both certs+keys into one secret of tls type, but kubernetes expected it to be called tls.crt and tls.key, so I had to split it into two secret files. if they could be done as opaque, i think I could remove the two secret values and just use the one opaque entry.

Thanks!

-- Evan R.
kubernetes
ssl

1 Answer

6/9/2018

would it be possible to mount both SSL certs to the same directory (/etc/nginx/ssl/*)?

No, because (at least when using a docker runtime) it uses volume mounts, which behave exactly the same as mount -t ext4 /dev/something /path/something in that /path/something will be last-one-wins.

However, you have an only mildly smelly work-around available to you: mount secret requestcert as /etc/nginx/.reqcert (or similar), mount secret mysitecert as /etc/nginx/.sitecert, then supersede the entrypoint of the image and copy the files into place before delegating down to the actual entrypoint:

containers:
- name: nginx
  image: etc etc
  command:
  - bash
  - -c
  - |
    mkdir -p /etc/nginx/ssl
    cp /etc/nginx/.*cert/* /etc/nginx/ssl/
    # or whatever initialization you'd like

    # then whatever the entrypoint is for your image
    /usr/local/sbin/nginx -g "daemon off;"

Or, if that doesn't seem like a good idea, you can leverage a disposable, Pod-specific directory in combination with initContainers::

spec:
  volumes:
  # all the rest of them, as you had them
  - name: temp-config
    emptyDir: {}
  initContainers:
  - name: setup-config
    image: busybox  # or whatever
    command:
    - sh
    - -c
    - |
       # "stage" all the config files, including certs
       # into /nginx-config which will evaporate on Pod destruction
    volumeMounts:
    - name: temp-config
      mountPath: /nginx-config
    # and the rest

  containers:
  - name: nginx
    # ...
    volumeMounts:
    - name: temp-config
      mountPath: /etc/nginx

They differ in complexity based on whether you want to have to deal with keeping track of the upstream image's entrypoint command, versus leaving the upstream image untouched, but expending a lot more initialization energy

-- mdaniel
Source: StackOverflow