4

I'm using ConfigMap to expose a php file intended to be shared across pods and writable by the www-data (Apache) user.

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: magento-config
data:
  env.php: |
    <?php
    return array ( ...

Deployment

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: apache-deployment
spec:
    ...
    spec:
      containers:
        - name: apache
          image: apache:2.4
          ...
          volumeMounts:
          - name: magento-configs
            mountPath: /var/www/html/etc
          imagePullPolicy: Always
      volumes:
        - name: magento-configs
          configMap:
            name: magento-config

The file appears writable only by root though

root@apache-deployment-79c8548cdc-r6qhs:/# realpath /var/www/html/etc/env.php
/var/www/html/etc/..2018_04_23_16_21_10.435323593/env.php
root@apache-deployment-79c8548cdc-r6qhs:/# ls -l /var/www/html/etc/..2018_04_23_16_21_10.435323593/env.php
-rw-r--r-- 1 root root 909 Apr 23 16:21

Is there any way to change this? I noticed VolumeMount has a readOnly property which defaults to false. Indeed the volume is writable, but only by root.

I tried setting APACHE_RUN_USER to root in Apache, but it wants me to recompile (currently using build from apt) lol, which feels like the wrong direction. I'd like to just figure out how to use ConfigMap correctly if possible.

quickshiftin
  • 2,025
  • 5
  • 27
  • 41

2 Answers2

5

Update:

So you must be using a prior version of Kubernetes < 1.13 which still allowed for that data volume behavior. I will tell you that in 1.13+ and later you will not be able to have read-write mounts like that. However, there is a work around, and it might be the 'Kubernetes' way of doing things (Although I struggle to understand why it's better).

The work around:

In your POD/Deployment, create an init container which mounts two volumes. The first volume being your configmap(file), and the second one being an emptyDir container. We will consider the first (configmap) volume as your source, and the later as your destination. Then all you have to do in your new init container is to copy the contents of the source volume to the destination volume.

Then in your normal application container section, mount the destination container from the above, and then you have full read/write capabilities without having to deal with Kubernete's API changes. This should also withstand much of the API changes they plan to do in the future as well.

Rory Savage
  • 51
  • 1
  • 2
  • I can't remember what version it was, but feel like it was < 1.13. It was GKE, so assume it's pretty solid, but again cannot remember, this was April of this year. I will certainly keep this in mind and thank you for the answer. Next time I'm in K8s and run into this I will come back here and accept the answer at that time (if I feel it's the right answer :) ) Thanks again for contributing and welcome to Stack Exchange! – quickshiftin Jan 11 '19 at 16:15
  • This answer is correct. More about RO configmaps can be read here: https://github.com/kubernetes/kubernetes/issues/62099#issuecomment-378809922 – Stefaan Neyts Jun 20 '19 at 09:25
0

OK, I found something workable (but not ideal). First I discovered I can mount the file directly from the ConfigMap with the subPath setting:

containers:
  - name: apache
    image: apache:2.4
    ...
    volumeMounts:
    - name: magento-configs
      mountPath: /var/www/html/app/env/etc.php
      subPath: etc.php
    imagePullPolicy: Always
volumes:
  - name: magento-configs
    configMap:
      name: magento-config

I then discovered changing the ownership of the file inside the pod works, and once changed www-data can write to the file. So I settled on a post start lifecycle hook that changes ownership when the pod starts

containers:
  - name: apache
    image: apache:2.4
    lifecycle:
      postStart:
        exec:
          command: ["chown", "www-data:www-data", "/var/www/html/app/etc/env.php"]

Ideally file ownership would be something we could configure on the volumeMount setting.

quickshiftin
  • 2,025
  • 5
  • 27
  • 41
  • If the configMap files is edited, will those changes get updated to all the pods that using it? And most of all whether the changes are persisted when the pod gets restarted? – user1595858 Aug 27 '18 at 20:45
  • 2
    This is a bad solution because postStart commands and container entrypoint commands run asynchronously. So the order is random. So it might fail. – Stefaan Neyts Jun 20 '19 at 09:23
  • Good to know @StefaanNeyts, thanks! – quickshiftin Jun 20 '19 at 12:24
  • in addition to Stefaan here is the docs: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks – NicoKowe Jul 17 '19 at 08:47