Linux容器资源控制的核心机制是cgroups,由内核实现而非运行时自建;Docker等仅通过创建cgroup子组、写入memory.max/cpu.max等参数并加入进程PID来调用该能力。

Linux 容器实现进程资源控制的核心机制是 cgroups(Control Groups),它由内核提供,不是容器运行时自己实现的“功能”,而是被 Docker、containerd、Podman 等运行时调用的底层能力。容器本身不直接操作硬件资源,而是通过把进程组织进特定的 cgroup 控制组,并设置对应资源上限,从而达成对 CPU、内存、IO 等的硬性或软性约束。
cgroups 是容器资源控制的真正执行者
当你运行 docker run --memory=512m --cpus=1.5 nginx,Docker 并没有在用户空间做调度或拦截系统调用;它只是:
- 在
/sys/fs/cgroup/下自动创建一个子控制组(如docker/abc123...) - 向该组写入
memory.max = 536870912和cpu.max = 150000 100000(即每 100ms 最多用 150ms CPU 时间) - 把容器主进程(PID)写入
cgroup.procs,使其及其所有后续 fork 出的同组进程受控
这个过程对应用完全透明,也不需要修改程序代码。
现代系统默认使用 cgroups v2 统一层级
Ubuntu 22.04+、Fedora 31+、Debian 12+ 等主流发行版已默认启用 cgroups v2。它的优势在于:
- 所有控制器(cpu、memory、io、pids 等)统一挂载在
/sys/fs/cgroup单一目录下 - 配置文件语义清晰,如
memory.max、cpu.max、pids.max,不再有 v1 的memory.limit_in_bytes或cpu.cfs_quota_us等冗长命名 - 支持嵌套控制组和委派(delegation),适合容器编排场景
你可以用 mount | grep cgroup2 确认是否启用;若输出含 cgroup2 on /sys/fs/cgroup type cgroup2,说明环境就绪。
资源限制不是“实时截断”,而是内核级干预
-
内存限制:设
memory.max = 512M后,当进程尝试分配新内存页且超出限额时,内核会返回ENOMEM(malloc 失败)或触发 OOM Killer 杀掉该 cgroup 中最“重”的进程。注意:memory.swap.max默认不限制 swap,如需严格物理内存管控,必须额外设为0。 -
CPU 限制:
cpu.max = 50000 100000表示每 100ms 周期最多运行 50ms。超出后进程会被调度器暂停,等待下一周期。这不是“降频”,而是时间片剥夺。 -
进程数限制:
pids.max = 100可防 fork 炸弹,一旦达到上限,fork()系统调用直接失败。
容器运行时封装了复杂性,但调试时可直查 cgroup
生产中无需手动写 sysfs,但排查资源问题时非常有用:
- 查看某容器当前内存使用:
cat /sys/fs/cgroup/docker/<container-id>/memory.current - 查看 CPU 配额是否生效:
cat /sys/fs/cgroup/docker/<container-id>/cpu.stat(关注nr_throttled和throttled_time) - 检查是否因配额过低被频繁限频:若
throttled_time持续增长,说明 CPU 限额太紧
不复杂但容易忽略。


















