Linux系统自内核5.0+默认启用cgroups v2,需通过修改GRUB参数systemd.unified_cgroup_hierarchy=1并重建引导配置实现切换;v2采用统一层级、按需启用控制器、语义化资源接口,兼容性需注意Docker、Go程序及systemd配置适配。

Linux系统默认启用的cgroups版本取决于内核配置和发行版策略,但自内核4.5起已支持cgroups v2,5.0+版本默认启用率显著提升。是否启用v2不只看内核版本,更关键的是启动参数与init系统(如systemd)是否启用统一层级。直接修改挂载点或强行卸载v1无法生效,必须从引导阶段切入。
cgroups v1 切换到 v2 的实操步骤
切换本质是让systemd使用统一cgroup层级启动,需修改内核命令行参数并重建引导配置:
- 编辑/etc/default/grub,在GRUB_CMDLINE_LINUX中添加:
systemd.unified_cgroup_hierarchy=1 - 备份原grub.cfg:
cp /boot/grub2/grub.cfg /boot/grub2/grub.cfg.bak - 重新生成引导配置:
grub2-mkconfig -o /boot/grub2/grub.cfg - 重启系统后验证:
mount | grep cgroup2 —— 应仅输出一行以cgroup2 on /sys/fs/cgroup开头的内容
cgroups v2 的核心新特性
v2不是v1的简单升级,而是架构重构,带来三方面实质性变化:
- 统一单一层级树:所有控制器(cpu、memory、io等)共用同一挂载点/sys/fs/cgroup,不再像v1那样分散在多个子目录(如/sys/fs/cgroup/cpu、/sys/fs/cgroup/memory)
- 控制器按需启用:通过cgroup.subtree_control文件控制子树是否继承某控制器,例如写入+cpu +memory即开启CPU与内存限制能力
- 资源模型更贴近语义:如CPU配额统一用cpu.max(格式为MAX PERIOD),内存用memory.max,避免v1中cpu.cfs_quota_us与memory.limit_in_bytes等命名不一致问题
常见兼容性注意事项
切换后部分旧工具或容器运行时可能行为异常,需提前确认:
- Docker默认仍依赖v1(尤其blkio、devices等控制器),若启用v2需配合--cgroup-manager=cgroupfs或升级至24.0+并启用systemd cgroup驱动
- Go程序若未使用automaxprocs等适配库,可能无法感知v2的CPU配额,导致GOMAXPROCS设为物理核数而非容器可用核数
- /proc/cgroups在v2下不显示有效信息,应改用cat /sys/fs/cgroup/cgroup.controllers查看已启用控制器
- systemd服务默认运行在v2下,但其scope或slice的资源限制需显式配置,不能依赖旧版MemoryLimit=等v1风格单位(v2中单位统一为字节,无自动换算)
v2环境下的典型应用示例
以限制一个后台服务的CPU与内存为例(无需安装额外工具):
- 创建控制组:
mkdir -p /sys/fs/cgroup/myapp - 启用CPU与内存控制器:
echo "+cpu +memory" > /sys/fs/cgroup/myapp/cgroup.subtree_control - 设置CPU上限为1核(100ms/100ms):
echo "100000 100000" > /sys/fs/cgroup/myapp/cpu.max - 设置内存上限为512MB:
echo "536870912" > /sys/fs/cgroup/myapp/memory.max - 将进程加入该组(假设PID为1234):
echo 1234 > /sys/fs/cgroup/myapp/cgroup.procs










