cgdelete 命令详解
更新时间:2026-09-17。本文是「一个命令一个文档」系列,聚焦
cgdelete(control group delete,删除控制组)——容器与云原生命令族、libcgroup 套件。它是 cgroup 手工工作流的收尾:cgcreate 建的组在任务结束后用它清理,避免大量空组残留。
cgdelete 从指定控制器层级移除控制组目录,等价于 rmdir /sys/fs/cgroup/<控制器>/<组>。删组有严格前置条件:组里不能还有任务(进程/线程),也不能还有子组,否则内核拒绝删除。
一、基本用法
cgdelete cpu,memory:myapp # 从 cpu、memory 两个控制器同时删除 myapp
cgdelete -g cpu:myapp # 只删 cpu 控制器下的
cgdelete -g *:myapp # 在所有控制器下删除同名组
cgdelete -r cpu,memory:mygroup # -r 递归:连同空子组一起删
-g 控制器列表:组路径与 cgcreate 对应——v1 下建了几个控制器,就要在几个控制器各删一次,所以最常用cgdelete cpu,memory:组名一次清干净。-r(recursive)会先尝试把子组清空再删,省去手工从叶子往上逐个 rmdir。
二、删不掉的两种典型原因
cgdelete: cannot remove group 'myapp': Device or resource busyEBUSY 基本对应两件事之一:
# 1) 组里还有进程:先看 tasks/cgroup.procs
cat /sys/fs/cgroup/memory/myapp/tasks # v1:列出组内线程
# 把残留进程移出(移回根组或其父组),再删
while read p; do echo $p > /sys/fs/cgroup/memory/tasks; done < /sys/fs/cgroup/memory/myapp/tasks
# 2) 还有子组:先删叶子子组
lscgroup -g memory | grep myapp # 用 lscgroup 看层级
cgdelete -r memory:myapp # 或直接 -r 递归删正确的收尾顺序:确认任务进程都已退出(lscgroup/systemd-cgls 查组内 PID)→ 若有残留先把 PID 移到上层组 → 删空子组 → cgdelete 删组。组里只要还剩一个内核线程占着就 busy,这是最常见的卡点。
三、内存组删除与计费残留
删掉 memory 控制组时,若组内进程已全部离开,组的用量会计费归零;但如果进程是被移动(cgclassify)到其他组而非退出,它们占用的页会随迁移重新归属,不会因为删组而释放。删 cgroup 不等于杀掉进程或释放内存,它只移除"账本容器"。要真正结束任务仍需 kill 进程。
四、一条完整的临时限流与回收
cgcreate -g cpu,memory:tmpjob
cgset -r cpu.cfs_quota_us=50000 -r memory.limit_in_bytes=512M tmpjob
cgexec -g cpu,memory:tmpjob ./one-off-job.sh
# ...任务跑完...
cgget -g cpuacct,memory:tmpjob | grep -E 'usage' # 可选:留档用量
cgdelete cpu,memory:tmpjob # 清理五、v2 与 systemd 等价做法
cgroup v2 下控制组就是普通目录,删除用 rmdir(内核同样要求组空);systemd 管理的 scope/unit 在服务停止时会自动回收其 cgroup:
# v2:组内必须无进程、无子组,然后删目录
rmdir /sys/fs/cgroup/myapp # 非空会报 "Device or resource busy"
# systemd-run 起的 scope:停止单元即自动删组
systemd-run --unit=tmpjob --scope ... # 任务结束 / 下面命令停止后
systemctl stop tmpjob.scope # 触发 stop,cgroup 自动移除
# Docker 容器:
docker rm -f mycontainer # containerd/shim 负责建组与删组手工
mkdir建的 v2 组用rmdir删;systemd/Docker 建的组不要手动 rmdir,交给管理器生命周期回收,否则管理器里还留着单元状态会不一致。
相关命令
建组 cgcreate、设限 cgset、读取 cgget、启动入组 cgexec、迁移进程 cgclassify、列组 lscgroup、结束进程 kill。
总结
cgdelete 控制器:组名 = 删除 cgroup v1 控制组:与 cgcreate 对应,多控制器要分别删、可用 -r 递归;报 Device or resource busy 必是组内仍有进程或子组,先迁空再删;删组不杀进程、不释放内存,v2 下等价 rmdir,systemd/Docker 的组交给管理器随单元停止自动回收。