如何在Docker容器内获取可用CPU资源配额
我明白你的痛点——用--cpus限制了容器的CPU资源,但/proc/cpuinfo还在显示宿主机的所有CPU,想用stress测试又觉得不够直接准确对吧?其实Docker的CPU限制是通过Linux cgroup实现的,从容器内部直接读取cgroup的配置文件是最靠谱的方法,给你几个可行方案:
1. 直接读取cgroup CPU限制文件(最准确)
Docker用cgroup来管控CPU资源配额,你可以在容器内的/sys/fs/cgroup/cpu/目录找到两个关键文件:
cpu.cfs_period_us:CPU调度的周期时长(默认是100000微秒,也就是0.1秒)cpu.cfs_quota_us:一个周期内允许容器使用的CPU时间(如果值为-1表示无CPU限制)
可用CPU核心数的计算公式是:cpu.cfs_quota_us / cpu.cfs_period_us
执行以下命令就能直接得到结果:
# 整数计算输出可用CPU核心数 echo $(( $(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us) / $(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us) ))
比如你启动容器时指定了--cpus=1,这个命令会输出1;如果是--cpus=0.5,整数除法会输出0,这时候可以用浮点计算得到更精确的结果:
# 浮点计算输出精确的CPU配额 awk '{print $1/$2}' /sys/fs/cgroup/cpu/cpu.cfs_quota_us /sys/fs/cgroup/cpu/cpu.cfs_period_us
2. 为什么/proc/cpuinfo无法满足需求
你提到的/proc/cpuinfo显示宿主机CPU是正常现象:--cpus参数是CPU使用率限制(比如允许容器最多用满1核的算力),而不是把容器绑定到特定的CPU核心。只有当你使用--cpuset-cpus指定具体核心(比如--cpuset-cpus=0)时,/proc/cpuinfo才会只显示被分配的核心。
3. 改进你的stress测试方法
如果还是想用stress验证CPU限制,建议直接指定与配额匹配的CPU数,比如你设置了--cpus=1,就运行:
\time stress --cpu 1 --timeout 10
查看输出的%CPU值,如果接近100%,说明容器能用到1核的算力;如果是--cpus=0.5,%CPU会接近50%。不过这个方法是间接验证,当容器有其他进程运行时结果会有偏差,不如直接读取cgroup文件准确。
内容的提问来源于stack exchange,提问作者Trevor Norris

