Kubernetes Downward API的介绍及使用
我们都知道,Pod的逻辑概念在容器之上,K8s 在成功创建Pod之后,会为Pod和容器设置一些额外的信息,例如Pod级别的Pod 名称,Pod IP ,Label,Annotation,容器级别的资源限制等。在很多应用场景中,这些信息对容器内的应用来说都很有用,例如使用Pod名称作为日志记录的一个字段用于标识日志来源,为了在容器内获取Pod级别的这些信息,k8s 提供了Downward API 机
我们都知道,Pod的逻辑概念在容器之上,K8s 在成功创建Pod之后,会为Pod和容器设置一些额外的信息,例如Pod级别的Pod 名称,Pod IP ,Label,Annotation,容器级别的资源限制等。
在很多应用场景中,这些信息对容器内的应用来说都很有用,例如使用Pod名称作为日志记录的一个字段用于标识日志来源,为了在容器内获取Pod级别的这些信息,k8s 提供了Downward API 机制来将Pod 和容器的某些元数据信息注入容器环境内,供容器应用方便地使用。
Downward API 可以通过以下两种方式将Pod 和容器的元数据信息注入容器内部。
(1)环境变量:将Pod或Container信息设置为容器内的环境变量。
(2)Volume挂载:将Pod或Container信息以文件的形式挂载到容器内部。
下面通过例子对Downward API 的用法进行说明。
一. 环境变量方式
通过环境变量的方式可以将Pod 信息或Container 信息注入容器运行环境中,下面通过两个例子进行说明。
- 将Pod 信息设置为容器内的环境变量
下面的例子通过Downward API 将Pod 的IP,名称和所在命名空间注入容器的环境变量中,Pod 的yaml 文件如下:
# dapi-envars-pod.yaml
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
注意,环境变量不直接设置value,而是设置valueFrom 对Pod 的元数据进行引用。
在本例中通过会Downward API 的设置使用了以下Pod 的元数据信息设置环境变量。
(1) spec.nodeName: Pod 所在Node 的名称。
(2)metadata.name: Pod 名称。
(3)metadata.namespace:Pod所在命名空间的名称。
(4)status.podIP:Pod的IP地址。
(5)spec.serviceAccountName:Pod 使用的ServiceAccount名称。
运行kubectl create 命令创建这个Pod:
[root@k8s-master ~]# kubectl create -f dapi-envars-pod.yaml
pod/dapi-envars-fieldref created
查看Pod的日志,可以看到容器启动命令将环境变量的值打印出来:
[root@k8s-master ~]# kubectl logs dapi-envars-fieldref
k8s-node-1
dapi-envars-fieldref
default
10.244.109.86
default
.......
我们从日志中可以看到Pod 的Node IP ,Pod名称,命名空间名称,Pod IP ServiceAccount 名称等信息都被正确设置到了容器的环境变量中。
也可以通过kubectl exec 命令登陆容器查看环境变量的设置:
[root@k8s-master ~]# kubectl exec -it dapi-envars-fieldref -- sh
/ # printenv | grep MY
MY_POD_SERVICE_ACCOUNT=default
MY_POD_NAMESPACE=default
MY_POD_IP=10.244.109.86
MY_NODE_NAME=k8s-node-1
MY_POD_NAME=dapi-envars-fieldref
......其pod的环境变量
- 将Container 信息设置为容器内的环境变量
下面的例子通过Downward API 将Container 的资源请求和资源限制信息设置为容器内的环境变量,Pod 的yaml文件内容如下:
# dapi-envars-container.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: busybox
imagePullPolicy: Never
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;
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 3600;
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
在本例中通过Downward API 将以下Container 的资源限制信息设置为环境变量。
(1)requests.cpu: 容器的cpu请求值。
(2)limits.cpu: 容器的cpu限制值。
(3)requests.memory: 容器的内存请求值。
(4)limits.memory: 容器的内存限制值。
运行kubectl create 命令创建Pod:
[root@k8s-master ~]# kubectl create -f dapi-envars-container.yaml
pod/dapi-envars-resourcefieldref created
查看Pod日志:
[root@k8s-master ~]# kubectl logs dapi-envars-resourcefieldref
1
1
33554432
67108864
我们从日志中可以看到 Container 的 requests.cpu,limits,cpu,requests.memory,limits.memory 等信息都被正确保存到了容器的环境变量中。
二. Volume挂载方式
通过Volume 挂载方式可以将Pod 信息或Container 信息挂载为容器内的文件,下面通过例子进行说明。
- 将Pod信息挂载为容器内的文件
下面的例子通过Downward API 将Pod 的Label,Annotation 信息通过Volume挂载为容器中的文件:
# dapi-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster
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'; /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; /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 的 volumes 字段中使用Downward API 的方法: 通过fieldRef 字段设置需要引用Pod 的元数据信息,将其设置到volume 的items 中,在本例中使用了以下Pod 元数据信息:
(1)metadata.labels: Pod 的Label 列表。
(2)metadata.annotations: Pod 的Annotation 列表。
然后,通过容器级别volumeMounts 的设置,系统会基于volume 中item 的path 名称生成文件。根据上面的设置,系统将在容器内的/etc/podinfo,目录下生成labels 和annotations两个文件,在labels 文件中将包含Pod 的全部Label 列表,在annotations文件中将包含Pod 的全部Annotation 列表。
运行kubectl create 命令创建Pod:
[root@k8s-master ~]# kubectl create -f dapi-volume.yaml
pod/kubernetes-downwardapi-volume-example created
进入容器查看挂载的文件:
[root@k8s-master ~]# kubectl exec -it kubernetes-downwardapi-volume-example -- sh
/ # ls -l /etc/podinfo/
total 0
lrwxrwxrwx 1 root root 18 Feb 19 05:49 annotations -> ..data/annotations
lrwxrwxrwx 1 root root 13 Feb 19 05:49 labels -> ..data/labels
/ # cat /etc/podinfo/labels
cluster="test-cluster"
rack="rack-22"
/ # cat /etc/podinfo/annotations
build="two"
builder="john-doe"
cni.projectcalico.org/containerID="81d9ae3d027ad163683db9580053106270e8d7cce5ef19214620f39ecc4c2cd9"
cni.projectcalico.org/podIP="10.244.140.87/32"
cni.projectcalico.org/podIPs="10.244.140.87/32"
kubernetes.io/config.seen="2022-02-19T13:49:48.645023277+08:00"
kubernetes.io/config.source="api"
- 将Container信息挂载为容器内的文件
下面的例子通过DownWard API 将Container 的资源限制信息通过Volume挂载为容器中的文件:
# dapi-volume-resources.yaml
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: busybox
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
在本例中通过Downward API 设置将以下Container的资源限制信息设置到Volume中。
(1)requests.cpu : 容器的cpu请求值。
(2)limits.cpu: 容器的cpu限制值。
(3)requests.memory: 容器的内存请求值。
(4)limits.memory: 容器的内存限制值。
运行kubectl create 命令创建Pod:
[root@k8s-master ~]# kubectl create -f dapi-volume-resources.yaml
pod/kubernetes-downwardapi-volume-example-2 created
进入容器,查看挂载的文件:
[root@k8s-master ~]# kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
/ # ls -l /etc/podinfo
total 0
lrwxrwxrwx 1 root root 16 Feb 19 06:13 cpu_limit -> ..data/cpu_limit
lrwxrwxrwx 1 root root 18 Feb 19 06:13 cpu_request -> ..data/cpu_request
lrwxrwxrwx 1 root root 16 Feb 19 06:13 mem_limit -> ..data/mem_limit
lrwxrwxrwx 1 root root 18 Feb 19 06:13 mem_request -> ..data/mem_request
/ # cat /etc/podinfo/cpu_limit
250
更多推荐
所有评论(0)