Kubernetes 向 cgroup v2 的转变:你需要了解的内容

💡 原文英文,约1700词,阅读约需7分钟。
📝

内容提要

Kubernetes 已弃用 cgroup v1:v1.35 起 kubelet 默认拒绝在 cgroup v1 节点启动,v1.38 将彻底移除支持。cgroup v2 提供统一层级和更强隔离,支持内存 QoS 分层保护、OOM 整组终止及原地 Pod 扩缩容。建议尽快将所有 Linux 节点迁移至 cgroup v2,并配置 systemd cgroup 驱动。

🔎

延伸解读

迁移时间线与风险

Kubernetes 已弃用 cgroup v1,v1.35 起 kubelet 默认拒绝在 cgroup v1 节点启动,v1.38 将彻底移除支持。若仍运行旧版本,需在升级前将所有 Linux 节点迁移至 cgroup v2,或临时设置 failCgroupV1: false 覆盖。但该覆盖仅作为过渡,最终仍会按弃用策略移除。对于 kubeadm 集群,v1.35 的 SystemVerification 预检会在 init、join、upgrade 时直接报错,而非仅警告。

内存 QoS 的收益与限制

cgroup v2 支持内存 QoS 分层保护:memory.high 提供节流,memory.min 和 memory.low 提供硬/软保护。启用 MemoryQoS 特性门控后,Burstable 容器会受 memory.high 节流,阈值由 request、limit 和 memoryThrottlingFactor(默认 0.9)决定。TieredReservation 策略可将 Guaranteed Pod 的 request 映射为 memory.min,Burstable Pod 映射为 memo

OOM 行为与监控变化

在 cgroup v2 节点上,kubelet 默认将 singleProcessOOMKill 设为 false,并为每个容器 cgroup 设置 memory.oom.group,使 OOM 事件终止容器内所有进程,避免多进程容器部分存活。此行为仅作用于容器 cgroup,而非整个 Pod。若需兼容 cgroup v1 的逐个进程终止行为,可设 singleProcessOOMKill: true。此外,cgroup v2 内存控制器提供 memory.events 计数器,可供监控系统或用户态 OOM 管理器

CPU 权重转换与工具适配

cgroup v1 使用 cpu.shares,cgroup v2 使用 cpu.weight。新版 OCI 运行时采用改进的非线性转换,保留默认优先级并给小 CPU 请求更细粒度。该转换在运行时实现,crun v1.23 和 runc v1.3.2 已支持。升级运行时后,依赖精确预测 cpu.weight 值的监控或策略工具可能需要更新。同时,原地 Pod 垂直扩缩容在 v1.35 稳定,v1.36 对 Pod 级资源默认启用 Beta,其精确聚合执行需要 cgroup v2。

❓

Q&A

Kubernetes 从哪个版本开始默认拒绝在 cgroup v1 节点上启动 kubelet?

从 Kubernetes v1.35 开始,failCgroupV1 默认为 true,kubelet 默认不会在 cgroup v1 节点上启动。管理员可以临时在 kubelet 配置文件中设置 failCgroupV1: false 来覆盖,但该选项将按照弃用策略移除。

cgroup v2 相比 cgroup v1 有哪些主要优势?

cgroup v2 提供单一统一层级、更一致的接口,以及更强的资源隔离基础。它支持内存 QoS 分层保护(memory.high 节流、memory.min/memory.low 保护)、OOM 整组终止(memory.oom.group)和原地 Pod 扩缩容等现代资源管理功能。

如何为 Kubernetes 节点配置 cgroup 驱动?

需要将 kubelet 的 cgroup 驱动配置为与容器运行时一致。使用 kubeadm 管理的集群推荐使用 systemd 驱动。kubelet 会自动检测运行时推荐的驱动(需运行时实现 RuntimeConfig CRI RPC,如 containerd v2.0+ 或 CRI-O v1.28+)。若不支持自动检测,可手动在 kubelet 配置文件中设置 cgroupDriver: systemd。

cgroup v2 下的内存 QoS 分层保护是如何工作的?

内存 QoS 依赖 cgroup v2 内存控制器:memory.high 提供节流,memory.min 和 memory.low 在启用分层预留时提供硬保护和软保护。启用 MemoryQoS 特性门控后,Burstable 容器会应用 memory.high 节流,阈值由 request、limit 和 memoryThrottlingFactor(默认 0.9)决定。memoryReservationPolicy: TieredReservation 将 Guaranteed Pod 的请求映射到 memory.min,Burstable Pod 的请求映射到 memory.low,BestEffort Pod 不获得保护。

在 cgroup v2 节点上,kubelet 如何处理 OOM 事件?

在 cgroup v2 节点上,kubelet 默认将 singleProcessOOMKill 设为 false,并为每个容器 cgroup 设置 memory.oom.group,使得 OOM 事件会终止该容器内的所有进程,而不是留下部分功能的多进程容器。如果需要兼容 cgroup v1 的行为(内核可能一次只杀死一个进程),可以设置 singleProcessOOMKill: true。

cgroup v1 的 cpu.shares 在 cgroup v2 中对应什么?转换时需要注意什么?

cgroup v1 使用 cpu.shares,cgroup v2 使用 cpu.weight。较新的 OCI 运行时(crun v1.23 和 runc v1.3.2)使用改进的非线性转换,保留默认优先级并给小 CPU 请求更多可用粒度。转换在 OCI 运行时中实现,升级运行时后,预测精确 cpu.weight 值的监控或策略工具可能需要更新。

🏷️

标签

➡️

继续阅读