cgcreate 命令详解
更新时间:2026-09-17。本文是「一个命令一个文档」系列,聚焦
cgcreate(control group create,创建控制组)——属于容器与云原生命令族。它是 libcgroup 工具集的建组入口,配套的还有 cgset(设参数)、cgget(读参数)、cgexec(组内启动进程)。
cgcreate 在 cgroup 层级里创建一个(或同时在多个控制器下创建同名的)控制组目录。cgroup(control group,控制组)是内核给一组进程做资源 accounting(统计)和限制的机制,容器的 CPU/内存上限最终都落到它上面(见容器与虚拟机的区别)。需要注意:cgcreate 面向的是 cgroup v1 的多控制器层级;在如今主流的 cgroup v2(unified hierarchy,统一层级)上,建组就是在 /sys/fs/cgroup 下 mkdir,或更推荐直接用 systemd。
一、基本用法
# 安装(debian/redhat 系)
apt install cgroup-tools # Debian/Ubuntu(包名 cgroup-tools)
yum install libcgroup # RHEL/CentOS(包名 libcgroup / libcgroup-tools)
# 在一个或多个控制器下创建名为 myapp 的组
cgcreate -g cpu,memory:myapp # 在 cpu、memory 两个控制器各建 myapp
cgcreate -g cpu:/web/front # 可建层级子组 web/front
cgcreate -g *:myapp # * 表示在所有已挂载控制器下都建
-g <controllers>:<path>是核心参数:冒号前是逗号分隔的控制器列表(cpu、memory、blkio、devices、pids…),冒号后是组路径。建完后到/sys/fs/cgroup/<控制器>/myapp/能看到一组控制文件——这正是 cgset 写入、cgget 读取的对象。
二、建组后做什么:一条典型链路
cgcreate -g cpu,memory:batch # 1. 建组
cgset -r cpu.shares=512 batch # 2. 设 CPU 权重(见 cgset)
cgset -r memory.limit_in_bytes=536870912 batch
cgexec -g cpu,memory:batch ./heavy-job.sh # 3. 在组内启动进程(见 cgexec)
cgget -g memory:batch # 4. 读回参数与用量(见 cgget)
cgdelete cpu,memory:batch # 5. 用完删除(见 cgdelete)单独
cgcreate只是建了一个空组,不设任何参数等于没有限制——它必须配合 cgset 才有实际效果。新手常见的困惑是「我明明建组了为什么程序照样吃满 CPU」,原因就是只建组、没写cpu.shares或cpu.cfs_quota_us。
三、控制器速查
| 控制器(v1 名) | 管什么 | 典型参数 |
|---|---|---|
cpu / cpuacct | CPU 调度与统计 | cpu.shares(权重)、cpu.cfs_quota_us(配额) |
memory | 内存与 swap | memory.limit_in_bytes、memory.memsw.limit_in_bytes |
blkio | 块设备 IO | blkio.throttle.read_bps_device(限速) |
pids | 进程/线程数量 | pids.max(防 fork 炸弹) |
devices | 设备访问白名单 | devices.allow / devices.deny |
cpu.shares是相对权重(默认 1024,设 512 表示在竞争时拿一半),不是硬上限;要硬限核数得用cpu.cfs_quota_us / cpu.cfs_period_us(如 period 100000、quota 50000 = 限 0.5 核)。这也是容器「CPU limit 到底限的是权重还是核数」的根源,见容器性能。
四、v1 与 v2、以及为什么更推荐 systemd
cgroup v1 的每个控制器一棵独立树,所以 cgcreate -g cpu,memory:myapp 会在两棵树各建一个目录;cgroup v2 把所有控制器统一到一棵 /sys/fs/cgroup 树,libcgroup 的多控制器语法不再对应,现代发行版(Ubuntu 22.04+、RHEL 9、K8s 节点)默认 v2:
# cgroup v2 手工等价操作
mkdir /sys/fs/cgroup/myapp
echo "50000 100000" > /sys/fs/cgroup/myapp/cpu.max # 限 0.5 核
echo 536870912 > /sys/fs/cgroup/myapp/memory.max
echo $PID > /sys/fs/cgroup/myapp/cgroup.procs # 把进程放进去
# 生产环境更推荐:交给 systemd 管理(自动回收、随服务生命周期)
systemd-run --unit=batch --scope -p CPUQuota=50% -p MemoryMax=512M ./heavy-job.shlibcgroup 命令在今天更多出现在老系统(CentOS 7、v1 环境)与题库/面试里;新系统首选
systemd-run、systemctl set-property,或直接写.service单元的CPUQuota=/MemoryMax=。理解 cgcreate 的价值在于看懂 v1 时代脚本和 cgroup 的目录模型——v2 只是把多棵树合并、文件改名,思想完全一致。
五、常见报错
cgcreate: can't create group ...: Cgroup is not mounted # 控制器没挂载,或系统是纯 v2
cgcreate: ... Permission denied # 需要 root
# cgconfig 服务方式:用配置文件 /etc/cgroup/cgconfig.conf 开机批量建组
service cgconfig start若
cgcreate -g cpu:myapp报 "not mounted",先用mount | grep cgroup看是 v1 多挂载还是 v2 单挂载;纯 v2 系统应改用第四节的mkdir/ systemd 方式,不要再执着于 libcgroup。
相关命令
设参数用 cgset,读参数用 cgget,组内启动进程用 cgexec,移动已运行进程用 cgclassify,列组用 lscgroup,删组用 cgdelete。概念背景见容器性能。
总结
cgcreate = cgroup v1 的建组命令(libcgroup):cgcreate -g cpu,memory:组名 在指定控制器层级创建控制组目录,但只建组不限制,必须配合 cgset 写参数、cgexec 放进程才生效;cgroup v2 下等价为 mkdir /sys/fs/cgroup/组名,生产更推荐 systemd-run -p CPUQuota -p MemoryMax。