Information in this document may be out of date

This document has an older update date than the original, so the information it contains may be out of date. If you're able to read English, see the English version for the most up-to-date information: Expose Pod Information to Containers Through Files

通过文件将 Pod 信息呈现给容器

此页面描述 Pod 如何使用 downwardAPI 把自己的信息呈现给 Pod 中运行的容器。 downwardAPI 卷可以呈现 Pod 和容器的字段。

在 Kubernetes 中,有两种方式可以将 Pod 和容器字段呈现给运行中的容器:

这两种呈现 Pod 和容器字段的方式都称为 downward API

准备开始

你必须拥有一个 Kubernetes 的集群,同时你必须配置 kubectl 命令行工具与你的集群通信。 建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:

存储 Pod 字段

在这部分的练习中,你将创建一个包含一个容器的 Pod,并将 Pod 级别的字段作为文件投射到正在运行的容器中。 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: registry.k8s.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
  volumes:
    - name: podinfo
      downwardAPI:
        items:
          - path: "labels"
            fieldRef:
              fieldPath: metadata.labels
          - path: "annotations"
            fieldRef:
              fieldPath: metadata.annotations

在 Pod 清单中,你可以看到 Pod 有一个 downwardAPI 类型的卷,并且挂载到容器中的 /etc/podinfo 目录。

查看 downwardAPI 下面的 items 数组。 数组的每个元素定义一个 downwardAPI 卷。 第一个元素指示 Pod 的 metadata.labels 字段的值保存在名为 labels 的文件中。 第二个元素指示 Pod 的 annotations 字段的值保存在名为 annotations 的文件中。

创建 Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume.yaml

验证 Pod 中的容器运行正常:

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"

进入 Pod 中运行的容器,打开一个 Shell:

kubectl exec -it kubernetes-downwardapi-volume-example -- sh

在该 Shell中,查看 labels 文件:

/# cat /etc/podinfo/labels

输出显示 Pod 的所有标签都已写入 labels 文件。

cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"

同样,查看 annotations 文件:

/# cat /etc/podinfo/annotations

查看 /etc/podinfo 目录下的文件:

/# ls -laR /etc/podinfo

在输出中可以看到,labelsannotations 文件都在一个临时子目录中。 在这个例子中,这个临时子目录为 ..2982_06_02_21_47_53.299460680。 在 /etc/podinfo 目录中,..data 是指向该临时子目录的符号链接。 另外在 /etc/podinfo 目录中,labelsannotations 也是符号链接。

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

用符号链接可实现元数据的动态原子性刷新;更新将写入一个新的临时目录, 然后通过使用 rename(2) 完成 ..data 符号链接的原子性更新。

退出 Shell:

/# exit

存储容器字段

前面的练习中,你使用 downward API 使 Pod 级别的字段可以被 Pod 内正在运行的容器访问。 接下来这个练习,你将只传递由 Pod 定义的部分的字段到 Pod 内正在运行的容器中, 但这些字段取自特定容器而不是整个 Pod。 下面是一个同样只有一个容器的 Pod 的清单:

apiVersion: v1
kind: Pod
metadata:
  name: kubernetes-downwardapi-volume-example-2
spec:
  containers:
    - name: client-container
      image: registry.k8s.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
  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

在这个清单中,你可以看到 Pod 有一个 downwardAPI, 并且这个卷会挂载到 Pod 内的单个容器的 /etc/podinfo 目录。

查看 downwardAPI 下面的 items 数组。 数组的每个元素定义一个 downwardAPI 卷。

第一个元素指定在名为 client-container 的容器中, 以 1m 所指定格式的 limits.cpu 字段的值应推送到名为 cpu_limit 的文件中。 divisor 字段是可选的,默认值为 1。1 的除数表示 CPU 资源的核数或内存资源的字节数。

创建 Pod:

kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume-resources.yaml

打开一个 Shell,进入 Pod 中运行的容器:

kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh

在 Shell 中,查看 cpu_limit 文件:

# 在容器内的 Shell 中运行
cat /etc/podinfo/cpu_limit

你可以使用同样的命令查看 cpu_requestmem_limitmem_request 文件。

投射键名到指定路径并且指定文件权限

你可以将键名投射到指定路径并且指定每个文件的访问权限。 更多信息,请参阅 Secret

接下来

  • 参阅 Pod spec API 的定义,其中包括了容器(Pod 的一部分)的定义。
  • 参阅你可以使用 downward API 公开的可用字段列表。

阅读旧版的 API 参考中关于卷的内容:

  • 参阅 Volume API 定义,该 API 在 Pod 中定义通用卷以供容器访问。
  • 参阅 DownwardAPIVolumeSource API 定义,该 API 定义包含 Downward API 信息的卷。
  • 参阅 DownwardAPIVolumeFile API 定义,该 API 包含对对象或资源字段的引用,用于在 Downward API 卷中填充文件。
  • 参阅 ResourceFieldSelector API 定义,该 API 指定容器资源及其输出格式。
最后修改 October 17, 2022 at 8:11 PM PST: [zh] sync /downward-api-volume-expose-pod-information.md (aed0a43add)