為系統常駐程式預留運算資源

Kubernetes 節點可以排程至 Capacity。預設情況下,Pod 可以消耗節點上所有可用的容量。這是一個問題,因為節點通常執行相當多的系統常駐程式,以支援作業系統和 Kubernetes 本身。除非為這些系統常駐程式預留資源,否則 Pod 和系統常駐程式會競爭資源,並導致節點上的資源匱乏問題。

kubelet 公開名為「節點可分配資源」的功能,可協助為系統常駐程式預留運算資源。Kubernetes 建議叢集管理員根據每個節點上的工作負載密度設定「節點可分配資源」。

準備開始

您需要有一個 Kubernetes 叢集,並且必須將 kubectl 命令列工具設定為與您的叢集通訊。建議在至少有兩個節點的叢集上執行本教學課程,這些節點不充當控制平面主機。如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用下列 Kubernetes 練習場之一

您可以使用 kubelet 組態設定,透過 kubelet 組態檔 設定下列 kubelet 設定。

節點可分配資源

node capacity

Kubernetes 節點上的「可分配資源」定義為 Pod 可用的運算資源量。排程器不會過度訂閱「可分配資源」。目前支援「CPU」、「記憶體」和「臨時儲存」。

節點可分配資源會公開為 API 中 v1.Node 物件的一部分,以及 CLI 中 kubectl describe node 的一部分。

可以在 kubelet 中為兩種類別的系統常駐程式預留資源。

啟用 QoS 與 Pod 層級 cgroup

為了在節點上正確強制執行節點可分配資源的約束,您必須透過 cgroupsPerQOS 設定啟用新的 cgroup 階層。此設定預設為啟用。啟用後,kubelet 會將所有終端使用者 Pod 置於 kubelet 管理的 cgroup 階層下。

設定 cgroup 驅動程式

kubelet 支援使用 cgroup 驅動程式操作主機上的 cgroup 階層。驅動程式透過 cgroupDriver 設定進行設定。

支援的值如下

  • cgroupfs 是預設驅動程式,它直接操作主機上的 cgroup 檔案系統,以管理 cgroup 沙箱。
  • systemd 是一個替代驅動程式,它使用暫時性切片管理 cgroup 沙箱,用於該初始化系統支援的資源。

根據相關容器執行期的組態,運算子可能必須選擇特定的 cgroup 驅動程式,以確保正確的系統行為。例如,如果運算子使用 containerd 執行期提供的 systemd cgroup 驅動程式,則必須將 kubelet 設定為使用 systemd cgroup 驅動程式。

Kube 保留資源

  • KubeletConfiguration 設定kubeReserved: {}。範例值 {cpu: 100m, memory: 100Mi, ephemeral-storage: 1Gi, pid=1000}
  • KubeletConfiguration 設定kubeReservedCgroup: ""

kubeReserved 旨在擷取 Kubernetes 系統常駐程式(例如 kubelet容器執行期 等)的資源預留。它並非旨在為以 Pod 形式執行的系統常駐程式預留資源。kubeReserved 通常是節點上 Pod 密度 的函數。

除了 cpumemoryephemeral-storage 之外,還可以指定 pid 以為 Kubernetes 系統常駐程式預留指定的程序 ID 數量。

若要選擇性地在 Kubernetes 系統常駐程式上強制執行 kubeReserved,請將 Kube 常駐程式的父控制群組指定為 kubeReservedCgroup 設定的值,並kube-reserved 新增至 enforceNodeAllocatable

建議將 Kubernetes 系統常駐程式置於頂層控制群組下(例如,systemd 機器的 runtime.slice)。理想情況下,每個系統常駐程式都應在其自己的子控制群組中執行。如需建議的控制群組階層的更多詳細資訊,請參閱設計提案

請注意,如果 kubeReservedCgroup 不存在,Kubelet 不會建立它。如果指定了無效的 cgroup,kubelet 將無法啟動。使用 systemd cgroup 驅動程式,您應遵循為您定義的 cgroup 名稱的特定模式:名稱應為您為 kubeReservedCgroup 設定的值,並附加 .slice

系統保留資源

  • KubeletConfiguration 設定systemReserved: {}。範例值 {cpu: 100m, memory: 100Mi, ephemeral-storage: 1Gi, pid=1000}
  • KubeletConfiguration 設定systemReservedCgroup: ""

systemReserved 旨在擷取作業系統系統常駐程式(例如 sshdudev 等)的資源預留。systemReserved 也應為 kernel 預留 memory,因為目前 kernel 記憶體在 Kubernetes 中未計入 Pod。也建議為使用者登入會話預留資源(systemd 世界中的 user.slice)。

除了 cpumemoryephemeral-storage 之外,還可以指定 pid 以為作業系統系統常駐程式預留指定的程序 ID 數量。

若要選擇性地在系統常駐程式上強制執行 systemReserved,請將作業系統系統常駐程式的父控制群組指定為 systemReservedCgroup 設定的值,並system-reserved 新增至 enforceNodeAllocatable

建議將作業系統系統常駐程式置於頂層控制群組下(例如,systemd 機器的 system.slice)。

請注意,如果 systemReservedCgroup 不存在,kubelet 不會建立它。如果指定了無效的 cgroup,kubelet 將會失敗。使用 systemd cgroup 驅動程式,您應遵循為您定義的 cgroup 名稱的特定模式:名稱應為您為 systemReservedCgroup 設定的值,並附加 .slice

明確保留的 CPU 清單

功能狀態: Kubernetes v1.17 [穩定]

KubeletConfiguration 設定reservedSystemCPUs:。範例值 0-3

reservedSystemCPUs 旨在為作業系統系統常駐程式和 Kubernetes 系統常駐程式定義明確的 CPU 集。reservedSystemCPUs 適用於不打算為作業系統系統常駐程式和 Kubernetes 系統常駐程式定義獨立頂層 cgroup 的系統,關於 cpuset 資源。如果 Kubelet 沒有 kubeReservedCgroupsystemReservedCgroup,則 reservedSystemCPUs 提供的明確 cpuset 將優先於 kubeReservedCgroupsystemReservedCgroup 選項定義的 CPU。

此選項專門為電信/NFV 用例設計,在這些用例中,不受控制的中斷/計時器可能會影響工作負載效能。您可以使用此選項為系統/Kubernetes 常駐程式以及中斷/計時器定義明確的 cpuset,以便系統上的其餘 CPU 可以專門用於工作負載,並減少不受控制的中斷/計時器的影響。若要將系統常駐程式、Kubernetes 常駐程式和中斷/計時器移至此選項定義的明確 cpuset,應使用 Kubernetes 以外的其他機制。例如:在 Centos 中,您可以使用 tuned 工具組來執行此操作。

驅逐閾值

KubeletConfiguration 設定evictionHard: {memory.available: "100Mi", nodefs.available: "10%", nodefs.inodesFree: "5%", imagefs.available: "15%"}。範例值: {memory.available: "<500Mi"}

節點層級的記憶體壓力會導致系統 OOM(記憶體不足)錯誤,進而影響整個節點以及在其上執行的所有 Pod。節點可能會暫時離線,直到記憶體被回收。為了避免(或降低機率)系統 OOM 錯誤,kubelet 提供了資源耗盡管理。驅逐機制僅支援 memoryephemeral-storage。透過 evictionHard 設定保留一些記憶體,kubelet 會嘗試在節點上的可用記憶體降至低於保留值時驅逐 Pod。假設節點上不存在系統常駐程式,Pod 使用的記憶體將不會超過 capacity - eviction-hard。因此,為驅逐保留的資源無法供 Pod 使用。

強制執行節點可分配資源

KubeletConfiguration 設定enforceNodeAllocatable: [pods]。範例值: [pods,system-reserved,kube-reserved]

排程器將 'Allocatable' 視為 Pod 可用的 capacity(容量)。

預設情況下,kubelet 會跨 Pod 強制執行 'Allocatable'。強制執行的方式是在所有 Pod 的總體使用量超過 'Allocatable' 時驅逐 Pod。關於驅逐策略的更多詳細資訊,請參閱節點壓力驅逐頁面。此強制執行行為由 KubeletConfiguration 設定 enforceNodeAllocatable 中的 pods 值控制。

或者,可以透過在相同設定中指定 kube-reservedsystem-reserved 值,使 kubelet 強制執行 kubeReservedsystemReserved。請注意,若要強制執行 kubeReservedsystemReserved,則需要分別指定 kubeReservedCgroupsystemReservedCgroup

一般準則

系統常駐程式預期應與 Guaranteed Pod 類似地處理。系統常駐程式可以在其邊界控制群組內突增,而此行為需要作為 Kubernetes 部署的一部分進行管理。例如,kubelet 應該有自己的控制群組,並與容器執行時共享 kubeReserved 資源。但是,如果強制執行 kubeReserved,則 Kubelet 無法突增並用盡所有可用的節點資源。

在強制執行 systemReserved 保留時要格外小心,因為它可能導致關鍵系統服務 CPU 資源不足、被 OOM 終止,或無法在節點上 Fork。建議僅在使用者詳盡地分析其節點以得出精確估計,並確信自己有能力在該群組中的任何程序被 OOM 終止時恢復的情況下,才強制執行 systemReserved

  • 首先,在 pods 上強制執行 'Allocatable'。
  • 一旦建立了足夠的監控和警報機制來追蹤 Kube 系統常駐程式,請嘗試根據使用率啟發法來強制執行 kubeReserved
  • 如果絕對必要,隨著時間推移強制執行 systemReserved

隨著越來越多功能的加入,Kube 系統常駐程式的資源需求可能會隨著時間增長。隨著時間的推移,Kubernetes 專案將嘗試降低節點系統常駐程式的利用率,但目前這並非優先事項。因此,預計未來版本中的 Allocatable 容量會下降。

範例情境

以下範例說明節點可分配資源的計算

  • 節點具有 32Gimemory16 個 CPU100GiStorage
  • kubeReserved 設定為 {cpu: 1000m, memory: 2Gi, ephemeral-storage: 1Gi}
  • systemReserved 設定為 {cpu: 500m, memory: 1Gi, ephemeral-storage: 1Gi}
  • evictionHard 設定為 {memory.available: "<500Mi", nodefs.available: "<10%"}

在此情境下,'Allocatable' 將為 14.5 個 CPU、28.5Gi 的記憶體和 88Gi 的本機儲存空間。排程器確保此節點上所有 Pod 的總記憶體 requests 不超過 28.5Gi,且儲存空間不超過 88Gi。當 Pod 的總記憶體使用量超過 28.5Gi,或總磁碟使用量超過 88Gi 時,Kubelet 會驅逐 Pod。如果節點上的所有程序都盡可能多地消耗 CPU,則 Pod 一起不能消耗超過 14.5 個 CPU。

如果未強制執行 kubeReserved 和/或 systemReserved,且系統常駐程式超出其保留量,則當節點總記憶體使用量高於 31.5Gi 或 storage 大於 90Gi 時,kubelet 會驅逐 Pod。

上次修改時間:2024 年 6 月 4 日 凌晨 3:39 PST:Improve "Reserve Compute Resources for System Daemons" doc (#45771) (bc35539293)