linux cgroups v2 迁移需先确认内核≥4.15(推荐≥5.4)和systemd≥243,再通过grub添加systemd.unified_cgroup_hierarchy=1及cgroup_no_v1=all启用统一层级,最后适配systemd服务与容器运行时配置。

Linux cgroups v2 已成为现代内核的默认控制组实现,systemd 和主流容器运行时(如 containerd、CRI-O)均已全面支持。迁移的核心不是“是否启用”,而是如何在保持服务稳定前提下,完成从 v1 混合模式到纯 v2 的平滑过渡。
确认内核与 systemd 支持状态
需确保系统满足最低要求:内核 ≥ 4.15(推荐 ≥ 5.4),systemd ≥ 243。检查方法:
- 运行 uname -r 查看内核版本
- 执行 systemctl --version 确认 systemd 版本
- 检查 /proc/cgroups 中 name=unified 行是否存在且 enabled=1
- 查看 /sys/fs/cgroup/cgroup.controllers 是否可读 —— 这是 v2 挂载点就绪的关键信号
启用 cgroups v2 的启动参数
仅靠内核支持不够,必须通过内核命令行显式启用统一层级。编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX 中添加:
systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all
注意:cgroup_no_v1=all 会禁用所有 v1 控制器挂载,避免 v1/v2 混合干扰;若需临时兼容个别旧服务,可改用 cgroup_no_v1=memory,cpu 选择性关闭,但不建议长期使用。
更新 grub 并重启:sudo update-grub && sudo reboot
systemd 服务的自动适配要点
systemd ≥ 243 默认按 v2 语义管理资源限制,无需重写 unit 文件,但需注意:
- MemoryMax=、CPUWeight=、IOWeight= 等新指令直接作用于 v2 controller,替代了旧版 MemoryLimit=(v1)
- 旧指令如 CPUQuota= 在 v2 下仍被接受,但会被转换为 CPUWeight= 或 CPUQuota=(取决于调度器模式),行为可能变化
- 检查关键服务(如 sshd、nginx、数据库)的 unit 文件,移除已弃用的 v1 专用选项(如 MemoryAccounting= 在 v2 中默认开启)
- 使用 systemctl show service-name | grep -i cgroup 验证其实际归属的 cgroup 路径是否为 /sys/fs/cgroup/...(而非 /sys/fs/cgroup/memory/...)
容器运行时的协同配置
containerd 和 CRI-O 默认检测到 v2 后自动切换,但需验证并微调:
- containerd:确认 /etc/containerd/config.toml 中未设置 no_cgroup_v2 = true;v1.4+ 版本默认启用 v2
- CRI-O:检查 /etc/crio/crio.conf 中 cgroup_manager = "systemd"(非 "cgroupfs"),确保与 systemd 一致
- Kubernetes 用户:kubelet 启动参数中移除 --cgroup-driver=cgroupfs,保持默认 systemd;v1.22+ 已完全适配 v2
- 运行 crictl info | jq '.cgroupDriver' 或 sudo runc list | head -n 5 观察容器 cgroup 路径,确认为 unified 层级
不复杂但容易忽略的是:迁移后需重新评估资源限制值——v2 的 CPUWeight 和 IOWeight 是相对权重,不再直接对应绝对配额,原 v1 的硬限制逻辑需按新语义调整。










