平台與維運 2026 年 10 月 7 日

2026-10-07 Kubernetes 淘汰 cgroup v1:v1.35 起 kubelet 預設拒絕啟動

primary=https://kubernetes.io/blog/2026/10/06/kubernetes-cgroups-v2-shift/ primary=https://kubernetes.io/blog/2026/01/30/new-cgroup-v1-to-v2-cpu-conversion-formula/

Kubernetes 淘汰 cgroup v1:v1.35 起 kubelet 預設拒絕啟動

Kubernetes Blog(Paco Xu, DaoCloud)· 2026-10-06

從 Kubernetes v1.35 起,failCgroupV1 預設為 true,kubelet 在 cgroup v1 的節點上預設直接啟動失敗,不再只是警告。這是 v1.31 把 cgroup v1 列入維護模式之後的下一步。

官方這篇文章把遷移的理由、前置條件與排查方式一次整理出來,其中還提到 v1 退場的時程:v1 的備援選項預定在 v1.38 移除。

原本的問題

cgroup v2 自 v1.25 起就是 GA,但 cgroup v1 長期並存,所以許多叢集的舊節點一直沒動。新功能只做在 v2 上,v1 的行為則逐漸成為負擔。

  • Memory QoS 依賴 v2 的 memory.high、memory.min、memory.low,v1 提供不了這套保護模型。
  • PSI(壓力停滯資訊)需要 cgroup v2、Linux 4.20 以上、CONFIG_PSI=y,且核心不得以 psi=0 啟動。
  • v1.36 的 Pod 層級資源原地擴縮(Beta,預設啟用),要精確執行聚合限制也需要 cgroup v2。

預設行為的變化

v1.35 之前,v1 節點只會得到警告。現在 kubelet 啟動即失敗,要繼續用 v1 只能在 kubelet 設定檔明確寫入暫時性覆寫,後續移除工作由 KEP-5573 追蹤。

# 暫時保留 cgroup v1(會依 deprecation policy 移除)
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
failCgroupV1: false

kubeadm 也變嚴格:v1.35 起,SystemVerification 預檢在 kubeadm init、join、upgrade 偵測到 cgroup v1 且 kubelet 為 v1.35 以上時會回傳錯誤;kubelet 較舊時仍只是警告。

切換到 v2 之後行為會變的地方

項目cgroup v1cgroup v2
OOM 處理核心可一次只殺一個行程kubelet 預設設定 memory.oom.group,整個容器的行程一起被殺
CPU 權重cpu.sharescpu.weight(新版 runtime 使用非線性換算)
裝置控制介面檔案無介面檔案,建構於 cgroup BPF

OOM 的差異影響最直接:多行程容器以前可能只被殺掉一個 worker 而繼續半殘運作,現在會整體重啟。若依賴舊行為,要把 singleProcessOOMKill 設為 true。這個行為範圍是容器 cgroup,不是整個 Pod。

CPU 換算由 OCI runtime 負責,不在 Kubernetes:crun v1.23 與 runc v1.3.2 已採用新公式,保留預設優先權並讓小的 CPU request 有更細的解析度。會預測精確 cpu.weight 的監控或政策工具在升級 runtime 後可能要調整,細節見官方換算公式說明。

另有一點要分清:kubelet 把 active_file 記憶體視為不可回收,I/O 密集的工作負載可能因 page cache 過大而被誤判記憶體壓力(kubernetes/kubernetes#43916)。官方明說遷到 v2 本身不會改變這個計算,建議的繞法是對這類容器設定相同的 request 與 limit。

影響範圍

該檢查的對象依叢集版本而定。尚未升到 v1.35 的叢集,要先把每一個 Linux 節點遷到 cgroup v2,或規劃好 failCgroupV1: false 的暫時覆寫。已在 v1.35 以上的叢集,確認所有節點都是 v2,或確實知道自己保留了覆寫。

前置條件如下:

  • 核心 5.8 以上;使用 Memory QoS 建議 5.9 以上,較舊核心上 memory.high 回收可能 livelock,v1.36 起 kubelet 在受影響核心上會記錄警告。
  • 容器 runtime 要支援 cgroup v2:containerd v1.4 以上,或 CRI-O v1.20 以上。
  • kubelet 與 runtime 的 cgroup driver 要一致,kubeadm 管理的叢集建議 systemd driver。containerd v2.0 以上、CRI-O v1.28 以上可透過 CRI 自動偵測,此功能(KEP-4033)已於 v1.34 穩定。
  • 直接讀 cgroup 檔案系統的軟體要更新,官方建議 cAdvisor v0.43.0 以上。

時程上要留意:文章寫明 v1.36 仍保留 cgroup v1 作為備援,並預定在 v1.38 移除。也就是說,覆寫只是緩衝期,不是長期解法;用 Cilium 等依賴 cgroup BPF 的元件時,也應一併確認它們在 v2 上的掛載路徑(Cilium 預設 cgroup root 為 /run/cilium/cgroupv2)。

快速確認節點狀態

stat -fc %T /sys/fs/cgroup/   # 回傳 cgroup2fs 即為 v2
cat "$CGROUP/cpu.weight"      # 來自 CPU request,不是上限
cat "$CGROUP/cpu.max"         # limit.cpu:quota period
cat "$CGROUP/memory.max"      # limit.memory

文章還補了一個容易踩的坑:使用 systemd driver 時,runtimeSpec.linux.cgroupsPath 是 systemd 單元路徑(slice:runtime:id),不是 /sys/fs/cgroup 底下的目錄,不能直接當檔案路徑用。

仍屬 Alpha 的部分

Memory QoS 在 v1.36 仍是 Alpha,但把節流與保留拆開。啟用後 memory.high 套用在 Burstable 容器,閾值由 request、limit 與 memoryThrottlingFactor(預設 0.9)決定。若要 Guaranteed 對應 memory.min、Burstable 對應 memory.low,需設 memoryReservationPolicy: TieredReservation,BestEffort 兩者皆無。官方建議 Alpha 功能不要上正式環境,要用就先測試並計入被硬保留的記憶體。

原始來源:Kubernetes Blog:The Shift to cgroup v2 in Kubernetes、CPU shares 到 CPU weight 的新換算


End of article
0
Would love your thoughts, please comment.x
()
x