使用 DownwardAPIVolumeFile 把自己的信息呈现给 Pod 中运行的容器。 DownwardAPIVolumeFile 可以呈现 Pod 的字段和容器字段。
Downward API
有两种方式可以将 Pod 和 Container 字段呈现给运行中的容器:
这两种呈现 Pod 和 Container 字段的方式都称为 Downward API。
Volume File
Store Pod fields
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| 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: 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 volumes: - name: podinfo downwardAPI: items: - path: "labels" fieldRef: fieldPath: metadata.labels - path: "annotations" fieldRef: fieldPath: metadata.annotations
|
在配置文件中,你可以看到 Pod 有一个 downwardAPI
类型的卷,并且挂载到容器中的 /etc/podinfo
目录。
查看 downwardAPI
下面的 items
数组。 每个数组元素都是一个 DownwardAPIVolumeFile 对象。 第一个元素指示 Pod 的 metadata.labels
字段的值保存在名为 labels
的文件中。 第二个元素指示 Pod 的 annotations
字段的值保存在名为 annotations
的文件中。
说明: 本示例中的字段是Pod字段,不是Pod中容器的字段。
创建 Pod:
1
| kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume.yaml
|
验证Pod中的容器运行正常:
查看容器的日志:
1 2 3 4 5 6 7 8 9 10 11 12
| kubectl logs kubernetes-downwardapi-volume-example
cluster="test-cluster1" rack="rack-22" zone="us-est-coast"
build="two" builder="john-doe" kubectl.kubernetes.io/last-applied-configuration="{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{\"build\":\"two\",\"builder\":\"john-doe\"},\"labels\":{\"cluster\":\"test-cluster1\",\"rack\":\"rack-22\",\"zone\":\"us-est-coast\"},\"name\":\"kubernetes-downwardapi-volume-example\",\"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; sleep 5; done;\"],\"command\":[\"sh\",\"-c\"],\"image\":\"busybox\",\"name\":\"client-container\",\"volumeMounts\":[{\"mountPath\":\"/etc/podinfo\",\"name\":\"podinfo\"}]}],\"volumes\":[{\"downwardAPI\":{\"items\":[{\"fieldRef\":{\"fieldPath\":\"metadata.labels\"},\"path\":\"labels\"},{\"fieldRef\":{\"fieldPath\":\"metadata.annotations\"},\"path\":\"annotations\"}]},\"name\":\"podinfo\"}]}}\n" kubernetes.io/config.seen="2021-12-01T20:03:14.277999707+08:00" kubernetes.io/config.source="api"
|
进入 Pod 中运行的容器,打开一个 Shell:
1
| kubectl exec -it kubernetes-downwardapi-volume-example -- sh
|
在该 Shell中,查看 labels
文件:
1
| /# cat /etc/podinfo/labels
|
输出显示 Pod 的所有标签都已写入 labels
文件。
1 2 3
| cluster="test-cluster1" rack="rack-22" zone="us-est-coast"
|
同样,查看annotations
文件:
1
| /# cat /etc/podinfo/annotations
|
1 2 3 4 5 6 7 8
| cluster="test-cluster1" rack="rack-22" zone="us-est-coast"/ # cat /etc/podinfo/annotations build="two" builder="john-doe" kubectl.kubernetes.io/last-applied-configuration="{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{\"build\":\"two\",\"builder\":\"john-doe\"},\"labels\":{\"cluster\":\"test-cluster1\",\"rack\":\"rack-22\",\"zone\":\"us-est-coast\"},\"name\":\"kubernetes-downwardapi-volume-example\",\"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; sleep 5; done;\"],\"command\":[\"sh\",\"-c\"],\"image\":\"busybox\",\"name\":\"client-container\",\"volumeMounts\":[{\"mountPath\":\"/etc/podinfo\",\"name\":\"podinfo\"}]}],\"volumes\":[{\"downwardAPI\":{\"items\":[{\"fieldRef\":{\"fieldPath\":\"metadata.labels\"},\"path\":\"labels\"},{\"fieldRef\":{\"fieldPath\":\"metadata.annotations\"},\"path\":\"annotations\"}]},\"name\":\"podinfo\"}]}}\n" kubernetes.io/config.seen="2021-12-01T20:03:14.277999707+08:00" kubernetes.io/config.source="api"
|
Store Container fields
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| apiVersion: v1 kind: Pod metadata: name: kubernetes-downwardapi-volume-example-2 spec: containers: - name: client-container image: busybox:1.24 command: ["sh", "-c"] args: - while true; do echo -en '\n'; if [[ -e /etc/podinfo/cpu_limit ]]; then echo -en '\n'; cat /etc/podinfo/cpu_limit; fi; if [[ -e /etc/podinfo/cpu_request ]]; then echo -en '\n'; cat /etc/podinfo/cpu_request; fi; if [[ -e /etc/podinfo/mem_limit ]]; then echo -en '\n'; cat /etc/podinfo/mem_limit; fi; if [[ -e /etc/podinfo/mem_request ]]; then echo -en '\n'; cat /etc/podinfo/mem_request; fi; sleep 5; done; resources: requests: memory: "32Mi" cpu: "125m" limits: memory: "64Mi" cpu: "250m" volumeMounts: - name: podinfo mountPath: /etc/podinfo volumes: - name: podinfo downwardAPI: items: - path: "cpu_limit" resourceFieldRef: containerName: client-container resource: limits.cpu divisor: 1m - path: "cpu_request" resourceFieldRef: containerName: client-container resource: requests.cpu divisor: 1m - path: "mem_limit" resourceFieldRef: containerName: client-container resource: limits.memory divisor: 1Mi - path: "mem_request" resourceFieldRef: containerName: client-container resource: requests.memory divisor: 1Mi
|
在这个配置文件中,你可以看到 Pod 有一个 downwardAPI
类型的卷,并且挂载到容器的 /etc/podinfo
目录。
查看 downwardAPI
下面的 items
数组。每个数组元素都是一个 DownwardAPIVolumeFile。
第一个元素指定名为 client-container
的容器中 limits.cpu
字段的值应保存在名为 cpu_limit
的文件中。
创建Pod:
1
| kubectl apply -f dapi-volume-resources.yaml
|
打开一个 Shell,进入 Pod 中运行的容器:
1
| kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
|
在 Shell 中,查看 cpu_limit
文件:
1
| /# cat /etc/podinfo/cpu_limit
|
你可以使用同样的命令查看 cpu_request
、mem_limit
和 mem_request
文件.
Environment variables
Store Pod fields
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| apiVersion: v1 kind: Pod metadata: name: dapi-envars-fieldref spec: containers: - name: test-container image: busybox 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
|
这个配置文件中,你可以看到五个环境变量。env
字段是一个 EnvVars. 对象的数组。 数组中第一个元素指定 MY_NODE_NAME
这个环境变量从 Pod 的 spec.nodeName
字段获取变量值。 同样,其它环境变量也是从 Pod 的字段获取它们的变量值。
说明: 本示例中的字段是 Pod 字段,不是 Pod 中 Container 的字段。
创建Pod:
1
| kubectl apply -f dapi-envars-pod.yaml
|
验证 Pod 中的容器运行正常:
查看容器日志:
1
| kubectl logs dapi-envars-fieldref
|
输出信息显示了所选择的环境变量的值:
1 2 3 4 5
| minikube dapi-envars-fieldref default 172.17.0.4 default
|
要了解为什么这些值在日志中,请查看配置文件中的command
和 args
字段。 当容器启动时,它将五个环境变量的值写入 stdout。每十秒重复执行一次。
接下来,通过打开一个 Shell 进入 Pod 中运行的容器:
1
| kubectl exec -it dapi-envars-fieldref -- sh
|
在 Shell 中,查看环境变量:
输出信息显示环境变量已经设置为 Pod 字段的值。
1 2 3 4 5 6 7 8
| MY_POD_SERVICE_ACCOUNT=default ... MY_POD_NAMESPACE=default MY_POD_IP=172.17.0.4 ... MY_NODE_NAME=minikube ... MY_POD_NAME=dapi-envars-fieldref
|
Store Container fields
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| apiVersion: v1 kind: Pod metadata: name: dapi-envars-resourcefieldref spec: containers: - name: test-container image: busybox:1.24 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: containerName: test-container resource: requests.cpu - name: MY_CPU_LIMIT valueFrom: resourceFieldRef: containerName: test-container resource: limits.cpu - name: MY_MEM_REQUEST valueFrom: resourceFieldRef: containerName: test-container resource: requests.memory - name: MY_MEM_LIMIT valueFrom: resourceFieldRef: containerName: test-container resource: limits.memory restartPolicy: Never
|
这个配置文件中,你可以看到四个环境变量。env
字段是一个 EnvVars. 对象的数组。数组中第一个元素指定 MY_CPU_REQUEST
这个环境变量从 Container 的 requests.cpu
字段获取变量值。同样,其它环境变量也是从 Container 的字段获取它们的变量值。
说明: 本例中使用的是 Container 的字段而不是 Pod 的字段。
创建Pod:
1
| kubectl apply -f dapi-envars-container.yaml
|
验证 Pod 中的容器运行正常:
查看容器日志:
1
| kubectl logs dapi-envars-resourcefieldref
|
输出信息显示了所选择的环境变量的值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 1. 使用fieldRef可以声明使用: spec.nodeName - 宿主机名字 status.hostIP - 宿主机IP metadata.name - Pod的名字 metadata.namespace - Pod的Namespace status.podIP - Pod的IP spec.serviceAccountName - Pod的Service Account的名字 metadata.uid - Pod的UID metadata.labels['<KEY>'] - 指定<KEY>的Label值 metadata.annotations['<KEY>'] - 指定<KEY>的Annotation值 metadata.labels - Pod的所有Label metadata.annotations - Pod的所有Annotation
2. 使用resourceFieldRef可以声明使用: 容器的CPU limit 容器的CPU request 容器的memory limit 容器的memory request
|