cgroups-v2

cgroup v2 统一层级:限制与统计 CPU、内存、I/O 和进程数

补充说明

cgroup v2 用单一层级树替代 v1 的多控制器挂载。每个 cgroup 是一个目录,控制器通过父目录的 cgroup.subtree_control 逐级下放;资源限制写在 memory.max、cpu.max、io.max、pids.max 等文件里。

常用示例

# 判断当前是 v2、v1 还是 hybrid:cgroup2fs 表示 v2
stat -fc %T /sys/fs/cgroup

# 查看根 cgroup 可用的控制器
cat /sys/fs/cgroup/cgroup.controllers

# 创建一个 cgroup,并在根目录下放行 memory/cpu 控制器
sudo mkdir /sys/fs/cgroup/lab
echo "+memory +cpu" | sudo tee /sys/fs/cgroup/cgroup.subtree_control

# 把当前 shell 放进新 cgroup,限制为 0.5 个 CPU、512MiB 内存
echo $$ | sudo tee /sys/fs/cgroup/lab/cgroup.procs
echo "50000 100000" | sudo tee /sys/fs/cgroup/lab/cpu.max
echo 536870912 | sudo tee /sys/fs/cgroup/lab/memory.max

# 查看实际用量、限流与 OOM 事件
cat /sys/fs/cgroup/lab/memory.current
cat /sys/fs/cgroup/lab/cpu.stat
cat /sys/fs/cgroup/lab/memory.events

# 用 systemd 管理限额,避免与 systemd 自己写文件冲突
sudo systemd-run --scope -p MemoryMax=512M -p CPUQuota=50% bash

在已有 systemd unit 上改限制用 sudo systemctl set-property <unit> MemoryMax=1G CPUQuota=50%,不要直接 echo 到 unit 的 cgroup 文件,systemd 可能覆盖。

易错点与排错

读完自测

  1. 如何判断一台机器用的是 cgroup v2 而不是 v1 或 hybrid?
  2. memory.high 和 memory.max 的行为差异是什么?
  3. 为什么新建 cgroup 后写 cpu.max 会报错或文件不存在?
答案
  1. stat -fc %T /sys/fs/cgroup 返回 cgroup2fs 是 v2,返回 tmpfs 通常是 v1 或 hybrid;hybrid 下 v2 挂载点一般在 /sys/fs/cgroup/unified。
  2. memory.high 触发节流式回收,可能造成延迟但不直接杀进程;memory.max 是硬上限,回收失败后触发 cgroup OOM。
  3. 控制器需要在父 cgroup 的 cgroup.subtree_control 中启用后才会出现在子目录;若父 cgroup 同时有进程,还可能因 no-internal-processes 约束失败。

相关条目