前言
在 K8s 中執行容器時,你常常會需要取得當前 Pod 的資訊——例如 Pod 名稱、所在節點、命名空間、資源限制等。K8s 提供了三種方式讓容器內的程式取得這些元數據,從簡單到進階分別是:環境變數、Downward API Volume、以及直接與 API Server 互動。
方式一:透過環境變數
最簡單的方式,直接在 Pod 定義中用 env 搭配 fieldRef 或 resourceFieldRef 來取得 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 溝通。
三個必要條件
- 知道 API Server 的位置:在叢集內可以透過
https://kubernetes或https://kubernetes.default.svc存取 - 帶上 CA 憑證:K8s 自動掛載在
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt - 帶上 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。

發佈留言