In a previous post, I described the Kubernetes Downward API and how it allows us to inject pod/container metadata into our runtime container.
In this article, I’ll show how you can read the environment variables and mounted files from inside a containerized Python based application.
Injection of metadata
As explained in the earlier article, there are two types of metadata that can be exposed with the Downward API: pod metadata and container metadata.
This injection is put into environment variables by definitions located at ‘.spec.template.spec.containers[].env’, like below:
env: # pulling pod fields - name: MY_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName
And the injection of metadata as volume files is defined at ‘.spec.template.spec.volumes’ like below:
volumes: - name: podinfo downwardAPI: items: # pulling container fields from containers[].name - path: "mem_limit" resourceFieldRef: containerName: golang-hello-world-web resource: limits.memory divisor: 1Mi
View my downward-flask-web.yaml for a full example.
Environment variables from Python
From the example above, if you have an environment variable named MY_NODE_NAME coming from the Downward API that is the name of the Kubernetes worker node the pod is running on, then you can get that information using Python.
os.getenv("MY_NODE_NAME","n/a")
This would provide a default value in case it is not passed in, which is useful during non-Kubernetes testing of the container.
File from Python
In our manifest, the Downward API metadata is mounted at the directory “/etc/podinfo”. Finding all the files in that directory and printing their content is done using Python like below.
files = os.listdir("/etc/podinfo/") for f in files: fullname=os.path.join(path,f) if os.path.isfile(fullname): with open(fullname) as f: content = f.readlines() print ( "FILE {} = {}\n".format(fullname,content) )
Full example
If you would like to see a full example at work, see my k8s-downward-flask-web github project. Here is how you would grab the project, then run ‘kubectl apply’ on the manifest that deploys the Downward API with Python Flask application.
# get requirements sudo apt-get install git make -y # grab project from github git clone https://github.com/fabianlee/k8s-downward-flask-web.git cd k8s-downward-flask-web # run kubectl apply make k8s-apply
View the logs using kubectl.
kubectl logs -l app=downward-flask-web --tail=100
And you should see a result similar to below that shows the injected environment variable and file metadata that are printed out when the container starts and the Python Flask application reads them from ‘main’.
build version/time: 1.0.0/2021-04-30_21:24:08 app context: /downward-flask/ Starting web server on port 8000 ENV MY_NODE_NAME = microk8s-2 ENV MY_POD_NAME = downward-flask-web-6f6bb45f67-qlbxl ENV MY_POD_IP = 10.1.100.145 ENV MY_POD_SERVICE_ACCOUNT = default ENV MY_POD_LABEL_APP = downward-flask-web ENV MY_POD_ANNOTATION_AUTHOR = fabian lee ENV MY_POD_MEM_LIMIT_MB = 128 ENV MY_POD_MEM_REQUEST_MB = 32 files in /etc/podinfo/: ..data ..2021_04_30_21_43_03.692155107 annotations labels namespace name mem_request mem_limit
You can also exec directly into the shell and view the env vars and volume mounted files directly.
# try 'env' and 'ls /etc/podinfo' # use 'exit' to quit shell kubectl exec -it $(kubectl -l app=downward-flask-web get pods --output=jsonpath={.items..metadata.name}) -- sh
REFERENCES
kubernetes.io, expose pod info to containers through env vars