我们知道,每个pod在被成功创建出来之后,都会被系统分配唯一的名字,IP地址,并且处于某个namespace中。
我们如何在pod的容器内获取pod的的这些重要信息呢?
答案就是Downward API
Downward API 可以通过两种方式将pod信息注入容器内容
1:环境变量:用于单个变量,可以将pod信息和container 信息注入容器内部
2: volume挂载:将数组类信息生成为文件并挂载到容器内部。
环境变量方式:将pod信息注入环境变量
下面的例子通过Downward API将pod的ip,名称,和所在namespace注入容器的环境变量中,容器应用使用env命令将全部环境变量打印到标准输出中
[root@bogon ~]# kubectl create -f dapi-test-pod.yaml
pod/dapi-test-pod created
dapi-test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: ["/bin/sh","-c","env"]
env:
- 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
restartPolicy: Never
查看dapi-test-pod的日志
[root@bogon ~]# kubectl logs pod/dapi-test-pod
KUBERNETES_PORT=tcp://169.169.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.2
KUBERNETES_PORT_443_TCP_ADDR=169.169.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://169.169.0.1:443
KUBERNETES_SERVICE_HOST=169.169.0.1
PWD=/
MY_POD_NAME=dapi-test-pod
从日志中我们可以看到pod的ip name namespace 等信息被正确保存到了pod的环境变量中。
环境变量方式:将容器资源信息注入为环境变量
下面的例子将通过Downward API将Container的资源请求和限制信息注入容器的环境变量中,容器应用使用printenv命令将设置的资源请求和资源限制环境变量打印到标准输出中
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod-container-vars
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 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
requests.cpu:容器的cpu请求值
limits.cpu: 容器的cpu限制值
requests.memory:容器的内存请求值
limits.memory:容器的内存限制值
运行kubectl create 命令来创建pod
[root@bogon ~]# kubectl create -f dapi-test-pod-container-vars.yaml
pod/dapi-test-pod-container-vars created
[root@bogon ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dapi-test-pod 0/1 Completed 0 98m
dapi-test-pod-container-vars 1/1 Running 0 2m53s
查看日志:
[root@bogon ~]# kubectl logs dapi-test-pod-container-vars
1
1
33554432
67108864
从日志中我们可以看到container的requests.cpu limits.cpu requests.memory limits.memory 等信息都被正确保存到了pod的环境变量中
volume挂载方式:
下面的例子通过Downward API 将pod的Lable Annotation 列表通过Volume挂载为容器中的一个文件,
容器应用使用echo 命令将文件内容打印到标准输出中:
vim dapi-test-pod-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod-volume
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: test-container
image: busybox
imagePullPolicy: Never
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 3600;
done
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "lables"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
通过items字段的设置,系统会根据path的名称生成文件:
/etc/podinfo/lables
/etc/podinfo/annotations
我们将元数据 labels 和 annotaions 以文件的形式挂载到了/etc/podinfo
目录下,创建上面的 POD :
运行kubectl create 命令创建pod:
[root@bogon ~]# kubectl create -f dapi-test-pod-volume.yaml
pod/dapi-test-pod-volume created
[root@bogon ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dapi-test-pod 0/1 Completed 0 3h34m
dapi-test-pod-container-vars 1/1 Running 0 118m
dapi-test-pod-volume 1/1 Running 0 4s
查看日志:
我们通过打印出来的日志可以看到 POD 的 Labels 和 Annotations 信息都被挂载到 /etc/podinfo
目录下面的 lables 和 annotations
[root@bogon ~]# kubectl logs pods/dapi-test-pod-volume
build="two"
builder="john-doe"
kubernetes.io/config.seen="2020-06-27T15:57:50.532237846+08:00"
Downward API 价值:
在实际应用中,如果你的应用有获取 POD 的基本信息的需求,一般我们就可以利用Downward API
来获取基本信息,然后编写一个启动脚本或者利用initContainer
将 POD 的信息注入到我们容器中去,然后在我们自己的应用中就可以正常的处理相关逻辑了。