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: falsekubeadm 也變嚴格:v1.35 起,SystemVerification 預檢在 kubeadm init、join、upgrade 偵測到 cgroup v1 且 kubelet 為 v1.35 以上時會回傳錯誤;kubelet 較舊時仍只是警告。
切換到 v2 之後行為會變的地方
| 項目 | cgroup v1 | cgroup v2 |
|---|---|---|
| OOM 處理 | 核心可一次只殺一個行程 | kubelet 預設設定 memory.oom.group,整個容器的行程一起被殺 |
| CPU 權重 | cpu.shares | cpu.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 的新換算