Kubernetes Downward API
Accessing Pod's Metadata from a Container: Exploring the Downward API
What is it?
Data that is already known can be passed to the Pod using ConfigMap or Secret volumes. But there are a few cases where the data isn't known upfront such as Pod's IP or name as well as the data that is defined elsewhere, such as Pod's labels and annotations. How to pass this data to a container? This is where the Kubernetes Downward API comes into the picture.
The Kubernetes Downward API enables a container to access information about itself without having to interact with the Kubernetes API Server directly. This can be done in two ways:
Through Environment Variables
Through files in downwardAPI Volume
It is important to note that this isn't like a REST endpoint where the app has to hit to get the data. It's a way of having environment variables of files populated with values from Pod's specification or status.
Now let's see what are all fields available through this Downward API.
Information Available through Downward API
The pod's name
The pod's namespace
The pod's unique ID
The pod's IP
The host's IP
The pod's labels
The pod's annotations
The name of the node where the pod is executing
CPU and memory requests for each container
CPU and memory limits for each container
A more extensive list can be found in the official documentation.
Using Environment Variables
The YAML specification is taken from the official documentation.
fieldRef
: Refer to a field's value using downwardAPI.resourceFieldRef
: Refer to resource-related information.containerName
: Refer to container-related metadata instead of a pod (can be container resource limits/requests, etc)
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_POD_NAME MY_POD_NAMESPACE;
printenv MY_POD_IP MY_CPU_REQUEST;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- 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_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container # get information related a specific container rather than a pod
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
restartPolicy: Never
Using downwardAPI Volume Files
We must use downwardAPI volume for exposing the pod’s labels and annotations because neither can be exposed through environment variables. The reason for this is that labels and annotations can be modified when a pod is running. So when they change, Kubernetes updates the files holding them. If they were stored in environment variables, the pod needs to be restarted for the effects to take place.
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo # mount path where Kubernetes will store the information about labels and annotations
volumes:
- name: podinfo
downwardAPI: # this is the volume type we'll use with downwardAPI
items:
- path: "labels" # name of the file in which the labels information will get saved
fieldRef: # Refers to pod's labels
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
Let's assume that we posted the above YAML file using the following command:
$ kubectl apply -f downward-api-files.yaml
Now according to the specification, we should have a folder path /etc/podinfo
in our container. And inside that folder we should have two files named: labels
and annotations
. Let's check that:
$ kubectl exec kubernetes-downwardapi-volume-example -- ls /etc/podinfo
# output
annotations
labels
Yes, we have two files inside /etc/podinfo
. Let's look at the contents of those two files:
$ kubectl exec kubernetes-downwardapi-volume-example -- cat /etc/podinfo/labels
# output
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"%
$ kubectl exec kubernetes-downwardapi-volume-example -- cat /etc/podinfo/annotations
build="two"
builder="john-doe"
That's awesome. We have all the information about labels and annotations from the specification in those files.
Conclusion
By leveraging the Downward API, developers can easily access details such as the pod's name, namespace, IP address, labels, annotations, and other important metadata. This information can be utilized to make runtime decisions, and dynamically adjust application behavior.
Feedback is highly appreciated. Let me know about any improvements or suggestions. Thanks!