Downward API Volume

How do Pod labels become a file that follows every relabel? Kubelet writes metadata.labels into a downwardAPI volume file, one key="value" line per label, and rewrites it when a label changes, while an env var taken from one label key keeps the value it had when the container started. A subPath mount of the file misses the rewrite. The whole labels or annotations map reaches a container only as a file, and fields such as nodeName, podIP and hostIP only as env.

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

Downward API Volume, Kubernetes diagram

Downward API Volume, step by step

  1. Pod api-0 asks for its labels two ways: a downwardAPI volume whose labels file takes fieldRef metadata.labels, and an env var ZONE that takes the zone key alone. NODE_NAME takes spec.nodeName. Kubelet on Node-1 gets the Pod object bound to its Node.

    Play from step 1
  2. Before the container starts, Kubelet writes the volume. /etc/podinfo/labels holds the whole labels map, one key="value" line per label. An env var fieldRef cannot take the whole map, only one key.

    Play from step 2
  3. Kubelet starts the app container and hands it ZONE=east and NODE_NAME=Node-1 as environment variables, resolved once as the container is created. The app now holds the zone twice, in its environment and in the labels file.

    Play from step 3
  4. Someone changes the label zone to west on the Pod object. A label change does not restart the container. Kubelet watches the Pods bound to Node-1, so the new object reaches it.

    Play from step 4
  5. Kubelet rewrites the labels file and swaps it in through a ..data symlink, the way a ConfigMap volume is updated, so a read after the swap returns zone="west". ZONE in the environment still says east, and nothing changes it short of a container restart. A subPath mount of the labels file would keep zone="east" until its container restarts.

    Play from step 5
  6. Not every field goes both ways. Fields such as spec.nodeName, status.podIP, status.hostIP and spec.serviceAccountName reach a container only as env, so no file in the volume can hold them. The whole labels or annotations map reaches it only as a file, and a single key goes either way.

    Play from step 6

Sources