Pod 額外負擔
Kubernetes v1.24 [穩定]
當您在節點上執行 Pod 時,Pod 本身會佔用一定數量的系統資源。這些資源是執行 Pod 內容器所需的資源之外的額外資源。在 Kubernetes 中,「Pod 額外負擔」是一種計算 Pod 基礎架構所消耗資源的方式,此資源是在容器請求與限制之上的額外資源。
在 Kubernetes 中,Pod 的額外負擔會在准入時根據與 Pod 的RuntimeClass 相關聯的額外負擔來設定。
在排程 Pod 時,除了容器資源請求的總和之外,還會考量 Pod 的額外負擔。同樣地,kubelet 在調整 Pod cgroup 大小時以及執行 Pod 驅逐排名時,將會包含 Pod 額外負擔。
設定 Pod 額外負擔
您需要確保使用定義 overhead
欄位的 RuntimeClass
。
使用範例
若要使用 Pod 額外負擔,您需要定義 overhead
欄位的 RuntimeClass。例如,您可以將下列 RuntimeClass 定義與虛擬化容器運行時搭配使用(在此範例中,Kata Containers 與 Firecracker 虛擬機器監控器結合),每個 Pod 的虛擬機器和客體作業系統約使用 120MiB
# You need to change this example to match the actual runtime name, and per-Pod
# resource overhead, that the container runtime is adding in your cluster.
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata-fc
handler: kata-fc
overhead:
podFixed:
memory: "120Mi"
cpu: "250m"
指定 kata-fc
RuntimeClass 處理常式建立的工作負載,將會在資源配額計算、節點排程以及 Pod cgroup 大小調整時,將記憶體和 CPU 額外負擔納入考量。
考量執行給定的範例工作負載 test-pod
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
runtimeClassName: kata-fc
containers:
- name: busybox-ctr
image: busybox:1.28
stdin: true
tty: true
resources:
limits:
cpu: 500m
memory: 100Mi
- name: nginx-ctr
image: nginx
resources:
limits:
cpu: 1500m
memory: 100Mi
注意
如果 Pod 定義中僅指定limits
,則 kubelet 將從這些限制中推斷 requests
,並將其設定為與定義的 limits
相同。在准入時,RuntimeClass 准入控制器 會更新工作負載的 PodSpec 以包含 RuntimeClass 中描述的 overhead
。如果 PodSpec 已定義此欄位,則 Pod 將被拒絕。在給定的範例中,由於僅指定 RuntimeClass 名稱,因此准入控制器會變更 Pod 以包含 overhead
。
在 RuntimeClass 准入控制器進行修改後,您可以檢查更新的 Pod 額外負擔值
kubectl get pod test-pod -o jsonpath='{.spec.overhead}'
輸出為
map[cpu:250m memory:120Mi]
如果定義了ResourceQuota,則會計算容器請求的總和以及 overhead
欄位。
當 kube-scheduler 決定哪個節點應執行新的 Pod 時,排程器會考量該 Pod 的 overhead
以及該 Pod 的容器請求總和。對於此範例,排程器會將請求和額外負擔相加,然後尋找具有 2.25 個 CPU 和 320 MiB 可用記憶體的節點。
一旦 Pod 排程到節點,該節點上的 kubelet 會為 Pod 建立新的 cgroup。基礎容器運行時將在此 Pod 中建立容器。
如果資源為每個容器定義了限制(保證 QoS 或具有定義限制的可突發 QoS),則 kubelet 將為與該資源相關聯的 Pod cgroup 設定上限(CPU 的 cpu.cfs_quota_us 和記憶體的 memory.limit_in_bytes)。此上限基於容器限制的總和加上 PodSpec 中定義的 overhead
。
對於 CPU,如果 Pod 是保證或可突發 QoS,則 kubelet 將根據容器請求的總和加上 PodSpec 中定義的 overhead
來設定 cpu.shares
。
查看我們的範例,驗證工作負載的容器請求
kubectl get pod test-pod -o jsonpath='{.spec.containers[*].resources.limits}'
容器請求總計為 2000m CPU 和 200MiB 記憶體
map[cpu: 500m memory:100Mi] map[cpu:1500m memory:100Mi]
根據節點觀察到的內容檢查此值
kubectl describe node | grep test-pod -B2
輸出顯示 2250m CPU 和 320MiB 記憶體的請求。請求包含 Pod 額外負擔
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
default test-pod 2250m (56%) 2250m (56%) 320Mi (1%) 320Mi (1%) 36m
驗證 Pod cgroup 限制
檢查執行工作負載的節點上的 Pod 記憶體 cgroup。在以下範例中,節點上使用了 crictl
,它為與 CRI 相容的容器運行時提供 CLI。這是一個進階範例,用於顯示 Pod 額外負擔行為,並且預期使用者不需要直接在節點上檢查 cgroup。
首先,在特定節點上,判斷 Pod 識別碼
# Run this on the node where the Pod is scheduled
POD_ID="$(sudo crictl pods --name test-pod -q)"
從此,您可以判斷 Pod 的 cgroup 路徑
# Run this on the node where the Pod is scheduled
sudo crictl inspectp -o=json $POD_ID | grep cgroupsPath
產生的 cgroup 路徑包含 Pod 的 pause
容器。Pod 層級 cgroup 在上面一個目錄。
"cgroupsPath": "/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/7ccf55aee35dd16aca4189c952d83487297f3cd760f1bbf09620e206e7d0c27a"
在此特定案例中,pod cgroup 路徑為 kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2
。驗證記憶體的 Pod 層級 cgroup 設定
# Run this on the node where the Pod is scheduled.
# Also, change the name of the cgroup to match the cgroup allocated for your pod.
cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memory.limit_in_bytes
正如預期的,這是 320 MiB
335544320
可觀測性
部分 kube_pod_overhead_*
指標可在 kube-state-metrics 中取得,以協助識別 Pod 額外負擔何時被使用,並協助觀察以定義的額外負擔執行的工作負載之穩定性。
下一步
- 深入瞭解 RuntimeClass
- 閱讀 PodOverhead 設計增強提案,以取得更多背景資訊