【Kubernetes】Pod学习(五)从Pod到容器:Downward API

此文为学习《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-vars

1
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路径权限有所限制,有待研究

发布了27 篇原创文章 · 获赞 0 · 访问量 959

猜你喜欢

转载自blog.csdn.net/qq_38093301/article/details/103484948