Kubernetes Pod開(kāi)銷(xiāo)

2022-05-26 10:02 更新

Pod 開(kāi)銷(xiāo)

FEATURE STATE: Kubernetes v1.24 [stable]

在節(jié)點(diǎn)上運(yùn)行 Pod 時(shí),Pod 本身占用大量系統(tǒng)資源。這些是運(yùn)行 Pod 內(nèi)容器所需資源之外的資源。 在 Kubernetes 中,POD 開(kāi)銷(xiāo) 是一種方法,用于計(jì)算 Pod 基礎(chǔ)設(shè)施在容器請(qǐng)求和限制之上消耗的資源。

在 Kubernetes 中,Pod 的開(kāi)銷(xiāo)是根據(jù)與 Pod 的 RuntimeClass 相關(guān)聯(lián)的開(kāi)銷(xiāo)在準(zhǔn)入時(shí)設(shè)置的。

如果啟用了 Pod Overhead,在調(diào)度 Pod 時(shí),除了考慮容器資源請(qǐng)求的總和外,還要考慮 Pod 開(kāi)銷(xiāo)。 類(lèi)似地,kubelet 將在確定 Pod cgroups 的大小和執(zhí)行 Pod 驅(qū)逐排序時(shí)也會(huì)考慮 Pod 開(kāi)銷(xiāo)。

配置 Pod 開(kāi)銷(xiāo) 

你需要確保使用一個(gè)定義了 ?overhead ?字段的 ?RuntimeClass?。

使用示例

要使用 Pod 開(kāi)銷(xiāo),你需要一個(gè)定義了 ?overhead ?字段的 RuntimeClass。 作為例子,下面的 RuntimeClass 定義中包含一個(gè)虛擬化所用的容器運(yùn)行時(shí), RuntimeClass 如下,其中每個(gè) Pod 大約使用 120MiB 用來(lái)運(yùn)行虛擬機(jī)和寄宿操作系統(tǒng):

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

通過(guò)指定 ?kata-fc? RuntimeClass 處理程序創(chuàng)建的工作負(fù)載會(huì)將內(nèi)存和 CPU 開(kāi)銷(xiāo)計(jì)入資源配額計(jì)算、節(jié)點(diǎn)調(diào)度以及 Pod cgroup 尺寸確定。

假設(shè)我們運(yùn)行下面給出的工作負(fù)載示例 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

在準(zhǔn)入階段 RuntimeClass 準(zhǔn)入控制器 更新工作負(fù)載的 PodSpec 以包含 RuntimeClass 中定義的 ?overhead?。如果 PodSpec 中已定義該字段,該 Pod 將會(huì)被拒絕。 在這個(gè)例子中,由于只指定了 RuntimeClass 名稱(chēng),所以準(zhǔn)入控制器更新了 Pod,使之包含 ?overhead?。

在 RuntimeClass 準(zhǔn)入控制器進(jìn)行修改后,你可以查看更新后的 PodSpec:

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

輸出:

map[cpu:250m memory:120Mi]

如果定義了 ResourceQuata, 則容器請(qǐng)求的總量以及 ?overhead ?字段都將計(jì)算在內(nèi)。

當(dāng) kube-scheduler 決定在哪一個(gè)節(jié)點(diǎn)調(diào)度運(yùn)行新的 Pod 時(shí),調(diào)度器會(huì)兼顧該 Pod 的 ?overhead ?以及該 Pod 的容器請(qǐng)求總量。在這個(gè)示例中,調(diào)度器將資源請(qǐng)求和開(kāi)銷(xiāo)相加, 然后尋找具備 2.25 CPU 和 320 MiB 內(nèi)存可用的節(jié)點(diǎn)。

一旦 Pod 被調(diào)度到了某個(gè)節(jié)點(diǎn), 該節(jié)點(diǎn)上的 kubelet 將為該 Pod 新建一個(gè) cgroup。 底層容器運(yùn)行時(shí)將在這個(gè) Pod 中創(chuàng)建容器。

如果該資源對(duì)每一個(gè)容器都定義了一個(gè)限制(定義了限制值的 Guaranteed QoS 或者 Burstable QoS),kubelet 會(huì)為與該資源(CPU 的 ?cpu.cfs_quota_us? 以及內(nèi)存的 ?memory.limit_in_bytes?) 相關(guān)的 Pod cgroup 設(shè)定一個(gè)上限。該上限基于 PodSpec 中定義的容器限制總量與 ?overhead ?之和。

對(duì)于 CPU,如果 Pod 的 QoS 是 Guaranteed 或者 Burstable,kubelet 會(huì)基于容器請(qǐng)求總量與 PodSpec 中定義的 ?overhead ?之和設(shè)置 ?cpu.shares?。

請(qǐng)看這個(gè)例子,驗(yàn)證工作負(fù)載的容器請(qǐng)求:

kubectl get pod test-pod -o jsonpath='{.spec.containers[*].resources.limits}'

容器請(qǐng)求總計(jì) 2000m CPU 和 200MiB 內(nèi)存:

map[cpu: 500m memory:100Mi] map[cpu:1500m memory:100Mi]

對(duì)照從節(jié)點(diǎn)觀(guān)察到的情況來(lái)檢查一下:

kubectl describe node | grep test-pod -B2

該輸出顯示請(qǐng)求了 2250m CPU 以及 320MiB 內(nèi)存。請(qǐng)求包含了 Pod 開(kāi)銷(xiāo)在內(nèi):

  Namespace    Name       CPU Requests  CPU Limits   Memory Requests  Memory Limits  AGE
  ---------    ----       ------------  ----------   ---------------  -------------  ---
  default      test-pod   2250m (56%)   2250m (56%)  320Mi (1%)       320Mi (1%)     36m

驗(yàn)證 Pod cgroup 限制

在工作負(fù)載所運(yùn)行的節(jié)點(diǎn)上檢查 Pod 的內(nèi)存 cgroups。在接下來(lái)的例子中, 將在該節(jié)點(diǎn)上使用具備 CRI 兼容的容器運(yùn)行時(shí)命令行工具 ?crictl?。 這是一個(gè)顯示 Pod 開(kāi)銷(xiāo)行為的高級(jí)示例, 預(yù)計(jì)用戶(hù)不需要直接在節(jié)點(diǎn)上檢查 cgroups。 首先在特定的節(jié)點(diǎn)上確定該 Pod 的標(biāo)識(shí)符:

# 在該 Pod 被調(diào)度到的節(jié)點(diǎn)上執(zhí)行如下命令:
POD_ID="$(sudo crictl pods --name test-pod -q)"

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

# 在該 Pod 被調(diào)度到的節(jié)點(diǎn)上執(zhí)行如下命令:
sudo crictl inspectp -o=json $POD_ID | grep cgroupsPath

執(zhí)行結(jié)果的 cgroup 路徑中包含了該 Pod 的 ?pause ?容器。Pod 級(jí)別的 cgroup 在即上一層目錄。

  "cgroupsPath": "/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/7ccf55aee35dd16aca4189c952d83487297f3cd760f1bbf09620e206e7d0c27a"

在這個(gè)例子中,該 Pod 的 cgroup 路徑是 ?kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2?。 驗(yàn)證內(nèi)存的 Pod 級(jí)別 cgroup 設(shè)置:

# 在該 Pod 被調(diào)度到的節(jié)點(diǎn)上執(zhí)行這個(gè)命令。
# 另外,修改 cgroup 的名稱(chēng)以匹配為該 Pod 分配的 cgroup。
 cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memory.limit_in_bytes

和預(yù)期的一樣,這一數(shù)值為 320 MiB。

335544320

可觀(guān)察性 

在 kube-state-metrics 中可以通過(guò) ?kube_pod_overhead_*? 指標(biāo)來(lái)協(xié)助確定何時(shí)使用 Pod 開(kāi)銷(xiāo), 以及協(xié)助觀(guān)察以一個(gè)既定開(kāi)銷(xiāo)運(yùn)行的工作負(fù)載的穩(wěn)定性。 該特性在 kube-state-metrics 的 1.9 發(fā)行版本中不可用,不過(guò)預(yù)計(jì)將在后續(xù)版本中發(fā)布。 在此之前,用戶(hù)需要從源代碼構(gòu)建 kube-state-metrics。


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)