参考:https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/
本文描述如何将定义pod时的字段如标签、注释等某些字段以文件的形式暴露给容器,使容器在运行时能读到这些字段,注意这里是以文件的形式不是以环境变量的形式。这个特性的主要目的是将定义pod、容器时的信息很方便的传递向运行中的容器,比如说容器运行时对cpu、内存等的限定,运行中的容器可以不用通过与集群交互,直接可以很方便的获得这些信息。
假设有如下的pod定义:
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: k8s.gcr.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
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
你可以在配置文件中看到,pod有一个名为downwardAPI的volume,容器将这个volume挂载到了目录/etc/podinfo。现在关注volume中的内容,看它的items数组。第一项表示是一个名为“labels”的文件,它的内容就是配置文件中"metadata.labels"路径下的内容。同样第二项是一个名为"annotations”的文件,内容是配置文件中"metadata.annotations"路径下的内容。注意,在上述例子,无论是"labels"还是"annotations",它们都是pod的有关内容,不是container的内容。
创建pod:
kubectl create -f https://k8s.io/examples/pods/inject/dapi-volume.yaml
确认容器在运行:
kubectl get pods
查看容器日志:
kubectl logs kubernetes-downwardapi-volume-example
输出会显示文件"labels"与"annotations"的内容:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
build="two"
builder="john-doe"
为容器运行交互式shell:
kubectl exec -it kubernetes-downwardapi-volume-example -- sh
在shell内查看"labels"文件内容:
/# cat /etc/podinfo/labels
输出如下:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
“annotations"文件相同,省略。
运行如下命令查看目录内容:
/# ls -laR /etc/podinfo
drwxr-xr-x ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx ... Feb 6 21:47 labels -> ..data/labels
/etc/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r-- ... Feb 6 21:47 annotations
-rw-r--r-- ... Feb 6 21:47 labels
labels与annotations都是符号链接文件,原始文件存放在宿主机的某个目录下,也就是如果pod的配置文件变更引,首先会更新宿主机上的原始文件,而pod无需重新重创,就可以自动更新labels、annotations文件。
上节描述如何将pod定义中与pod有关的字段暴露给容器,本节描述如何将pod定义中与container有关的字段暴露给运行中的容器。以下是一个pod的示例配置文件:
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: k8s.gcr.io/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
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
从配置文件可以看出,在downwardAPI部分,关于容器字段的引用多了一个限定条件:containerName,因为一个pod中可以包含多个容器定义,所以要加上此字段以限定到底引用的是那个容器的内容,其它与上一节介绍的内容相同。
目前好像并不是任意字段都可以以这种方式暴露给运行中的容器。
feildRef,即可以暴露的pod定义中的项目:
resourceFieldRef,即可以暴露的container定义中的项目: