
docker资源配额
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