Projected Volumes

How does one mounted directory hold a ConfigMap key, Pod metadata and a token that renews itself? A projected volume fills one mount from several sources, a ConfigMap, a Secret, downwardAPI, a serviceAccountToken, plus clusterTrustBundle and podCertificate, beta and off by default in 1.36. Kubelet replaces the audience-bound token at 80 percent of its lifetime or after 24 hours and the app re-reads it, while a legacy Secret token never expires.

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

Projected Volumes, Kubernetes diagram

Projected Volumes, step by step

  1. Pod api-0 mounts one projected volume at /var/run/secrets/app, filled from three sources. Kubelet gets ConfigMap vault-ca from the API server and writes its key as ca.crt, then writes namespace from the Pod object through downwardAPI.

    Play from step 1
  2. The third source, serviceAccountToken, lives in no object. Kubelet sends a TokenRequest for the audience vault and one hour, gets back a token bound to Pod api-0, and writes it as token. A recipient outside that audience should reject it.

    Play from step 2
  3. The app sees one directory, not three sources. It opens ca.crt, namespace and token as plain files and never calls the Kubernetes API to fetch any of them. The token is what it authenticates with.

    Play from step 3
  4. Kubelet does not wait for the expiry. Once the token is past 80 percent of its lifetime or 24 hours old, Kubelet requests a fresh token on its next sync, here about minute 48, and swaps it into the same file atomically. The other two files stay. The app gets token 2 only when it re-reads.

    Play from step 4
  5. If instead the Pod used a legacy Secret-based token, it would never expire or rotate, and a leaked copy would stay valid until that Secret or its ServiceAccount is deleted. The projected token ends at its expiry, and the API server rejects it once Pod api-0 or its ServiceAccount is deleted.

    Play from step 5

Sources