Cgroup V2下如何隔离Docker容器分配的CPU,禁止其他进程使用?
在Ubuntu 22.04(Cgroup v2)下隔离CPU 35、39给指定Docker容器的方法
问题背景
我在Ubuntu 22.04(使用Cgroup v2)环境中,通过以下命令部署了Docker容器:
docker run --name=testapp --cpuset-cpus=35,39 -it testapp
现在需要确保运行时除这个容器外,其他所有Linux进程都无法使用CPU 35和39。已知Cgroup v1里能用cset shielding搞定,但cset不支持Cgroup v2;手动挨个改/sys/fs/cgroup/system.slice下除目标容器外的cpuset.cpus太麻烦;isolcpus内核参数没法运行时调整,灵活性不够。
可行解决方案
1. 利用Cgroup v2顶层控制组全局限制
Cgroup v2的顶层控制组(/sys/fs/cgroup/)的cpuset.cpus是所有子控制组的默认规则,我们可以先把全局可用CPU范围设为排除35、39,再单独给目标容器开绿灯:
- 先查看当前顶层的CPU配置:
cat /sys/fs/cgroup/cpuset.cpus - 修改顶层
cpuset.cpus,把35、39排除在外(假设总CPU范围是0-39,可根据实际情况调整):
这一步后,所有未单独配置CPU的进程都只能使用上述范围的CPU,无法访问35、39。sudo echo 0-34,36-38 > /sys/fs/cgroup/cpuset.cpus - 找到目标容器的Cgroup路径(通过
docker inspect testapp可查询,格式类似/sys/fs/cgroup/system.slice/docker-<容器ID>.scope),给该容器的控制组单独设置允许使用的CPU:
注:若提示权限不足,加sudo echo 35,39 > /sys/fs/cgroup/system.slice/docker-17321ee94...scope/cpuset.cpussudo执行即可;修改前可查看cpuset.cpus.effective确认是否支持修改。
2. 持久化配置(重启不失效)
如果需要重启系统后依然保持隔离规则,可通过systemd的slice配置实现:
- 创建自定义slice配置文件
/etc/systemd/system/isolated-cpu.slice:[Unit] Description=隔离CPU 35、39的专用Slice [Slice] CPUSet=0-34,36-38 - 重新加载systemd配置:
sudo systemctl daemon-reload - 后续启动容器时,直接指定该slice并设置cpuset:
这样容器会归属到自定义slice下,单独拥有35、39的使用权,其他默认进程都在受限slice中,无法访问这两个CPU。docker run --name=testapp --cpuset-cpus=35,39 --cgroup-parent=/isolated-cpu.slice -it testapp
3. 临时调整小技巧
如果只是临时需要隔离,也可以用systemd-run把特定进程迁移到受限slice,或者直接修改对应控制组的cpuset.cpus。但要注意:修改顶层cpuset后,包括init在内的所有系统进程都会受限制,操作前需确保关键进程不会因CPU范围缩小出现异常。
内容的提问来源于stack exchange,提问作者PJConnol
相关产品推荐
相关产品推荐

