Downward API
Overview
The downward API is a mechanism that allows containers to consume information about API objects without coupling to OKD. Such information includes the pod’s name, namespace, and resource values. Containers can consume information from the downward API using environment variables or a volume plug-in.
Selecting Fields
Fields within the pod are selected using the **FieldRef**
API type. **FieldRef**
has two fields:
Field | Description |
---|---|
| The path of the field to select, relative to the pod. |
| The API version to interpret the |
Currently, the valid selectors in the v1 API include:
Selector | Description |
---|---|
| The pod’s name. This is supported in both environment variables and volumes. |
| The pod’s namespace.This is supported in both environment variables and volumes. |
| The pod’s labels. This is only supported in volumes and not in environment variables. |
| The pod’s annotations. This is only supported in volumes and not in environment variables. |
| The pod’s IP. This is only supported in environment variables and not volumes. |
The **apiVersion**
field, if not specified, defaults to the API version of the enclosing pod template.
Consuming Container Values Using the Downward API
Using Environment Variables
One mechanism for consuming the downward API is using a container’s environment variables. The **EnvVar**
type’s **valueFrom**
field (of type **EnvVarSource**
) is used to specify that the variable’s value should come from a **FieldRef**
source instead of the literal value specified by the **value**
field. In the future, additional sources may be supported; currently the source’s **fieldRef**
field is used to select a field from the downward API.
Only constant attributes of the pod can be consumed this way, as environment variables cannot be updated once a process is started in a way that allows the process to be notified that the value of a variable has changed. The fields supported using environment variables are:
Pod name
Pod namespace
Create a
***pod.yaml***
file:apiVersion: v1
kind: Pod
metadata:
name: dapi-env-test-pod
spec:
containers:
- name: env-test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: Never
Create the pod from the
***pod.yaml***
file:$ oc create -f pod.yaml
Check the container’s logs for the
**MY_POD_NAME**
and**MY_POD_NAMESPACE**
values:$ oc logs -p dapi-env-test-pod
Using the Volume Plug-in
Another mechanism for consuming the downward API is using a volume plug-in. The downward API volume plug-in creates a volume with configured fields extended into files. The **metadata**
field of the **VolumeSource**
API object is used to configure this volume. The plug-in supports the following fields:
Pod name
Pod namespace
Pod annotations
Pod labels
Example 1. Downward API Volume Plug-in Configuration
spec:
volumes:
- name: podinfo
downwardAPI:: (1)
items: (2)
-name: "labels" (3)
fieldRef:
fieldPath: metadata.labels (4)
1 | The metadata field of the volume source configures the downward API volume. |
2 | The items field holds a list of fields to extend into the volume. |
3 | The name of the file to extend the field into. |
4 | The selector of the field to extend. |
For example:
Create a
***volume-pod.yaml***
file:kind: Pod
apiVersion: v1
metadata:
labels:
zone: us-east-coast
cluster: downward-api-test-cluster1
rack: rack-123
name: dapi-volume-test-pod
annotations:
annotation1: "345"
annotation2: "456"
spec:
containers:
- name: volume-test-container
image: gcr.io/google_containers/busybox
command: ["sh", "-c", "cat /tmp/etc/pod_labels /tmp/etc/pod_annotations"]
volumeMounts:
- name: podinfo
mountPath: /tmp/etc
readOnly: false
volumes:
- name: podinfo
downwardAPI:
defaultMode: 420
items:
- fieldRef:
fieldPath: metadata.name
path: pod_name
- fieldRef:
fieldPath: metadata.namespace
path: pod_namespace
- fieldRef:
fieldPath: metadata.labels
path: pod_labels
- fieldRef:
fieldPath: metadata.annotations
path: pod_annotations
restartPolicy: Never
Create the pod from the
***volume-pod.yaml***
file:$ oc create -f volume-pod.yaml
Check the container’s logs and verify the presence of the configured fields:
$ oc logs -p dapi-volume-test-pod
cluster=downward-api-test-cluster1
rack=rack-123
zone=us-east-coast
annotation1=345
annotation2=456
kubernetes.io/config.source=api
Consuming Container Resources Using the Downward API
When creating pods, you can use the downward API to inject information about computing resource requests and limits so that image and application authors can correctly create an image for specific environments.
You can do this using both the environment variable and volume plug-in methods.
Using Environment Variables
When creating a pod configuration, specify environment variables that correspond to the contents of the
**resources**
field in the**spec.container**
field:....
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox:1.24
command: [ "/bin/sh", "-c", "env" ]
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
....
If the resource limits are not included in the container configuration, the downward API defaults to the node’s CPU and memory allocatable values.
Create the pod from the
***pod.yaml***
file:$ oc create -f pod.yaml
Using the Volume Plug-in
When creating a pod configuration, use the
**spec.volumes.downwardAPI.items**
field to describe the desired resources that correspond to the**spec.resources**
field:....
spec:
containers:
- name: client-container
image: gcr.io/google_containers/busybox:1.24
command: ["sh", "-c", "while true; do echo; if [[ -e /etc/cpu_limit ]]; then cat /etc/cpu_limit; fi; if [[ -e /etc/cpu_request ]]; then cat /etc/cpu_request; fi; if [[ -e /etc/mem_limit ]]; then cat /etc/mem_limit; fi; if [[ -e /etc/mem_request ]]; then cat /etc/mem_request; fi; sleep 5; done"]
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory
....
If the resource limits are not included in the container configuration, the downward API defaults to the node’s CPU and memory allocatable values.
Create the pod from the
***volume-pod.yaml***
file:$ oc create -f volume-pod.yaml
Consuming Secrets Using the Downward API
When creating pods, you can use the downward API to inject Secrets so image and application authors can create an image for specific environments.
Using Environment Variables
Create a secret.yaml file:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
data:
password: cGFzc3dvcmQ=
username: ZGV2ZWxvcGVy
type: kubernetes.io/basic-auth
Create a
Secret
from the secret.yaml file:oc create -f secret.yaml
Create a
***pod.yaml***
file that references theusername
field from the aboveSecret
:apiVersion: v1
kind: Pod
metadata:
name: dapi-env-test-pod
spec:
containers:
- name: env-test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: MY_SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
restartPolicy: Never
Create the pod from the
***pod.yaml***
file:$ oc create -f pod.yaml
Check the container’s logs for the
**MY_SECRET_USERNAME**
value:$ oc logs -p dapi-env-test-pod
Consuming ConfigMaps Using the Downward API
When creating pods, you can use the downward API to inject ConfigMap values so image and application authors can create an image for specific environments.
Using Environment Variables
Create a
***configmap.yaml***
file:apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
data:
mykey: myvalue
Create a
ConfigMap
from the***configmap.yaml***
file:oc create -f configmap.yaml
Create a
***pod.yaml***
file that references the aboveConfigMap
:apiVersion: v1
kind: Pod
metadata:
name: dapi-env-test-pod
spec:
containers:
- name: env-test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: MY_CONFIGMAP_VALUE
valueFrom:
configMapKeyRef:
name: myconfigmap
key: mykey
restartPolicy: Never
Create the pod from the
***pod.yaml***
file:$ oc create -f pod.yaml
Check the container’s logs for the
**MY_CONFIGMAP_VALUE**
value:$ oc logs -p dapi-env-test-pod
Environment Variable References
When creating pods, you can reference the value of a previously defined environment variable by using the $()
syntax. If the environment variable reference can not be resolved, the value will be left as the provided string.
Using Environment Variable References
Create a
***pod.yaml***
file that references an existingenvironment variable
:apiVersion: v1
kind: Pod
metadata:
name: dapi-env-test-pod
spec:
containers:
- name: env-test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: MY_EXISTING_ENV
value: my_value
- name: MY_ENV_VAR_REF_ENV
value: $(MY_EXISTING_ENV)
restartPolicy: Never
Create the pod from the
***pod.yaml***
file:$ oc create -f pod.yaml
Check the container’s logs for the
**MY_ENV_VAR_REF_ENV**
value:$ oc logs -p dapi-env-test-pod
Escaping Environment Variable References
When creating a pod, you can escape an environment variable reference by using a double dollar sign. The value will then be set to a single dollar sign version of the provided value.
Create a
***pod.yaml***
file that references an existingenvironment variable
:apiVersion: v1
kind: Pod
metadata:
name: dapi-env-test-pod
spec:
containers:
- name: env-test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: MY_NEW_ENV
value: $$(SOME_OTHER_ENV)
restartPolicy: Never
Create the pod from the
***pod.yaml***
file:$ oc create -f pod.yaml
Check the container’s logs for the
**MY_NEW_ENV**
value:$ oc logs -p dapi-env-test-pod