07-Docker资源配额¶
Docker 通过 cgroup 来控制容器使用的资源限制,可以对 docker 限制的资源包括 CPU、内存、磁盘
控制容器CPU配额¶
CPU份额控制
查看配置份额的帮助命令:
[root@linux-bkce-node21 ~]# docker run --help | grep cpu-shares
-c, --cpu-shares int CPU shares (relative weight)
CPU shares (relative weight) 在创建容器时指定容器所使用的 CPU 份额值。cpu-shares 的值不能 保证可以获得 1 个 vcpu 或者多少 GHz 的 CPU 资源,仅仅只是一个弹性的加权值。 默认每个 docker 容器的 cpu 份额值都是 1024。在同一个 CPU 核心上,同时运行多个容器时,容器的 cpu 加权的效果才能体现出来。 例: 两个容器 A、B 的 cpu 份额分别为 1000 和 500,结果会怎么样? 情况 1:A 和 B 正常运行,占用同一个 CPU,在 cpu 进行时间片分配的时候,容器 A 比容器 B 多一倍 的机会获得 CPU 的时间片。 情况 2:分配的结果取决于当时其他容器的运行状态。比如容器 A 的进程一直是空闲的,那么容器 B 是可以获取比容器 A 更多的 CPU 时间片的; 比如主机上只运行了一个容器,即使它的 cpu 份额只有 50,它也可以独占整个主机的 cpu 资源。 cgroups 只在多个容器同时争抢同一个 cpu 资源时,cpu 配额才会生效。因此,无法单纯根据某个容 器的 cpu 份额来确定有多少 cpu 资源分配给它,资源分配结果取决于同时运行的其他容器的 cpu 分 配和容器中进程运行情况。
CPU核心控制
参数:--cpuset 可以绑定 CPU
[root@linux-bkce-node21 ~]# docker run --help | grep cpuset-cpus
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
对多核 CPU 的服务器,docker 还可以控制容器运行限定使用哪些 cpu 内核和内存节点,即使用-- cpuset-cpus 和--cpuset-mems 参数。对具有 NUMA 拓扑(具有多 CPU、多内存节点)的服务器尤其有 用,可以对需要高性能计算的容器进行性能最优的配置。如果服务器只有一个内存节点,则-- cpuset-mems 的配置基本上不会有明显效果。
CPU份额与核心控制
在上面这些参数中,cpu-shares 控制只发生在容器竞争同一个 cpu 的时间片时有效。 如果通过 cpuset-cpus 指定容器 A 使用 cpu 0,容器 B 只是用 cpu1,在主机上只有这两个容器使用 对应内核的情况,它们各自占用全部的内核资源,cpu-shares 没有明显效果。
容器 A 和容器 B 配置上 cpuset-cpus 值并都绑定到同一个 cpu 上,然后同时抢占 cpu 资源,就可以 看出效果了。 例 1:测试 cpu-shares 和 cpuset-cpus 混合使用运行效果,就需要一个压缩力测试工具 stress 来让 容器实例把 cpu 跑满。 如何把 cpu 跑满? 如何把 4 核心的 cpu 中第一和第三核心跑满?可以运行 stress,然后使用 taskset 绑定一下 cpu。 先扩展:stress 命令 概述:linux 系统压力测试软件 Stress 。
yum install stress -y
运行第一个容器
docker run --name centos01 -d -it --cpuset-cpus 0,1 --cpu-shares 512 centos:7.9.2009 /bin/bash
运行第二个容器
docker run --name centos02 -d -it --cpuset-cpus 0,1 --cpu-shares 1024 centos:7.9.2009 /bin/bash
给第1个容器打CPU压力
docker exec -it centos01 /bin/bash
rm -f /etc/yum.repos.d/*.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum repolist
yum install stress -y
#运行 2 个进程,把两个 cpu 占满
stress -c 2 -v -t 10m
给第2个容器打CPU压力
docker exec -it centos02 /bin/bash
rm -f /etc/yum.repos.d/*.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum repolist
yum install stress -y
#运行 2 个进程,把两个 cpu 占满
stress -c 2 -v -t 10m
清理环境
docker rm -f centos01
docker rm -f centos02
控制容器内存配额¶
Docker 提供参数-m, --memory=""限制容器的内存使用量。 例 1:允许容器使用的内存上限为 128M:
docker run --name centos01 -d -it -m 128m centos:7.9.2009 /bin/bash
docker run --name centos02 -d -it centos:7.9.2009 /bin/bash
docker exec -it centos01 /bin/bash
容器内查看:
[root@40bf29765691 /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
134217728
docker stats
例 2:创建一个 docker,只使用 2 个 cpu 核心,只能使用 128M 内存
[root@linux-bkce-node21 ~]# docker run -it --cpuset-cpus 0,1 -m 128m centos
可以通过命令查看内存的使用率
docker stats
清理环境
docker rm -f centos01
docker rm -f centos02
控制容器磁盘IO配额¶
docker 容器控制 IO
[root@linux-bkce-node21 ~]# docker run --help | grep write-b
--device-write-bps throttled-device Limit write rate (bytes per second) to a device (default [])
限制此设备上的写速度(bytes per second),单位可以是 kb、mb 或者 gb。 --device-read-bps value #限制此设备上的读速度(bytes per second),单位可以是 kb、mb 或 者 gb。 情景:防止某个 Docker 容器吃光你的磁盘 I / O 资源 例 1:限制容器实例对硬盘的最高写入速度设定为 2MB/s。
--device 参数:将主机设备添加到容器
mkdir -p /var/www/html/
docker run -it -v /var/www/html/:/var/www/html --device /dev/sda:/dev/sda --device-write-bps /dev/sda:2mb centos /bin/bash
time dd if=/dev/sda of=/var/www/html/test.out bs=2M count=50 oflag=direct,nonblock
注:dd 参数: direct:读写数据采用直接 IO 方式,不走缓存。直接从内存写硬盘上。 nonblock:读写数据采用非阻塞 IO 方式,优先写 dd 命令的数据
50+0 records in
50+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 50.0184 s, 2.1 MB/s
real 0m50.032s
user 0m0.001s
sys 0m0.105s
注: 发现 1 秒写 2M。 限制成功。
容器自动释放资源¶
作用:当容器命令运行结束后,自动删除容器,自动释放资源
[root@linux-bkce-node21 ~]# docker run --help | grep rm
--rm 参数: Automatically remove the container when it exits
例子:
docker run --name centos01 --rm -it centos:7.9.2009 /bin/bash -c "cat /etc/redhat-release ; hostname"
等 5s 后,再查看:
docker ps | grep centos01 #自动删除了