Docker and K8S learning notes -- using the Downward API to inject Pod information into the container

When creating a Pod, Kubernetes will set some additional information for the Pod and container, such as Pod name, Pod IP, Node IP, Label, Annotation, resource restrictions, etc. we often use these data in the application. For example, we use the Pod name as the word segment of the application log to facilitate log analysis. In order to obtain this information in the container, we can use the Downward API mechanism.

The Downward API can inject Pod information into the container through environment variables and Volume mount. Let's take a look at them respectively:

 

1, Environment variable mode

Let's take Busybox as an example. We inject Pod information and Container information into the Container in the form of environment variables, and print it out through env command after the Container is started. The contents of our Yaml file are as follows:

apiVersion: v1
kind: Pod
metadata:
  name: busybox-pod
spec:
  containers:
  - name: busybox
    image: busybox
    command: ["/bin/sh", "-c", "env | grep VAR_"]
    resources:
      requests:
        memory: "16Mi"
        cpu: "125m"
      limits:
        memory: "32Mi"
        cpu: "250m"
    env:
    - name: VAR_NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: VAR_POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: VAR_POD_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: VAR_POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    - name: VAR_SERVICE_ACCOUNT
      valueFrom:
        fieldRef:
          fieldPath: spec.serviceAccountName
    - name: VAR_CPU_REQUEST
      valueFrom:
        resourceFieldRef:
          containerName: busybox
          resource: requests.cpu
    - name: VAR_CPU_LIMIT
      valueFrom:
        resourceFieldRef:
          containerName: busybox
          resource: limits.cpu
    - name: VAR_MEM_REQUEST
      valueFrom:
        resourceFieldRef:
          containerName: busybox
          resource: requests.memory
    - name: VAR_MEM_LIMIT
      valueFrom:
        resourceFieldRef:
          containerName: busybox
          resource: limits.memory
  restartPolicy: Never

We create a Pod and print the output using the kubtctl logs command:

$ sudo kubectl apply -f busy_pod.yaml
pod/busybox-pod created
$ sudo kubectl logs busybox-pod
VAR_MEM_REQUEST=16777216      # Container memory request value
VAR_NODE_NAME=ayato           # Node name
VAR_SERVICE_ACCOUNT=default   # ServiceAccount name used by Pod
VAR_CPU_REQUEST=1             # Container cpu request value
VAR_POD_NAME=busybox-pod      # pod name
VAR_MEM_LIMIT=33554432        # Container memory limit
VAR_POD_NAMESPACE=default     # Namespace of Pod
VAR_POD_IP=172.17.0.6         # Pod ip address
VAR_CPU_LIMIT=1               # Container cpu request value

 

2, Volume mount method

Next, we try to use the Volume mount method to inject Pod information into the container. Take Busybox as an example. Since Pod information is injected into the container in the form of files, we modify the container and execute the command after startup: we use cat to continuously print the injected files. The modified Yaml files are as follows:

apiVersion: v1
kind: Pod
metadata:
  name: busybox-pod
  labels:
    cluster: demo-cluster
    type: tool-pod
  annotations:
    builder: alalazy
spec:
  containers:
  - name: busybox
    image: busybox
    command: ["/bin/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;
        if [[ -e /etc/podinfo/cpu_limit ]]; then
          echo -en '\n\n'; cat /etc/podinfo/cpu_limit; fi;
        if [[ -e /etc/podinfo/cpu_request ]]; then
          echo -en '\n\n'; cat /etc/podinfo/cpu_request; fi;
        if [[ -e /etc/podinfo/mem_limit ]]; then
          echo -en '\n\n'; cat /etc/podinfo/mem_limit; fi;
        if [[ -e /etc/podinfo/mem_request ]]; then
          echo -en '\n\n'; cat /etc/podinfo/mem_request; fi;
        sleep 5;
      done;
    volumeMounts:
      - name: podinfo
        mountPath: /etc/podinfo
    resources:
      requests:
        memory: "16Mi"
        cpu: "125m"
      limits:
        memory: "32Mi"
        cpu: "250m"
  volumes:
    - name: podinfo
      downwardAPI:
        items:
          - path: "labels"
            fieldRef:
              fieldPath: metadata.labels
          - path: "annotations"
            fieldRef:
              fieldPath: metadata.annotations
          - path: "cpu_limit"
            resourceFieldRef:
              containerName: busybox
              resource: limits.cpu
              divisor: 1m
          - path: "cpu_request"
            resourceFieldRef:
              containerName: busybox
              resource: requests.cpu
              divisor: 1m
          - path: "mem_limit"
            resourceFieldRef:
              containerName: busybox
              resource: limits.memory
              divisor: 1Mi
          - path: "mem_request"
            resourceFieldRef:
              containerName: busybox
              resource: requests.memory
              divisor: 1Mi

We create this Pod and view the output through kubectl logs:

$ sudo kubectl apply -f busy_pod.yaml
pod/busybox-pod created
$ sudo kubectl logs busybox-pod
cluster="demo-cluster"
type="tool-pod"

builder="alalazy"
kubectl.kubernetes.io/last-applied-configuration="{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{\"builder\":\"alalazy\"},\"labels\":{\"cluster\":\"demo-cluster\",\"type\":\"tool-pod\"},\"name\":\"busybox-pod\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"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; if [[ -e /etc/podinfo/cpu_limit ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/cpu_limit; fi; if [[ -e /etc/podinfo/cpu_request ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/cpu_request; fi; if [[ -e /etc/podinfo/mem_limit ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/mem_limit; fi; if [[ -e /etc/podinfo/mem_request ]]; then echo -en '\\\\n\\\\n'; cat /etc/podinfo/mem_request; fi; sleep 5; done;\"],\"command\":[\"/bin/sh\",\"-c\"],\"image\":\"busybox\",\"name\":\"busybox\",\"resources\":{\"limits\":{\"cpu\":\"250m\",\"memory\":\"32Mi\"},\"requests\":{\"cpu\":\"125m\",\"memory\":\"16Mi\"}},\"volumeMounts\":[{\"mountPath\":\"/etc/podinfo\",\"name\":\"podinfo\"}]}],\"volumes\":[{\"downwardAPI\":{\"items\":[{\"fieldRef\":{\"fieldPath\":\"metadata.labels\"},\"path\":\"labels\"},{\"fieldRef\":{\"fieldPath\":\"metadata.annotations\"},\"path\":\"annotations\"},{\"path\":\"cpu_limit\",\"resourceFieldRef\":{\"containerName\":\"busybox\",\"divisor\":\"1m\",\"resource\":\"limits.cpu\"}},{\"path\":\"cpu_request\",\"resourceFieldRef\":{\"containerName\":\"busybox\",\"divisor\":\"1m\",\"resource\":\"requests.cpu\"}},{\"path\":\"mem_limit\",\"resourceFieldRef\":{\"containerName\":\"busybox\",\"divisor\":\"1Mi\",\"resource\":\"limits.memory\"}},{\"path\":\"mem_request\",\"resourceFieldRef\":{\"containerName\":\"busybox\",\"divisor\":\"1Mi\",\"resource\":\"requests.memory\"}}]},\"name\":\"podinfo\"}]}}\n"
kubernetes.io/config.seen="2022-01-15T05:33:53.379386410Z"
kubernetes.io/config.source="api"

250

125

32

16

Let's enter the container to view the attached files:

$  sudo kubectl exec -it busybox-pod -- sh
/ # cd /etc/podinfo/
/etc/podinfo # ls
annotations  cpu_limit    cpu_request  labels       mem_limit    mem_request

 

3, Downward API capabilities

We can inject the following information into the container through the Downward API:

1) Information available through fieldRef:

  • metadata.name: Pod name

  • metadata.namespace: Pod namespace

  • metadata.uid: UID of Pod

  • metadata. Labels ['< key >']: the value of the Pod label < key > (for example, metadata.labels['mylabel '])

  • metadata. Annotations ['< key >']: the value of Pod's annotation < key > (for example, metadata.annotations['myannotation '])

  • metadata.labels: get all labels

  • metadata.annotations: get all annotations

  • status. Popip: node IP

  • spec.serviceAccountName: Pod service account name, version requirements v1 4.0-alpha. three

  • spec.nodeName: node name, version v1 4.0-alpha. three

  • status.hostIP: node IP, version v1 7.0-alpha. one

2) Information available through resourceFieldRef:

  • CPU} constraint value of the container

  • CPU request value of the container

  • Memory constraint value of the container

  • Memory request value for container

  • The macro page limit value of the container (provided that the downwardapipagepages} feature gating is enabled)

  • Macro page request value of the container (provided that downwardapipagepages} feature gating is enabled)

  • Temporary storage constraint values for containers

  • Temporary storage request value for container

Added by SteveMT on Tue, 25 Jan 2022 03:27:32 +0200