← 返回上一頁
Kubernetes

K8s Pod 元數據存取三種方式:環境變數、Downward API 與 API Server 互動

本頁目錄

前言

在 K8s 中執行容器時,你常常會需要取得當前 Pod 的資訊——例如 Pod 名稱、所在節點、命名空間、資源限制等。K8s 提供了三種方式讓容器內的程式取得這些元數據,從簡單到進階分別是:環境變數、Downward API Volume、以及直接與 API Server 互動。

方式一:透過環境變數

最簡單的方式,直接在 Pod 定義中用 env 搭配 fieldRefresourceFieldRef 來取得 Pod 的元數據:

apiVersion: v1
kind: Pod
metadata:
  name: my-downward
spec:
  containers:
  - name: my-downward
    image: busybox
    command: ["sleep","8888888"]
    env:
    - name: MY_POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: MY_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: MY_NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: MY_SERVICE_ACCOUNT
      valueFrom:
        fieldRef:
          fieldPath: spec.serviceAccountName
    - name: MY_REQUEST_CPU
      valueFrom:
        resourceFieldRef:
          resource: requests.cpu
          divisor: 1m
    - name: MY_LIMITS_MEMORY
      valueFrom:
        resourceFieldRef:
          resource: limits.memory
          divisor: 1Ki

常用的 fieldPath 可取得的欄位:

fieldPath 對應資訊
metadata.name Pod 名稱
metadata.namespace 命名空間
metadata.labels 所有 Label
spec.nodeName 所在節點名稱
spec.serviceAccountName Service Account 名稱
status.podIP Pod IP

建立 Pod 後進入容器,用 env 指令就能看到所有自訂的環境變數。

方式二:透過 Downward API Volume

Downward API 並不是 REST API,而是一種把 Pod 的定義和狀態資訊以檔案形式掛載到容器中的機制。

apiVersion: v1
kind: Pod
metadata:
  name: my-downward-vol
  labels:
    env: dev
spec:
  containers:
  - name: my-downward-vol
    image: busybox
    command: ["sleep","8888888"]
    volumeMounts:
    - name: podinfo
      mountPath: /etc/podinfo
  volumes:
  - name: podinfo
    downwardAPI:
      items:
      - path: "podName"
        fieldRef:
          fieldPath: metadata.name
      - path: "namespace"
        fieldRef:
          fieldPath: metadata.namespace
      - path: "labels"
        fieldRef:
          fieldPath: metadata.labels

建立後進入容器,可以在 /etc/podinfo/ 目錄下看到對應的檔案,每個檔案的內容就是對應的元數據值。

Downward API Volume 的優勢

相比環境變數,Volume 方式有一個重要的特性:當元數據改變時(例如修改 label),檔案內容會自動更新,而環境變數在 Pod 啟動後就固定了。

# 修改 label
kubectl label pod my-downward-vol env=prod --overwrite

# 進入容器查看,/etc/podinfo/labels 的內容會自動更新

方式三:與 API Server 互動

前兩種方式只能取得自身 Pod 的資訊。如果你需要查詢其他 Pod 或叢集中的其他資源,就必須直接跟 API Server 溝通。

三個必要條件

  1. 知道 API Server 的位置:在叢集內可以透過 https://kuberneteshttps://kubernetes.default.svc 存取
  2. 帶上 CA 憑證:K8s 自動掛載在 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  3. 帶上 Token:自動掛載在 /var/run/secrets/kubernetes.io/serviceaccount/token

實際操作

先確保有適當的 RBAC 權限(否則會收到 403 Forbidden):

kubectl create clusterrolebinding my-cluster-admin \
  --clusterrole=cluster-admin \
  --group=system:serviceaccounts \
  --namespace=YOUR_NAMESPACE

進入容器後:

# 設定 CA 憑證
export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

# 讀取 Token
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

# 存取 API Server
curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/default/pods

這樣就能查詢到其他 Pod 的資訊、Service、ConfigMap 等所有 K8s 資源。

安全提醒:上面用了 cluster-admin 權限只是為了演示方便。生產環境務必遵循最小權限原則,只授予必要的存取範圍。

三種方式比較

方式 適用場景 動態更新 可存取範圍
環境變數 取得自身 Pod 基本資訊 否(啟動後固定) 僅自身 Pod
Downward API Volume 需要動態感知自身元數據變化 僅自身 Pod
API Server 互動 需要查詢叢集中任意資源 即時查詢 叢集內所有資源(受 RBAC 限制)

小結

三種方式各有適用場景:需要簡單取得自身資訊用環境變數,需要動態追蹤 label 變化用 Downward API Volume,需要跨 Pod 查詢就用 API Server。實務上最常見的做法是前兩者搭配使用,只有在真正需要查詢其他資源時才走 API Server。

分享這篇
X LinkedIn Facebook Hacker News Reddit

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料