此文为学习《Kubernetes权威指南》的相关笔记
学习笔记:
正如名字所表示的,Downward API是一种向下传递信息的接口,所谓向下,是Pod向其包含的容器传递,传递的内容为自身属性,主要传递方式仍然是容器接收外界信息的两大途径:环境变量和Volume,从目前学习来看,这个接口可以向容器提供的信息包括:所属Pod的名称、命名空间、IP地址,Pod为自身设置的资源限制、Pod所拥有的Labels和Annotations.
在我的理解里,Downward API加强了容器的自我认知功能,能够更好的感知自己所属Pod的信息,以便完善自身功能,目前能想到的应用场景如:根据上面提供给自己的资源限制调整自己的运行状态、根据Pod信息来决定自己的实际运行方式来提高可移植性,这个功能发挥的应用场景仍然有待学习。
下面是Downward API的运行实例:
1、通过环境变量的方式将Pod信息注入容器
新建Pod配置文件dapi-test-pod.yaml,在spec.containers.env中指定环境变量来源为Downward API
设置在容器运行时打印当前环境变量
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 #Pod名称
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace #所属命名空间
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP #Pod的IP地址
restartPolicy: Never
创建Pod,等待运行完成
# kubectl create -f dapi-test-pod.yaml
pod/dapi-test-pod created# kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-pod 0/1 Completed 0 60s
查看容器运行日志,可以看到在容器的环境变量中已经包含了所属Pod的信息
# kubectl logs dapi-test-pod -c test-container
......
MY_POD_NAMESPACE=default
MY_POD_IP=10.44.0.1
......
MY_POD_NAME=dapi-test-pod
2、通过环境变量的方式将容器资源信息注入容器
新建Pod配置文件 dapi-test-pod-container-vars.yaml
对于容器设置资源上下限
通过指定env.valueFrom.resourceFieldRef在容器环境变量中包含自身资源信息
容器运行时通过shell命令prinenv打印这些信息
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: #将资源上下辖添加到容器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
创建Pod并打印运行日志,可以看到容器资源信息被成功保存到环境变量中
# kubectl create -f dapi-test-pod-container-vars.yaml
pod/dapi-test-pod-container-vars created
# kubectl logs dapi-test-pod-container-vars1
1
33554432
67108864
3、通过挂载Volume的方式向容器注入Labels、Annotations
新建Pod配置文件dapi-test-pod-volume.yaml
将Pod的Label、Annotation列表通过volumes.downwardAPI.items.fieldRef.fieldPath挂载到容器上
设置容器运行后打印挂载文件
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod-volume
labels: #设置测试label、annotation
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 /usr/labels ]]; then
echo -en '\n\n';cat /usr/labels;fi;
if [[ -e /usr/annotations ]]; then
echo -en '\n\n';cat /usr/annotations; fi;
sleep 3600;
done;
volumeMounts:
- name: podinfo
mountPath: /usr
readOnly: false
volumes: #设置将Pod的labels、annotations作为volume
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
创建Pod,查看运行日志,可以看到容器中挂载文件夹下已经包含了想要的文件
# kubectl create -f dapi-test-pod-volume.yaml
pod/dapi-test-pod-volume created
# kubectl logs dapi-test-pod-volume
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"build="two"
builder="john-doe"
>>坑 :根据原书的给的yaml尝试创建dapi-test-pod-volume,出现报错
# kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-pod-volume 0/1 RunContainerError 1 9s
使用kubectl describe查看运行event,报错如下
Warning Failed 10s kubelet, xu.node1 Error: failed to start container "test-container": Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/containers/296132ab9a72d69633770b24b2a5d5d90fe973540ebe897781b6cdce62a78847/resolv.conf\\\" to rootfs \\\"/var/lib/docker/overlay2/c56f7a7c7fc2c75835458dfd1cea7f923e1b06348b1c7ae0defb8de7a2f78409/merged\\\" at \\\"/var/lib/docker/overlay2/c56f7a7c7fc2c75835458dfd1cea7f923e1b06348b1c7ae0defb8de7a2f78409/merged/etc/resolv.conf\\\" caused \\\"open /var/lib/docker/overlay2/c56f7a7c7fc2c75835458dfd1cea7f923e1b06348b1c7ae0defb8de7a2f78409/merged/etc/resolv.conf: read-only file system\\\"\"": unknown
网上能查到的相似问题基本不能参考,后来用猜测容器挂载目标路径有问题
原挂载路径为 /etc,修改为 /usr
运行成功
猜测/etc路径权限有所限制,有待研究