透過檔案向容器公開 Pod 資訊

本頁面展示了 Pod 如何使用 downwardAPI,將自身的 Pod 資訊暴露給 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:1.27.2
      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 有一個 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

使用符號連結可以實現元資料的動態原子重新整理;更新會寫入新的臨時目錄,並且 ..data 符號連結會使用 rename(2) 進行原子更新。

退出 Shell

/# exit

儲存容器欄位

在前面的練習中,你使用 Downward API 使 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.27.2
      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 陣列。陣列的每個元素都定義了 Downward API 卷中的一個檔案。

第一個元素指定在名為 client-container 的容器中,limits.cpu 欄位的值以 1m 指定的格式釋出為名為 cpu_limit 的檔案。divisor 欄位是可選的,預設值為 1。除數 1 表示 CPU 資源的核心數,或記憶體資源的位元組數。

建立 Pod

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

進入 Pod 中執行的容器的 Shell

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

在你的 Shell 中,檢視 cpu_limit 檔案

# Run this in a shell inside the container
cat /etc/podinfo/cpu_limit

你可以使用類似的命令檢視 cpu_requestmem_limitmem_request 檔案。

將鍵投射到特定路徑和檔案許可權

你可以將鍵投射到特定路徑和每個檔案的特定許可權。有關更多資訊,請參閱 Secrets

下一步

  • 閱讀 Pod 的 spec API 定義。這包括容器的定義(Pod 的一部分)。
  • 閱讀你可以使用 Downward API 暴露的可用欄位列表。

閱讀關於舊版 API 參考中的卷

  • 檢查 Volume API 定義,它定義了 Pod 中供容器訪問的通用卷。
  • 檢查 DownwardAPIVolumeSource API 定義,它定義了一個包含 Downward API 資訊的卷。
  • 檢查 DownwardAPIVolumeFile API 定義,它包含對物件或資源欄位的引用,用於填充 Downward API 卷中的檔案。
  • 檢查 ResourceFieldSelector API 定義,它指定容器資源及其輸出格式。
最後修改於 2023 年 8 月 24 日下午 6:38 PST:使用 code_sample 簡碼代替 code 簡碼 (e8b136c3b3)