1、docker容器资源配额控制

启动 docker 容器时,指定 cpu,内存,硬盘性能等的硬件资源使用份额。

Docker通过cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。

cgroup 概述:

cgroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离迚程组所使用的物理资源(如 cpu、memory、磁盘 IO 等等) 的机制,被 LXC、docker 等很多项目用于实现迚程资源控制。cgroup 将任意迚程迚行分组化管理的 Linux 内核功能。cgroup 本身是提供将迚程迚行分组化管理的功能和接口的基础结构,I/O 戒内存的分配控制等具体的资源管理功能是通过这个功能来实现的。

为什么要迚行硬件配额? 当多个容器运行时,防止某容器把所有的硬件都占用了。(比如一台被黑的容器)


2、docker容器资源配额控制之CPU

1 给容器实例分配512权重的CPU使用份额

[root@syxk ~]#docker run --help | grep cpu-shares

cpu配额参数

-c,--cpu-shares int CPU shares 在创建容器时指定容器所使用的CPU份额值。

cpu shares的值不能保证可以获得1个vcpu或者多少GHz的CPU资源,仅仅只是一个弹性的加权值。默认情况下:每个docker容器的cpu份额都是1024.单独一个容器的份额是没有意义的,只有在同时运行多个容器时,容器的CPU加权的效果才能体现出来。

例如:两个容器A,B的CPU份额分别为1000和500,结果会怎么样?

情况1:A和B正常运行,在CPU进行时间片分配的时候,容器A比容器B多一倍的机会获得CPU的时间片。

情况2:分配的结果取决于当前主机和其他容器运行状况,实际上也无法保证容器A一定能获得CPU时间片。比如容器A的进程一直是空闲的,那么容器B是可以获取比容器A更多的CPU时间片的。极端情况下,比如主机只运行一个容器,即使它的CPU份额只有50,它也可以独占整个主机的CPU资源。

问:两个容器A、B的CPU份额分别为1000和500,1000+500>1024是超出了吗?

答:没有。A使用1024的2/3,B使用1024的1/3

cgroups 只在容器分配的资源紧缺时,也就是说在需要对容器使用的资源迚行限制时,才会生效。因此,无法单纯根据某个容器的 cpu 份额来确定有多少 cpu 资源分配给它,资源分配结果取决于同时运行的其他容器的 cpu 分配和容器中进程运行情况。

[root@syxk ~]#docker run -it --cpu-shares 512 centos:latest /bin/bash

[root@df176dd75bd3]#cat /sys/fs/cgroup/cpu/cpu.shares 查看结果

512

注:应启动多个容器,测试下是不是只能使用512份额的CPU资源。单独一个容器,看不出来。

2 docker还提供了--cpu-period(周期)、--cpu-quota两个参数控制容器可以分配的CPU时钟周期。

--cpu-period 指定周期 默认值是0.1秒

--cpu-quota 指定在这个周期中使用多少时间片 默认值是 -1 表示不做控制

--cpu-period --cpu-quota的单位是微妙

跟--cpu-shares不同,--cpu-period --cpu-quota是指定一个绝对值,而且没有弹性在里面,容器对CPU资源的使用绝对不会超过配置的值。

实例:如果容器进程需要每1秒使用单个CPU的0.2秒时间,可以将cpu-period配置为1000000(即1秒),cpu-quota设置为200000(0.2秒)。

[root@syxk ~]#docker run -it --cpu-period 1000000 --cpu-quota 200000 centos /bin/bash

[root@0363ce23f264]#cat /sys/fs/cgroup/cpu/cpu.cfs_period_us

1000000

[root@0363ce23f264]#cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us

200000

3 CPU core 核心控制

参数:--cpuset 可以绑定CPU

对多核CPU服务器,docker还可以控制容器运行限定使用哪些CPU内核和内存节点,即使用-cpuset-cpus和-cpuset-mems参数。对具有 NUMA 拓扑(具有多 CPU、多内存节点)的服务器尤其有用,可以对需要高性能计算的容器迚行性能最优的配置。如果服务器只有一个内存节点,则–cpuset-mems 的配置基本上不会有明显效果。


3、docker容器资源配额控制之内存

docker 提供参数 -m,--memory="" 限制容器的内存使用量

实例:允许容器使用的内存上限为128M

[root@syxk ~]#docker run -it -m 128m centos:latest

[root@40bf29765691 /]#cat /sys/fs/cgroup/memory/memory.limit_in_bytes

134217725


4、docker容器资源配额控制之IO

[root@syxk ~]#docker run --help | grep write-b

--device-write-bps value

限制此设备上的写速度,单位可以是kb、mb或者gb

--device-read-bps value

限制此设备上的读速度,单位可以是kb、mb或者gb

为什么阿里云上普通云盘的IO为:1000 IOPS,为什么这么小?

原因:存储给2000台云主机使用,需要控制一下。防止某台云主机吃光你的磁盘I/O资源

场景:防止某个docker容器吃光你的磁盘I/O资源。

实例:容器对磁盘的最高写入速度设定为1MB/s

--device 参数:将主机设备添加到容器

说明:1、该设备在主机上是要真实存在的 2、默认情况下,在容器里没有该设备

[root@syxk ~]#docker run -it -v /var/www/html/:/var/www/html --device /dev/sda:/dev/sda --device-write-bps /dev/sda:1mb centos /bin/bash

[root@81254456fe12:~]#time dd if=/dev/sda of=/var/www/html/test.out bs=1M count=50 oflag=direct,nonblock

direct:读写数据采用直接IO方式。

nonblock:读写数据采用非阻塞IO方式。

验证:

[root@syxk ~]#ll -h /var/www/html

发现1秒写1M。限制成功。

同理:测试容器对磁盘的最大读取速度设定为1MB/s

[root@syxk ~]#docker run -it --device /dev/sda:/dev/sda --device-read-bps /dev/sda:1mb centos /bin/bash

[root@8124556fe12:~]#time dd if=/dev/sda of=test.out bs=1M count=50 oflag=direct,nonblock




作者:​​岁月星空​

 

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。