Skip to content
Rahul Shishodiaon GitHub LinkedIn profile

Downward API

  • Exposes metadata about the Pod itself to containers running inside it
  • Two mechanisms:
    • Environment variables (fieldRef, resourceFieldRef)
    • Files via downwardAPI volume type

Pod fields as environment variables

apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-fieldref
spec:
  containers:
    - name: test-container
      image: registry.k8s.io/busybox:1.27.2
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
          printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: MY_POD_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
  restartPolicy: Never

Container resource fields as environment variables

Use resourceFieldRef to expose requests/limits. Inside a container's env block, Kubernetes already knows which container you're in, so containerName defaults to the current container and can be omitted:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-resourcefieldref
spec:
  containers:
    - name: test-container
      image: registry.k8s.io/busybox:1.27.2
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_CPU_REQUEST MY_CPU_LIMIT;
          printenv MY_MEM_REQUEST MY_MEM_LIMIT;
          sleep 10;
        done;
      resources:
        requests:
          memory: "32Mi"
          cpu: "125m"
        limits:
          memory: "64Mi"
          cpu: "250m"
      env:
        - name: MY_CPU_REQUEST
          valueFrom:
            resourceFieldRef:
              resource: requests.cpu
        - name: MY_CPU_LIMIT
          valueFrom:
            resourceFieldRef:
              resource: limits.cpu
        - name: MY_MEM_REQUEST
          valueFrom:
            resourceFieldRef:
              resource: requests.memory
        - name: MY_MEM_LIMIT
          valueFrom:
            resourceFieldRef:
              resource: limits.memory
  restartPolicy: Never
  • Set containerName in env only when container A needs limits/requests from container B in a multi-container Pod

Pod information through files (downwardAPI volume)

resourceFieldRef: containerName optional vs required

WherecontainerName
containers[].env[].valueFrom.resourceFieldRefOptional (defaults to same container)
volumes[].downwardAPI.items[].resourceFieldRefRequired (volume is Pod-scoped, not tied to one container)

Volume (required): spec.volumes sits at Pod root, outside any container block. The API server rejects resourceFieldRef without containerName:

spec:
  containers:
  - name: processing-engine
    image: alpine
    resources:
      limits:
        memory: "128Mi"
    volumeMounts:
    - name: budget-volume
      mountPath: /etc/podinfo
  volumes:
  - name: budget-volume
    downwardAPI:
      items:
      - path: "labels"
        fieldRef:
          fieldPath: metadata.labels
      - path: "mem_limit"
        resourceFieldRef:
          containerName: processing-engine
          resource: limits.memory

Exam tips

  • fieldRef.fieldPath uses API paths (metadata.name, spec.nodeName, status.podIP)
  • resourceFieldRef in env: containerName optional for same container; required only to read another container's resources
  • resourceFieldRef in downwardAPI volume: containerName always required
  • downwardAPI volume: each item needs path + fieldRef (or resourceFieldRef)