Docker中通过指定--cgroup-parent绑定容器到租户级cgroup(如systemd slice),实现多容器共享CPU/内存硬限额,防止抱团突破配额。

在 Docker 中配置容器的 cgroup 父级资源限制,本质是绕过容器默认自建 cgroup 的方式,让多个容器共享一个上层 cgroup 控制组,从而实现租户粒度的资源统一分配与硬性约束。这比单个容器单独设 --cpus/--memory 更适合多租户场景——它能防止租户内多个容器“抱团突破”总配额。
以下分三步说明关键操作和注意事项:
明确父级 cgroup 路径并创建控制组
Docker 默认把每个容器放在 /sys/fs/cgroup/<subsystem>/docker/<container-id>/ 下。要实现租户级控制,需提前创建一个租户专属的父级 cgroup(如 tenant-a),再让该租户所有容器归属其中。
# 创建 CPU + 内存联合控制组(以 systemd 为 cgroup v2 环境为例) sudo mkdir -p /sys/fs/cgroup/tenant-a echo 1 | sudo tee /sys/fs/cgroup/tenant-a/cgroup.procs # 初始化组 # 设置租户总配额:最多用 2 个 CPU 核心、4GB 内存 echo 200000 | sudo tee /sys/fs/cgroup/tenant-a/cpu.max # period=100000, quota=200000 → 2 核 echo 4294967296 | sudo tee /sys/fs/cgroup/tenant-a/memory.max
注意:路径需与宿主机 cgroup 版本匹配(v1 使用
/sys/fs/cgroup/cpu,memory/tenant-a/;v2 统一挂载在/sys/fs/cgroup/下)。
启动容器时指定父级 cgroup
Docker 不直接支持 --cgroup-parent 指定非 docker 自管路径,但可通过 --cgroup-parent + 手动注入或 --cgroup-parent 配合 systemd slice 实现:
-
推荐方式(systemd 环境):
利用 systemd 的 slice 机制天然支持层级 cgroup,更稳定且可持久化:# 创建租户 slice(/etc/systemd/system/tenant-a.slice) [Unit] Description=Tenant A Resource Slice Before=slices.target [Slice] CPUQuota=200% MemoryMax=4G # 启用并重载 sudo systemctl daemon-reload sudo systemctl start tenant-a.slice
启动容器时绑定该 slice:
docker run -d \ --name clawdbot-a-01 \ --cgroup-parent=tenant-a.slice \ --memory=2g --cpus=1 \ clawdbot:latest
✅ 此时该容器及其子进程自动归属
tenant-a.slice,受其CPUQuota和MemoryMax约束,即使启动多个容器也共用同一上限。
验证父子级资源生效
检查容器是否真正运行在目标 cgroup 下:
# 查看容器实际所在 cgroup 路径 docker inspect clawdbot-a-01 | grep CgroupParent # 进入对应 cgroup 目录确认数值 cat /sys/fs/cgroup/tenant-a/cpu.max cat /sys/fs/cgroup/tenant-a/memory.max # 查看当前租户下所有进程的内存使用总和 sudo cat /sys/fs/cgroup/tenant-a/memory.current
若 memory.current 接近 memory.max 且新增容器无法突破该值,说明租户级隔离已生效。
- 不建议手动用
cgexec注入容器进程(易被 Docker daemon 干扰或重启失效) -
--cgroup-parent必须指向已存在的、有权限写入的 cgroup 路径或 systemd slice - 多租户场景下,建议配合用户命名空间(
--userns-remap)+ 网络命名空间隔离,补全安全维度
这样配置后,每个租户就像拥有一个“资源保险箱”,内部容器可灵活调度,但总量不越界。


















