.webp)
docker资源配额
本文最后更新于 2025-07-13,文章内容可能已经过时。
CPU 配额
Docker 使用 cgroup 来管理容器使用的 CPU、内存、磁盘资源限额。
权重方式
--cpu-shares
或者 -c
参数可以为容器设置指定的权重值。容器默认的权重值为 1024。当多个容器竞争 CPU 资源时,权重越高的容器将获得更多的 CPU 调度时间。
例如容器 A 的权重值为 1024,容器 B 的权重值为 512,则容器 A 与容器 B 在 CPU 资源竞争时,容器 A 所获得的 CPU 调度时间是容器 B 的两倍。
cgroup 只有多个容器同一时间在竞争同一个 CPU 资源时,CPU 配额才会生效。
启动一个容器,然后将其 cpu 配额设置为 512。
docker run -it --cpu-shares 512 busybox /bin/sh
在容器内部使用 cat /sys/fs/cgroup/cpu/cpu.shares
查看 CPU 配额
核心控制
使用 --cpuset 使容器绑定到特定的 CPU 内核和内存节点上运行
--cpuset-cpus
--cpuset-mems
当两个容器使用 --cpuset 分别绑到了不同 CPU 上,例如容器 A 绑到 cpu1、容器 B 绑到 cpu2 上,由于容器 A 和容器 B 不会争夺同一个 CPU 资源,所以设置的 CPU 配额并不会生效,只有两个容器绑到同一个 CPU 时,CPU 配额才会生效。
压测
创建两个容器,分别为容器 container
A 和容器 container
B,两个容器都绑定 cpu0 和 cpu1,其中容器 A 的 CPU 权重为 1024、容器 B 的 CPU 权重为 512。
前提是服务器或者本地虚拟机 cpu 核心数要多于一个(建议 2 核以上,因为后面压测两个 cpu 时,如果你只有 2 核,那就会卡死😂),可以使用 lscpu 查看当前服务器的 cpu 核数
CPU(s): 4
On-line CPU(s) list: 0-3
也可以使用 top 命令,然后按 1️⃣键显示 CPU 信息
docker run -itd --name containerA --cpu-shares 1024 --cpuset-cpus 0,1 alpine /bin/sh
docker run -itd --name containerB --cpu-shares 512 --cpuset-cpus 0,1 alpine /bin/sh
先进入 containerB 容器安装 stress-ng(alpine 中没有 stress,所以用 stress-ng) 压测工具,容器 A 也重复这步。
docker exec -it containerB /bin/sh
apk update
apk add stress-ng
分别在两个容器中运行 stress-ng 进行压测。
stress-ng --cpu 2 --timeout 30000s
我们可以看到 CPU0 和 CPU1 跑满了,但是其他 CPU 没有受到影响。
在进程中出现了 4 条关于 stress-ng 的进程,我们可以使用 cat /proc/PID(替换为具体的PID)/cgroup
命令查看进程所属容器,例如
cid=$(cat /proc/PID(替换为具体的PID)/cgroup | grep 'docker' | awk -F/ '{print $3}')
docker ps --no-trunc --format '{{.ID}} {{.Names}}' | grep "$cid"
可以使用一个脚本实现输出,创建一个 pid2name.sh 文件,内容如下
#!/bin/bash
# 获取 stress-ng-cpu 进程列表
ps -eo pid,comm,%cpu --no-headers | awk '$2=="stress-ng-cpu"{print $1, $3}' | while read pid cpu; do
# 提取容器 ID(Docker cgroup)
cid=$(awk -F/ '/docker/{print $3}' /proc/$pid/cgroup 2>/dev/null)
# 如果找到了容器 ID
if [ -n "$cid" ]; then
# 获取容器名
cname=$(docker ps -a --no-trunc --format '{{.ID}} {{.Names}}' | grep "$cid" | awk '{print $2}')
else
cname="host" # 非容器进程
fi
echo "PID: $pid | CPU: $cpu% | Container: $cname"
done
输出结果如下
PID: 438781 | CPU: 65.2% | Container: containerA
PID: 438782 | CPU: 65.5% | Container: containerA
PID: 438138 | CPU: 32.4% | Container: containerB
PID: 438139 | CPU: 32.4% | Container: containerB
可以看到 containerA 容器的 CPU 使用率始终为 containerB 的两倍
内存控制
docker 可以使用 --memory 或者 -m 参数实现容器内存使用量的控制
例如:
docker run -itd --name containerA -m 512m alpine /bin/sh
containerA 容器只能使用 512M 的内存。
IO 控制
--device-write-bps {设备名:值}
限制容器的写速度。
--device-read-bps {设备名:值}
限制容器的读速度。单位可以是 kb、mb、gb