cgroups是容器资源限制的核心机制,v2统一用memory.max设内存硬限防OOM,cpu.max提供CPU硬上限,io.max控制块设备IO速率,需统一使用v2并验证配置生效。

Linux cgroups(Control Groups)是容器资源限制的核心机制,Docker、Podman 等容器运行时都依赖它实现 CPU、内存、IO 等维度的精确配额控制。理解并正确配置 cgroups,才能避免容器“抢资源”、OOM 被杀、CPU 饱和拖垮宿主机等问题。
内存限额:防 OOM 与合理预留
cgroups v1 使用 memory.limit_in_bytes,v2 统一为 memory.max。设为 -1 表示不限制;设为具体字节数(如 512M)则硬限——超限时内核会触发 OOM Killer 杀进程。
- 建议始终设置 memory.max,哪怕只是保守值(如应用常驻内存 × 1.5)
- 配合 memory.min(v2)保障关键容器最低内存不被回收,适合数据库缓存类服务
- 通过 memory.current 和 memory.stat 实时观察实际使用与页回收情况,判断是否配额过紧
CPU 分配:份额 vs. 硬限
cgroups 提供两种 CPU 控制逻辑:
- cpu.weight(v2,默认 100):相对权重,多个容器共争 CPU 时按比例分配。例如 weight=200 的容器获得 weight=100 的两倍时间片
- cpu.max(如 "50000 100000"):硬性上限,表示每 100ms 最多用 50ms CPU 时间,等效于 0.5 核,适合对延迟敏感或需强隔离的场景
- 避免同时设 weight 和 max,后者会覆盖前者效果;生产环境推荐优先用 cpu.max 做确定性限制
IO 限速:防止磁盘打满拖垮节点
块设备 IO 受 io.max(v2)控制,格式为 "MAJ:MIN rbps wbps riops wiops",例如:
echo "8:0 10485760 5242880 100 50" > /sys/fs/cgroup/myapp/io.max
表示对主设备号 8、次设备号 0(通常是 sda)限制读 10MB/s、写 5MB/s、读 IOPS 100、写 IOPS 50。
- 必须挂载 cgroup v2 并启用 io 子系统(kernel 启动参数含 systemd.unified_cgroup_hierarchy=1)
- 容器运行时(如 Docker 20.10+)可通过 --device-read-bps /dev/sda:10mb 自动映射到 cgroups
- 注意:IO 限速作用于发出请求的 cgroup,不是文件路径,同一块盘上多个容器需各自配置
实战检查与调试技巧
容器启动后,可直接进入其 cgroup 目录验证配置是否生效:
- 查路径:cat /proc/<pid>/cgroup 找到对应 cgroup 路径(如 /sys/fs/cgroup/myapp.slice/docker-abc123...scope)
- 看当前值:cat memory.current cpu.weight io.stat
- 动态调优:echo 200 > cpu.weight 或 echo "1G" > memory.max 即刻生效,无需重启容器
- 警惕 v1/v2 混用:systemd 默认启用 v2,但部分老内核或容器引擎可能 fallback 到 v1,需统一确认 mount | grep cgroup











