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

在准入時,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 額外負擔何時被使用,並協助觀察以定義的額外負擔執行的工作負載之穩定性。

下一步

上次修改時間為 2024年4月10日下午 5:56 PST:在 Pod Overhead 概念中解釋 RuntimeClass 名稱 (#45454) (c25ceaa535)