Kubernetes 通過(guò)文件將Pod信息呈現(xiàn)給容器

2022-06-13 14:16 更新

通過(guò)文件將 Pod 信息呈現(xiàn)給容器

此頁(yè)面描述 Pod 如何使用 DownwardAPIVolumeFile 把自己的信息呈現(xiàn)給 Pod 中運(yùn)行的容器。 ?DownwardAPIVolumeFile ?可以呈現(xiàn) Pod 和容器的字段。

在開(kāi)始之前

你必須擁有一個(gè) Kubernetes 的集群,同時(shí)你的 Kubernetes 集群必須帶有 kubectl 命令行工具。 建議在至少有兩個(gè)節(jié)點(diǎn)的集群上運(yùn)行本教程,且這些節(jié)點(diǎn)不作為控制平面主機(jī)。 如果你還沒(méi)有集群,你可以通過(guò) Minikube 構(gòu)建一個(gè)你自己的集群,或者你可以使用下面任意一個(gè) Kubernetes 工具構(gòu)建:

要獲知版本信息,請(qǐng)輸入 kubectl version。

Downward API 

有兩種方式可以將 Pod 和 Container 字段呈現(xiàn)給運(yùn)行中的容器:

  • 環(huán)境變量
  • 卷文件

這兩種呈現(xiàn) Pod 和 Container 字段的方式都稱(chēng)為 "Downward API"。

存儲(chǔ) Pod 字段 

在這個(gè)練習(xí)中,你將創(chuàng)建一個(gè)包含一個(gè)容器的 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: k8s.gcr.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 有一個(gè) ?downwardAPI ?類(lèi)型的卷,并且掛載到容器中的 ?/etc/podinfo? 目錄。

查看 ?downwardAPI ?下面的 ?items ?數(shù)組。 每個(gè)數(shù)組元素都是一個(gè) DownwardAPIVolumeFile 對(duì)象。 第一個(gè)元素指示 Pod 的 ?metadata.labels? 字段的值保存在名為 ?labels ?的文件中。 第二個(gè)元素指示 Pod 的 ?annotations ?字段的值保存在名為 ?annotations ?的文件中。

說(shuō)明: 本示例中的字段是Pod字段,不是Pod中容器的字段。

創(chuàng)建 Pod:

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

驗(yàn)證Pod中的容器運(yùn)行正常:

kubectl get pods

查看容器的日志:

kubectl logs kubernetes-downwardapi-volume-example

輸出顯示 ?labels ?和 ?annotations ?文件的內(nèi)容:

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

build="two"
builder="john-doe"

進(jìn)入 Pod 中運(yùn)行的容器,打開(kāi)一個(gè) Shell:

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

在該 Shell中,查看 ?labels? 文件:

/# cat /etc/podinfo/labels

輸出顯示 Pod 的所有標(biāo)簽都已寫(xiě)入 ?labels ?文件。

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

同樣,查看 ?annotations ?文件:

/# cat /etc/podinfo/annotations

查看 ?/etc/podinfo? 目錄下的文件:

/# ls -laR /etc/podinfo

在輸出中可以看到,labels 和 annotations 文件都在一個(gè)臨時(shí)子目錄中。 在這個(gè)例子,..2982_06_02_21_47_53.299460680。 在 /etc/podinfo 目錄中,..data 是一個(gè)指向臨時(shí)子目錄 的符號(hào)鏈接。/etc/podinfo 目錄中,labels 和 annotations 也是符號(hào)鏈接。

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

用符號(hào)鏈接可實(shí)現(xiàn)元數(shù)據(jù)的動(dòng)態(tài)原子性刷新;更新將寫(xiě)入一個(gè)新的臨時(shí)目錄, 然后通過(guò)使用 rename(2) 完成 ..data 符號(hào)鏈接的原子性更新。

說(shuō)明: 如果容器以 subPath卷掛載方式來(lái)使用 Downward API,則該容器無(wú)法收到更新事件。

退出 Shell:

/# exit

存儲(chǔ)容器字段 

前面的練習(xí)中,你將 Pod 字段保存到 ?DownwardAPIVolumeFile ?中。 接下來(lái)這個(gè)練習(xí),你將存儲(chǔ) Container 字段。這里是包含一個(gè)容器的 Pod 的配置文件:

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

在這個(gè)配置文件中,你可以看到 Pod 有一個(gè) ?downwardAPI ?卷, 并且掛載到容器的 ?/etc/podinfo? 目錄。

查看 ?downwardAPI ?下面的 ?items ?數(shù)組。每個(gè)數(shù)組元素都是一個(gè) DownwardAPIVolumeFile

第一個(gè)元素指定在名為 ?client-container? 的容器中, 以 ?1m? 所指定格式的 ?limits.cpu? 字段的值應(yīng)保存在名為 ?cpu_limit ?的文件中。 ?divisor ?字段是可選的,默認(rèn)值為 1,表示 CPU 的核心和內(nèi)存的字節(jié)。

創(chuàng)建Pod:

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

打開(kāi)一個(gè) Shell,進(jìn)入 Pod 中運(yùn)行的容器:

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

在 Shell 中,查看 ?cpu_limit ?文件:

/# cat /etc/podinfo/cpu_limit

你可以使用同樣的命令查看 ?cpu_request?、?mem_limit ?和 ?mem_request ?文件.

Downward API 的能力 

下面這些信息可以通過(guò)環(huán)境變量和 ?downwardAPI ?卷提供給容器:

能通過(guò) ?fieldRef ?獲得的:

  • ?metadata.name? - Pod 名稱(chēng)
  • ?metadata.namespace? - Pod 名字空間
  • ?metadata.uid? - Pod 的 UID
  • ?metadata.labels['<KEY>']? - Pod 標(biāo)簽 ?<KEY>? 的值 (例如:?metadata.labels['mylabel']?)
  • ?metadata.annotations['<KEY>']? - Pod 的注解 ?<KEY>? 的值 (例如:?metadata.annotations['myannotation']?)

能通過(guò) ?resourceFieldRef ?獲得的:

  • 容器的 CPU 約束值
  • 容器的 CPU 請(qǐng)求值
  • 容器的內(nèi)存約束值
  • 容器的內(nèi)存請(qǐng)求值
  • 容器的巨頁(yè)限制值(前提是啟用了 ?DownwardAPIHugePages ?特性門(mén)控)
  • 容器的巨頁(yè)請(qǐng)求值(前提是啟用了 ?DownwardAPIHugePages ?特性門(mén)控)
  • 容器的臨時(shí)存儲(chǔ)約束值
  • 容器的臨時(shí)存儲(chǔ)請(qǐng)求值

此外,以下信息可通過(guò) ?downwardAPI ?卷從 ?fieldRef ?獲得:

  • ?metadata.labels? - Pod 的所有標(biāo)簽,以 ?label-key="escaped-label-value"? 格式顯示,每行顯示一個(gè)標(biāo)簽
  • ?metadata.annotations? - Pod 的所有注解,以 ?annotation-key="escaped-annotation-value"? 格式顯示,每行顯示一個(gè)標(biāo)簽

以下信息可通過(guò)環(huán)境變量獲得:

  • ?status.podIP? - Pod IP 地址
  • ?spec.serviceAccountName? - Pod 服務(wù)帳號(hào)名稱(chēng)
  • ?spec.nodeName? - 調(diào)度器總是嘗試將 Pod 調(diào)度到的節(jié)點(diǎn)的名稱(chēng)
  • ?status.hostIP? - Pod 分配到的節(jié)點(diǎn)的 IP

說(shuō)明: 如果容器未指定 CPU 和內(nèi)存限制,則 Downward API 默認(rèn)將節(jié)點(diǎn)可分配值 視為容器的 CPU 和內(nèi)存限制。

投射鍵名到指定路徑并且指定文件權(quán)限 

你可以將鍵名投射到指定路徑并且指定每個(gè)文件的訪(fǎng)問(wèn)權(quán)限。

Downward API 的動(dòng)機(jī) 

對(duì)于容器來(lái)說(shuō),有時(shí)候擁有自己的信息是很有用的,可避免與 Kubernetes 過(guò)度耦合。 Downward API 使得容器使用自己或者集群的信息,而不必通過(guò) Kubernetes 客戶(hù)端或 API 服務(wù)器來(lái)獲得。

一個(gè)例子是有一個(gè)現(xiàn)有的應(yīng)用假定要用一個(gè)非常熟悉的環(huán)境變量來(lái)保存一個(gè)唯一標(biāo)識(shí)。 一種可能是給應(yīng)用增加處理層,但這樣是冗余和易出錯(cuò)的,而且它違反了低耦合的目標(biāo)。 更好的選擇是使用 Pod 名稱(chēng)作為標(biāo)識(shí),把 Pod 名稱(chēng)注入這個(gè)環(huán)境變量中。


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)