k8s cgroup


 

Pod 開銷

FEATURE STATE:  Kubernetes v1.18 [beta]

在節點上運行 Pod 時,Pod 本身占用大量系統資源。這些資源是運行 Pod 內容器所需資源的附加資源。 POD 開銷 是一個特性,用於計算 Pod 基礎設施在容器請求和限制之上消耗的資源。

Pod 開銷

在 Kubernetes 中,Pod 的開銷是根據與 Pod 的 RuntimeClass 相關聯的開銷在 准入 時設置的。

當啟用 Pod 開銷時,在調度 Pod 時,除了考慮容器資源請求的總和外,還要考慮 Pod 開銷。類似地,Kubelet 將在確定 Pod cgroup 的大小和執行 Pod 驅逐排序時包含 Pod 開銷。

啟用 Pod 開銷

您需要確保在集群中啟用了 PodOverhead 特性門控 (在 1.18 默認是開啟的),以及一個用於定義 overhead 字段的 RuntimeClass

使用示例

要使用 PodOverhead 特性,需要一個定義 overhead 字段的 RuntimeClass。 作為例子,可以在虛擬機和寄宿操作系統中通過一個虛擬化容器運行時來定義 RuntimeClass 如下,其中每個 Pod 大約使用 120MiB:

---
kind: RuntimeClass
apiVersion: node.k8s.io/v1beta1
metadata:
    name: kata-fc
handler: kata-fc
overhead:
    podFixed:
        memory: "120Mi"
        cpu: "250m"

通過指定 kata-fc RuntimeClass 處理程序創建的工作負載會將內存和 cpu 開銷計入資源配額計算、節點調度以及 Pod cgroup 分級。

假設我們運行下面給出的工作負載示例 test-pod:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  runtimeClassName: kata-fc
  containers:
  - name: busybox-ctr
    image: busybox
    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 准入控制器之后,可以檢驗一下已更新的 PodSpec:

kubectl get pod test-pod -o jsonpath='{.spec.overhead}'

輸出:

map[cpu:250m memory:120Mi]

如果定義了 ResourceQuata, 則容器請求的總量以及 overhead 字段都將計算在內。

當 kube-scheduler 決定在哪一個節點調度運行新的 Pod 時,調度器會兼顧該 Pod 的 overhead 以及該 Pod 的容器請求總量。在這個示例中,調度器將資源請求和開銷相加,然后尋找具備 2.25 CPU 和 320 MiB 內存可用的節點。

一旦 Pod 調度到了某個節點, 該節點上的 kubelet 將為該 Pod 新建一個 cgroup. 底層容器運行時將在這個 pod 中創建容器。

如果該資源對每一個容器都定義了一個限制(定義了受限的 Guaranteed QoS 或者 Bustrable QoS),kubelet 會為與該資源(CPU 的 cpu.cfs_quota_us 以及內存的 memory.limit_in_bytes) 相關的 pod cgroup 設定一個上限。該上限基於容器限制總量與 PodSpec 中定義的 overhead 之和。

對於 CPU, 如果 Pod 的 QoS 是 Guaranteed 或者 Burstable, 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 內存,包含了 PodOverhead 在內:

  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 的內存 cgroups. 在接下來的例子中,將在該節點上使用具備 CRI 兼容的容器運行時命令行工具 crictl. 這是一個展示 PodOverhead 行為的進階示例,用戶並不需要直接在該節點上檢查 cgroups.

首先在特定的節點上確定該 Pod 的標識符:ying

# 在該 Pod 調度的節點上執行如下命令:
POD_ID="$(sudo crictl pods --name test-pod -q)"

可以依此判斷該 Pod 的 cgroup 路徑:

# 在該 Pod 調度的節點上執行如下命令:
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 設置:

# 在該 Pod 調度的節點上執行這個命令。
# 另外,修改 cgroup 的名稱以匹配為該 pod 分配的 cgroup。
 cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memory.limit_in_bytes

和預期的一樣是 320 MiB

335544320


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM