cgroup v2实战指南:runc如何精细管控容器CPU、内存与PID资源
【免费下载链接】runcCLI tool for spawning and running containers according to the OCI specification项目地址: https://gitcode.com/gh_mirrors/ru/runc
runc 是依据 OCI 规范启动和运行容器的命令行工具,而 cgroup v2 是 Linux 内核统一层级中精细管控容器 CPU、内存与 PID 资源的核心机制。runc 自 v1.0.0-rc93 起完全支持 cgroup v2(unified mode),本指南带你快速掌握:如何检查系统是否已启用 cgroup v2,如何用runc配置 CPU 权重、内存上限与 PID 数量限制,以及如何动态调整资源配额。
一、先确认:你的系统在用 cgroup v2 吗?
判断方法只有一行:只要文件/sys/fs/cgroup/cgroup.controllers存在,就是 cgroup v2。
主流发行版如 Fedora 31+、Debian 11+、Ubuntu 21.10+、RHEL 9+ 均已默认启用。其他基于 systemd 的系统可在内核启动参数中加入systemd.unified_cgroup_hierarchy=1开启。
⚠️ 内核要求:推荐5.2 及以上(缺少 freezer 控制器的旧内核不推荐),最低 4.15。详见 docs/cgroup-v2.md。
在 cgroup v2 主机上,强烈建议使用 systemd cgroup 驱动:
runc --systemd-cgroup run mycontainer二、三大控制器逐个击破
runc 的资源限制定义在 OCI 配置的linux.resources中,对应结构体见 config.go,包含memory、cpu、pids等字段,最终由 specconv/spec_linux.go 转换为 cgroup 写入操作。
1️⃣ 管控 CPU:cpu.weight 与 cpu.max
cgroup v2 用cpu.weight(10~1000)替代了 v1 的cpu.shares,两者语义不同,runc 在 update.go 中通过ConvertCPUSharesToCgroupV2Value自动完成换算。
- 相对权重:
cpu.weight决定多个容器争抢 CPU 时的分配比例; - 硬上限:
cpu.max(如200000 100000表示最多使用 2 个 CPU)限制绝对用量,还可配cpu.max.burst吸收突发。
实际写入逻辑在 fs2/cpu.go 中,runc 就是把值写进容器 cgroup 目录的cpu.max文件。
2️⃣ 管控内存:memory.high 与 memory.max
cgroup v2 把内存限制拆成两级:
| 文件 | 作用 |
|---|---|
memory.high | 软限制:超过后内核施加内存压力回收,进程会被拖慢 |
memory.max | 硬限制:超过直接触发 OOM 杀死进程 |
推荐组合使用——先设memory.high做"温和减速",再设memory.max兜底防 OOM 扩散到宿主机。写入实现在 fs2/memory.go。
3️⃣ 限制 PID:pids.max 防止进程炸弹
一个失控的容器疯狂 fork 进程会耗尽宿主机的 PID 资源。设置pids.max后,容器内 fork 超限会直接收到EAGAIN错误,宿主机安然无恙。实现见 fs2/pids.go。
三、进阶玩法:unified 模式直接写 cgroup v2 参数
不想被标准字段束缚?OCI 规范提供unified字段,允许直接指定任意 cgroup v2 控制器的键值对,runc 会原样写入。例如在config.json中:
"unified": { "memory.high": "20971520", "memory.max": "41943040", "cpuset.cpus": "0-3" }官方集成测试就覆盖了这一场景,可参考 tests/integration/cgroups.bats 中test_cgroups_unified用例的完整写法。
四、不停机调整:runc update 动态改配额
容器运行中也能修改资源限额,runc update支持的关键参数:
# 调整 CPU 权重(cgroup v2 的 10~1000) runc update --cpu-weight 500 mycontainer # 调整内存 / PID 限制 runc update --memory 512m --pids 1024 mycontainer各参数说明见 man/runc-update.8.md。注意:若使用 systemd 驱动设置 CPU 配额,需同时提供 quota 和 period 两个值,runc 会自动处理,见 update.go 中的相关注释。
五、Rootless 用户注意:控制器委托
无 root 权限运行时,cgroup v2 主机上 runc 可通过 systemd 申请委托(delegation)。默认只委托memory和pids两个控制器,若要使用 CPU 限制,需修改 systemd 配置:
# /etc/systemd/system/user@.service.d/delegate.conf [Service] Delegate=cpu cpuset io memory pids委托相关的边界情况(无权限时 runc 会给出清晰的错误提示)在 tests/integration/cgroup_delegation.bats 中有完整测试,可直接对照排查。
六、常见坑速查清单 📋
- 报错 "failed to write ... cpu.weight: invalid argument"—— v1 的 shares 值直接写给了 v2,需用 v2 的 weight 值(10~1000);
- rootless 下 "unable to apply cgroup configuration: permission denied"—— 控制器未委托,按第五节配置;
- 想批量准备测试环境的 cgroup v2 目录—— 可用仓库提供的 script/prepare-cgroup-v2.sh;
- systemd 版本过旧(<244)—— 不支持 cpuset 控制器委托,建议升级。
七、关键资料索引
| 资料 | 路径 |
|---|---|
| cgroup v2 官方支持文档 | docs/cgroup-v2.md |
| cgroup 权限/委托集成测试 | tests/integration/cgroup_delegation.bats |
| systemd 驱动说明 | docs/systemd.md |
| runc update 手册 | man/runc-update.8.md |
掌握了本文的"检查 → 配置 → 动态调整 → 排坑"四步法,你就能用 runc 把每台宿主机的 CPU、内存与 PID 资源都分配得明明白白 🚀
【免费下载链接】runcCLI tool for spawning and running containers according to the OCI specification项目地址: https://gitcode.com/gh_mirrors/ru/runc
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考