Cloud Native 10 min read

Kubernetes Volume Mounts: Hot Reload, subPath Pitfalls & Projected Volumes

This article explains Kubernetes volume mounting for ConfigMaps and Secrets, detailing how directory mounts achieve hot reloads via atomic symlink switching, why subPath mounts never update, and how projected volumes merge multiple configuration sources into a single directory.

Code Mala Tang
Code Mala Tang
Code Mala Tang
Kubernetes Volume Mounts: Hot Reload, subPath Pitfalls & Projected Volumes

1. Basic Directory Mount for ConfigMap

Environment variables suit a few short values, but applications reading entire config files (e.g., nginx.conf, application.yaml) should use volumes. Declare a volume and mount it to a container path:

spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: config-vol
      mountPath: /etc/config  # mount to this directory in container
  volumes:
  - name: config-vol
    configMap:
      name: app-config  # source: ConfigMap created earlier

After mounting, each key in app-config becomes a file under /etc/config/; key app.properties maps to /etc/config/app.properties with the key's value as content. Secrets work identically — replace configMap with secret.

To mount only selected keys and optionally rename files, use items:

volumes:
- name: config-vol
  configMap:
    name: app-config
    items:
    - key: app.properties
      path: application.yaml  # key app.properties → filename becomes application.yaml

2. Hot Reload Truth: Atomic Symlink Switch

When you update a ConfigMap and run kubectl apply, files in the mounted directory update automatically — no Pod restart needed. This is not magic; kubelet uses a symlink mechanism.

Volume hot reload symlink mechanism
Volume hot reload symlink mechanism

The mounted directory hides this structure:

The file the application opens (e.g., app.properties) is a symlink, not a real file.

It points to a symlink named ..data. ..data points to the actual content directory named with a timestamp.

When the ConfigMap changes, kubelet writes the new content into a new timestamped directory, then atomically switches the ..data symlink to point to the new directory. Symlink switching is atomic, so the application reads either the old complete version or the new complete version — never a half-written corrupt file .

⏱️ Hot reload is not "instant" From apply to actual file change in the container there is latency. Kubelet syncs periodically (default ~1 minute) plus a cache TTL, so worst case may take 1–2 minutes. Don't panic if nothing changes after two seconds.

3. Fatal Trap: subPath Never Hot Reloads

Now that you understand the symlink mechanism, the notorious pitfall is explained in one sentence. subPath is a common requirement: mount a single config file to a precise location without overwriting the entire directory (e.g., inject into /etc/nginx/nginx.conf without touching other files under /etc/nginx/).

volumeMounts:
- name: config-vol
  mountPath: /etc/nginx/nginx.conf
  subPath: nginx.conf  # mount only this file, don't overwrite whole directory

It looks convenient, but the cost is: with subPath, the file will never hot reload .

Reason: subPath copies the file directly to the target path, bypassing the ..data symlink system. No matter how kubelet later switches symlinks, the copied file is unrelated — it stays at the state from the moment of mount.

This trap is dangerous because it fails silently. Everything appears normal, ConfigMap updates apply successfully, but the file never changes. Many engineers waste hours debugging this.

✅ Want hot reload? Don't use subPath If the file must hot reload, mount the whole directory (even if it contains only that one file). If you truly need subPath's precise insertion, accept that it won't hot reload — pair config changes with a rolling restart (using the checksum annotation trick from part 1), which is actually clearer and more controllable.

4. Advanced: projected Volume Merges Multiple Sources

Sometimes a container needs to read: a business config (ConfigMap), TLS certs (Secret), pod metadata (Downward API), and a service account token. The previous approach requires four volumes and four mount paths — verbose and scattered YAML. projected volume solves this by projecting multiple sources into the same mount point :

Projected volume merging multiple sources
Projected volume merging multiple sources
volumes:
- name: all-in-one
  projected:
    sources:
    - configMap:
        name: app-config
    - secret:
        name: tls-cert
    - downwardAPI:
        items:
        - path: labels
          fieldRef:
            fieldPath: metadata.labels
    - serviceAccountToken:
        # token with expiration and audience binding
        path: token
        expirationSeconds: 3600
        audience: my-api

After mounting, /etc/all/ contains app.conf, tls.key, labels, token side by side.

The serviceAccountToken deserves special mention. It is not a long-lived legacy token but a short-lived token with expiration and bound audience ; kubelet renews it automatically on expiry. Service meshes and scenarios requiring proof of identity to a specific API rely on this — far more secure than the default mounted SA token.

5. Hard Conclusions from This Article

ConfigMap / Secret mounted as volumes: each key becomes a file in the directory .

Directory mounts hot reload via ..data symlink atomic switch ; applications never read partial data.

Hot reload has latency (sync period + cache TTL), worst case 1–2 minutes — be patient.

subPath mount never hot reloads because it bypasses the symlink mechanism — mount the whole directory if you need hot reload.

File hot reload ≠ application re-reads; the app must watch the file itself; if not, use rolling restart.

Multiple sources (config + certs + token + metadata) into one directory: use projected.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesHot ReloadkubeletConfigMapSecretsubPathProjected VolumeVolume Mount
Code Mala Tang
Written by

Code Mala Tang

Read source code together, write articles together, and enjoy spicy hot pot together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.