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