kubernetes容器編排之定義環境變數以及通過downwardapi把pod資訊作為環境變數傳入容器內

周國通發表於2019-06-18

系列目錄

在學習docker的時候,大家可能經常看到不少示例在docker run的時候指定環境變數(比如wordpress的docker示例就是通過環境變數傳入賬戶和密碼到容器內).這裡之所以經常用到環境變數,主要基於以下兩點原因

  • 容器內的操作往往都是自動化的,而不像在windows會有圖形介面提示輸入資訊或者像在linux有互動式命令可以輸入程式需要的資料.也就是程式執行時需要的引數無法互動式指定,不同程式讀取配置的方式又各式各樣,這種情況下讀取環境變數是比較通用的做法

  • 容器的隔離性,在k8s裡,pod是最小的邏輯單元,關於容器執行時的很多資訊(pod的ip,節點的ip,申請的cpu資源,記憶體資源)都存在pod裡,但是有些時候pod內的容器想要知道這些資訊,然而容器無法直接讀取到pod的所有資訊,kubernetes本身提供了download ap(下面交介紹)i來把pod的資訊傳遞給容器,其實就是通過環境變數把pod的資訊傳遞給容器.

為容器定義環境變數

當建立pod的時候,可以在配置檔案裡使用env欄位來定義環境變數,示例如下

apiVersion: v1
kind: Pod
metadata:
  name: envar-demo
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: envar-demo-container
    image: tutum/hello-world
    env:
    - name: DEMO_GREETING
      value: "Hello from the environment"
    - name: DEMO_FAREWELL
      value: "Such a sweet sorrow"

我們通過kubectl apply -f建立它

通過執行命令kubectl exec -it envar-demo /bin/sh進入互動式命令執行容器

輸入printenv來檢視環境變數是否正確傳入

/ # printenv DEMO_GREETING
Hello from the environment
/ # printenv DEMO_FAREWELL
Such a sweet sorrow
/ #

在配置檔案中使用環境變數

以上我們通過互動式容器檢視到了我們定義的環境變數,實際上我們在配置檔案中定義的環境變數也可以在配置檔案中其它位置被引用,比如做為容器初始化執行命令的引數,請看下面示例:

apiVersion: v1
kind: Pod
metadata:
  name: print-greeting
spec:
  containers:
  - name: env-print-demo
    image: tutum/hello-world
    env:
    - name: GREETING
      value: "Warm greetings to"
    - name: HONORIFIC
      value: "The Most Honorable"
    - name: NAME
      value: "Kubernetes"
    command: ["echo"]
    args: ["$(GREETING) $(HONORIFIC) $(NAME)"]

與上面不同的是,上面僅僅定義了變數,這裡我們引用了定義的變數.

我們通過以上配置建立容器,然後執行kubectl logs檢視輸出日誌

λ kubectl logs print-greeting
Warm greetings to The Most Honorable Kubernetes

可以看到,被引用的環境變數內容輸出了.

downwardapi介紹及簡單使用

對於一些容器型別,特別是有狀態的,它執行的時候可能需要知道外部依附於pod的資訊,比如pod的ip,叢集ip,pod申請的記憶體和cpu數量等.這時候可以通過環境變數把這些依附於pod的欄位資訊傳入到容器內容.另一種方式是通過DownwardAPIVolumeFiles把資訊傳入到容器內容,這兩種方式合在一起被稱作downward api

使用pod的欄位值作為環境變數

apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-fieldref
spec:
  containers:
    - name: test-container
      image: tutum/hello-world
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
          printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: MY_POD_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
  restartPolicy: Never

以上配置檔案,我們引用了pod的若干屬性然後通過printenv列印出來檢視.

我們使用kubectl logs pod名稱來檢視輸出資訊

docker-for-desktop
dapi-envars-fieldref
default
10.1.0.75

需要注意的是,以上欄位是pod的欄位,而不是容器的欄位.

相關文章