subPath Mounts

Why does a config file mounted with subPath miss an update? A subPath mount places one path from a volume, here one file beside the files an image ships, and Kubelet resolves it when the container starts. The ..data symlink flip that updates a ConfigMap, Secret, downward API or projected volume never reaches that mount, so a whole-directory mount in the same Pod reads v2 while the subPath file stays at v1 until its container restarts.

Play the animation 5 steps, animated, best on a wide screen

subPath Mounts, Kubernetes diagram

subPath Mounts, step by step

  1. The web container mounts the whole config volume as a directory at /etc/app. Every read of app.conf goes through the ..data symlink, which points at the v1 directory, so web reads app.conf v1.

    Play from step 1
  2. The proxy container needs only app.conf, in /etc/nginx next to the files its image ships. A whole-volume mount there would hide them, so it sets subPath: app.conf. When the container starts, Kubelet resolves that path to the v1 file and bind-mounts the file itself.

    Play from step 2
  3. The ConfigMap changes. Kubelet does not edit the files in place: on its next sync it writes the new version into a fresh v2 directory, flips ..data to point at it, then deletes the v1 directory.

    Play from step 3
  4. The web container reads app.conf again. Its path still runs through ..data, so the same read now resolves into the v2 directory and web gets the new config without a restart.

    Play from step 4
  5. Proxy reads app.conf too. Its bind mount never goes through ..data and still holds the v1 file, readable although its directory is deleted, so proxy gets v1. The docs say it for ConfigMap, Secret, downward API and projected volumes: a subPath mount does not receive updates. Proxy sees v2 once its container restarts and Kubelet resolves the path again.

    Play from step 5

Sources