kubernetes: ConfigMaps and Secrets mounted with subPath do not update when changed
/kind bug
What happened:
I wanted to mount a ConfigMap and a Secret directly as a file and didn’t want to mount it as a full directory, so I used subPath to do so:
volumeMounts:
- name: my-config
mountPath: /usr/src/app/config/config.json
subPath: config.json
- name: my-secret
mountPath: /usr/src/app/secret/secret.json
subPath: secret.json
volumes:
- name: my-config
configMap:
name: my-config
- name: my-secret
secret:
secretName: my-secret
When the pod is created, it mounts the ConfigMap and Secret correctly. However, if I change them, the updates are not projected into the currently running pods. New pods get the updated file. According to the documentation, changes to a ConfigMap should be automatically propagated to running containers that mount them.
However, if I don’t use subPath and instead mount the ConfigMap and Secret as a directory:
volumeMounts:
- name: my-config
mountPath: /usr/src/app/config
- name: my-secret
mountPath: /usr/src/app/secret
volumes:
- name: my-config
configMap:
name: my-config
- name: my-secret
secret:
secretName: my-secret
Then the files are updated inside the container when the underlying ConfigMap and Secret are updated and everything works as expected.
Anything else we need to know?:
In both cases, the files are being updated on the host VM. @kelseyhightower and I tried to debug this, and the only conclusion we could come up with is that subPath is using a different method to mount the files (I think it is using symlinks), and these either aren’t or can’t be updated for whatever reason.
Action: The behavior that files mounted with subPath don’t get updated needs to be documented, or it needs to be fixed so that subPath mounts are updated when the underlying ConfigMap or Secret changes.
Environment: GKE
- Kubernetes version (use
kubectl version): 1.6.7 - Cloud provider or hardware configuration**: GKE n1-standard-1
- OS (e.g. from /etc/os-release): Container-Optimized OS 59 9460.64.0
- Kernel (e.g.
uname -a): 4.4.52+
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 69
- Comments: 35 (10 by maintainers)
Commits related to this issue
- Move dynamic config file to it's own directory because of https://github.com/kubernetes/kubernetes/issues/50345 — committed to nlnwa/veidemann-dashboard by maeb 6 years ago
- Move dynamic config file to it's own directory because of https://github.com/kubernetes/kubernetes/issues/50345 — committed to nlnwa/veidemann-dashboard by maeb 6 years ago
- fluent-bit: Add 'fullConfigMap' option to allow entire config external By default this template provies different 'files' for config (fluent-bit.conf, custom_parsers.conf) under a common configMap. T... — committed to donbowman/charts by donbowman 6 years ago
- [stable/fluent-bit] Revert to og indentation... or Refactor configuration (#9008) * fluent-bit: Add 'fullConfigMap' option to allow entire config external By default this template provies different ... — committed to helm/charts by naseemkullah 6 years ago
- [stable/fluent-bit] Revert to og indentation... or Refactor configuration (#9008) * fluent-bit: Add 'fullConfigMap' option to allow entire config external By default this template provies different ... — committed to yuchaoran2011/charts by naseemkullah 6 years ago
- [stable/fluent-bit] Revert to og indentation... or Refactor configuration (#9008) * fluent-bit: Add 'fullConfigMap' option to allow entire config external By default this template provies different ... — committed to FairwindsOps/helm-charts by naseemkullah 6 years ago
- [stable/fluent-bit] Revert to og indentation... or Refactor configuration (#9008) * fluent-bit: Add 'fullConfigMap' option to allow entire config external By default this template provies different ... — committed to wgiddens/charts by naseemkullah 6 years ago
- feat: automatic reloads for DB-less deployment This commit introduces a co-located (aka sidecar) process to the Kong process which runs without a database. Whenever the ConfigMap holding Kong's conf... — committed to Kong/kong-dist-kubernetes by hbagdi 5 years ago
- feat: automatic reloads for DB-less deployment This commit introduces a co-located (aka sidecar) process to the Kong process which runs without a database. Whenever the ConfigMap holding Kong's conf... — committed to Kong/kong-dist-kubernetes by hbagdi 5 years ago
- feat: automatic reloads for DB-less deployment This commit introduces a co-located (aka sidecar) process to the Kong process which runs without a database. Whenever the ConfigMap holding Kong's conf... — committed to Kong/kong-dist-kubernetes by hbagdi 5 years ago
- feat: automatic reloads for DB-less deployment This commit introduces a co-located (aka sidecar) process to the Kong process which runs without a database. Whenever the ConfigMap holding Kong's conf... — committed to Kong/kong-dist-kubernetes by hbagdi 5 years ago
- feat: automatic reloads for DB-less deployment This commit introduces a co-located (aka sidecar) process to the Kong process which runs without a database. Whenever the ConfigMap holding Kong's c... — committed to Kong/kong-dist-kubernetes by hbagdi 5 years ago
- [stable/fluent-bit] Revert to og indentation... or Refactor configuration (#9008) * fluent-bit: Add 'fullConfigMap' option to allow entire config external By default this template provies different ... — committed to fluent/helm-charts by naseemkullah 6 years ago
- [stable/fluent-bit] Revert to og indentation... or Refactor configuration (#9008) * fluent-bit: Add 'fullConfigMap' option to allow entire config external By default this template provies different ... — committed to Rungway/charts-we-use by naseemkullah 6 years ago
- Mount tls secrets using projected volume not subpath - secrets and configmaps mounted with subpath do not not get updated in pods when changed, as reported in issue: https://github.com/kubernetes/kub... — committed to rabbitmq/cluster-operator by ChunyiLyu 4 years ago
- Mount tls secrets using projected volume not subpath - secrets and configmaps mounted with subpath do not not get updated in pods when changed, as reported in issue: https://github.com/kubernetes/kub... — committed to rabbitmq/cluster-operator by ChunyiLyu 4 years ago
- Add TODO for propagating authorized keys into async server Changes to configmaps are not propagated when the configmap is mounted via subPath. We can work around this but it would require changes to ... — committed to amisevsk/devworkspace-operator by amisevsk 3 years ago
- Add TODO for propagating authorized keys into async server Changes to configmaps are not propagated when the configmap is mounted via subPath. We can work around this but it would require changes to ... — committed to amisevsk/devworkspace-operator by amisevsk 3 years ago
- Add TODO for propagating authorized keys into async server Changes to configmaps are not propagated when the configmap is mounted via subPath. We can work around this but it would require changes to ... — committed to amisevsk/devworkspace-operator by amisevsk 3 years ago
- Add TODO for propagating authorized keys into async server Changes to configmaps are not propagated when the configmap is mounted via subPath. We can work around this but it would require changes to ... — committed to amisevsk/devworkspace-operator by amisevsk 3 years ago
@supereagle that is not the same thing. sometimes you want to merge in a few config files into a magic config dir, like, /etc/condor/config.d, but leave the rest of the dir open for other things to drop things in. subPath is the right way to do that I think. but should be able to get updates still.
@thesandlord Maybe your use case is Add ConfigMap data to a specific path in the Volume.
I follow the documentation, and it works as expected. My configmap:
My pod.yaml:
This is a known limitation of using subpath with atomic volume types and has been documented. There is no fix planned.
@mingfang you are right.
This configMap / items works great, it’s a symlink, so it get updated when the ConfigMap updates. However, it does not solve the other problem: let’s say if I want to mount nginx.conf to /etc/nginx/nginx.conf the directory /etc/nginx becomes empty (removing all other default configs), and will only contain this (finally symlinked) nginx.conf 😦
I would love to have a solution that combines symlinks (for hot reload), and keeping original directory contents…
@msau42 thanks for the clarification.
For anyone affected by this, I just learned about this https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#add-configmap-data-to-a-specific-path-in-the-volume and it seems to do the same thing as subPath but actually works.
For the original example above, the solution would look like this
I think we just need to document this as a known limitation.
Because subpaths are bind mounted by docker, if it was a symlink, then it gets resolved to the actual path during the bindmount.
we do it like this:
it work for us but not clean enough
I bumped into this issue because I was having the same frustraing problem. However, I think the following could be a legit workaround:
Designate a folder where you will mount your desired configmaps, for example:
/configmaps/Make the mountPath of each configmap (or secret) a subfolder of this folder. Going further on previous examples with nginx, your mount would look like this:
Now, to tie this all together, create a symlink from /etc/nginx/nginx.conf to /configmaps/nginx/nginx.conf. This symlink can exist before the configmap is even mounted.
Whenever you update the configmap, the /configmap/nginx folder is remounted, and your symlink is now pointing to the updated version.
The main challenge is technical. The subpath implementation uses bind-mounts for security reasons, and bind mount will stay with the original inode. I do not think we can remove the bind mount implementation, so the main alternatives to explore would be if we can get projected or configmap.items to provide single files instead of the whole directory.
Any way that this issue can be reopened? I ran into it with AWS EKS, and mounting a ConfigMap like
You can update the
ConfigMap, then wait some time (I waited 30min). Thenkubectl exec -ti {pod} -- bashinto the running pod,cat /usr/src/app/site_config.ymland still see the old ConfigMap value.Deleting the pod to force recreation results in having the correct file contents mounted.
Edit:
OK I guess this isn’t an issue because it’s “documented” as not working for
subPath😞https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#mounted-configmaps-are-updated-automatically
I tried working off the example shown in that docs page, but that is set up to mount a directory, not a single file.
the docs also state that
Caution: Like before, all previous files in the /etc/config/ directory will be deletedwhich is not how mounting thesubPathway works. That also won’t work for me because I need to mount a file into an existing directory that has other files in it.What is the correct way to mount a single key in a ConfigMap to a single file in an existing directory that has existing files? 😕
Really I don’t even care about a ConfigMap at all, it just forces me to have a key/value pair, but in reality all I want to do is generate a file that contains a JSON string and mount it into my project root, but there seems to be no obvious way to do that.
Yes, symlinks are involved. Atomic writer relies on symlinks to update configmaps, secrets and such: https://github.com/kubernetes/kubernetes/blob/master/pkg/volume/util/atomic_writer.go. On the host, the pod volume directory looks something like this:
When you subPath the secret file, that secret.json file is bind mounted into the container. But secret.json is actually a symlink to another secret.json in a timestamped folder (…8988_09_08_14_21_15.788262705). When the secret gets updated, the symlinks get changed around but the file bind mounted into the container remains the same.
Not sure what the solution is. Hope this helps somebody else think of one though 😃
e: Disregarding the symlinking complexity of the atomic writer algorithm for the moment…the tool we have to atomically update the file is a rename, in that case is a solution even possible? The bind mount file will always refer to the same inode yes?
@kundralaci it seems to be now possible , look at that : https://github.com/kubernetes/kubernetes/issues/44815#issuecomment-297077509 I’ve just tested a few minutes ago and seems to be ok.
why is this close? what is the fix or is there going to be a fix?
It’s so sad that this one is closed without any improvement. So we have to use symlink to workaround this problem?
@jeff-1amstudios In the Dockerfile of the image. The destination doesn’t need to exist (yet) when creating the symlink
/sig storage /sig docs