Docker--Cgroup资源配置
- CPU使用率控制
- 优先级/权重测试:
- 编写Dockerfile
- 创建容器
- 容器产生10个子函数进程,做cpu权重限制
- 另开一个终端,在创建一个容器进行对比
- 查看当前宿主机所有容器CPU和内存等信息
- 说明:
- CPU周期限制
- 指定容器目录中
- top完按数值1可查看所有的cpu
- CPU Core核心控制
- 指定容器只能用0、1两个内核
- 查看容器中进程与CPU内核绑定关系
- CPU配额控制参数的混合使用
- 创建两个容器,分别指定不同的内核,和cpu权限,对比查看
- 内存限额
- 配置容器最多使用200M内存和300M的swap
- Block IO的限制
- bps和iops限制
- 限制容器写/dev/sda的速率是5MB/s
- 总结
前言:cgroup是Control Groups的缩写,是Linux内核提供的一直可以限制、记录、隔离进程组所使用的物理资源,dokcer通过cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面
CPU使用率控制
- CPU周期:ls为一个周期的定律,参数值一般为100000(秒)
- 用stress压力测试工具测试CPU和内存使用情况
优先级/权重测试:
Cgroups只在容器分配的资源紧缺时,即在需要对容器使用的资源进行限制时,才会生效。因此,无法单纯根据某个容器的CPU份额来确定有多少CPU资源分配给它,
资源分配结果取决于同时运行的其他容器的CPU分配和容器中进程运行情况。
可以通过 cpu share 可以设置容器使用CPU的优先级,比如启动了两个容器及运行查看CPU使用百分比。
编写Dockerfile
[root@localhost ~]# mkdir /opt/stress
[root@localhost ~]# cd /opt/stress/
[root@localhost stress]# vim Dockerfile
FROM centos:7
RUN yum install -y wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum install -y stress
创建容器
[root@localhost stress]# docker build -t centos:stress .
容器产生10个子函数进程,做cpu权重限制
[root@localhost stress]# docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10
80fb5ebd06afa56dc337bfb2e18da455853d97c0b794644e9424de23b0076425
另开一个终端,在创建一个容器进行对比
[root@localhost ~]# docker run -itd --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10
725ed46010c9be97ff476bc0c7a96ed40657ec9a2b0bf4ef40ee8fdd9b1eb16e
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
725ed46010c9 centos:stress "stress -c 10" 30 seconds ago Up 29 seconds cpu1024
80fb5ebd06af centos:stress "stress -c 10" 2 minutes ago Up 2 minutes cpu512
查看当前宿主机所有容器CPU和内存等信息
[root@localhost ~]# docker stats
说明:
默认情况下,每个Docker容器的CPU份额都是1024。单独一个容器的份额是没有意义的。只有在同时运行多个容器时,容器的CPU加权的效果才能体现出来。
例如,两个容器A、B的 CPU 份额分别为1000和
500,在CPU进行时间片分配的时候,容器A比容器B多一倍的机会获得CPU的时间片。但分配的结果取决于当时主机和其他容器的运行状态,实际上也无法保证容器
A一定能获得CPU时间片。比如容器A的进程一直是空闲的,那么容器B是可以获取比容器A更多的CPU时间片的。极端情况下,例如主机上只运行了一个容器,即使它的CPU份额只有50,它也可以独占整个主机的CPU资源。
CPU周期限制
CPU—>VCPU–>以进程的方式体现在vorkstation环境(docker环境中)—》docker表现形式是容器–>Vcpu以进程的方式控制容器–》容器中的应用需要的是服务进程支持–》宿主机内核中cpu可以被cgroup管理(通过分配资源手段)–》linux内核中的cgroup可以控制管理docker容器中的应用
Docker提供了–cpu-period、–cpu-quota两个参数控制容器分配到的CPU时钟周期,单位为微秒
- –cpu-period是用来指定容器对CPU的使用要在多长时间内做一次重新分配
- –cpu-quota是用来指定在这个周期内,最多可以用多少时间来跑这个容器
–cpu-quota是用来指定在这个周期内,最多可以有多少时间用来跑这个容器。与–cpu-shares不同的是,这种配置是指定一个绝对值,容器对CPU资源的使用绝对不会超过配置的值。
cpu-period和 cpu-quota 的单位为微秒(us)。cpu-period 的最小值为 1000微秒,最大值为1秒(10^6μs),默认值为0.1秒(100000 μs)
cpu-quota 的值默认为-1,表示不做控制。cpu-period 和 cpu-quota参数一般联合使用。
例如:容器进程需要每1秒使用单个 CPU的0.2秒时间,可以将cpu-period 设置为1000000(即 1秒), cpu-quota 设置为200000 (0.2秒)
当然,在多核情况下,如果允许容器进程完全占用两个 CPU,则可以将cpu-period 设置为 100000 (0.1s) ,–cpu-quota设200000 (0.2s)
[root@localhost stress]# docker run -itd --name cpu01 --cpu-period 100000 --cpu-quota 200000 centos:stress
71a8c4843104f1c122d8188abb7e43481459c649e40403212abc9aeea5bf7f46
[root@localhost stress]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
71a8c4843104 centos:stress "/bin/bash" 5 seconds ago Up 4 seconds cpu01
指定容器目录中
[root@localhost stress]# docker exec -it 71a8c4843104 bash
[root@71a8c4843104 /]#
[root@71a8c4843104 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us
100000
[root@71a8c4843104 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
200000
top完按数值1可查看所有的cpu
[root@localhost ~]# top
top - 18:08:03 up 14:29, 4 users, load average: 0.00, 0.39, 3.53
Tasks: 237 total, 2 running, 235 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 7990276 total, 1400520 free, 1032996 used, 5556760 buff/cache
KiB Swap: 4067324 total, 4067324 free, 0 used. 6418852 avail Mem
CPU Core核心控制
对多核cPU的服务器,Docker还可以控制容器运行使用哪些cPU内核,即使用–cpuset-cpus参数。这对具有多cP0的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。
指定容器只能用0、1两个内核
[root@localhost stress]# docker run -itd --name cpu1 --cpuset-cpus 0-1 centos:stress14f33e4a25ea0d2db2f311720c0aec40932e3e3006cc69b2e34b2672dd53673c
[root@localhost stress]# docker exec -it 14f33e4a25ea bash
[root@14f33e4a25ea /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-1
查看容器中进程与CPU内核绑定关系
[root@localhost stress]# docker exec 14f33e4a25ea taskset -c -p 1
pid 1's current affinity list: 0,1
//容器内部第一个进程号pid为1被绑定在指定的CPU上运行
CPU配额控制参数的混合使用
- 通过cpuset-cpus参数指定容器A使用cPU内核0,容器B只是用cPu内核1。
- 在主机上只有这两个容器使用对应cPU内核的情况,它们各自占用全部的内核资源,cpu-shares没有明显效果。
cpuset-cpus、 cpuset-mems
- 参数只在多核、多内存节点上的服务器上有效,并且必须与实际的物理配置匹配,否则也无法达到资源控制的目的。
- 在系统具有多个CPU内核的情况下,需要通过cpuset-cpus 参数为设置容器CPU内核才能方便地进行测试。
创建两个容器,分别指定不同的内核,和cpu权限,对比查看
[root@localhost cgroup]# docker run -itd --name cpu2 --cpu-shares 512 --cpuset-cpus 1 centos:stress stress -c 1
909c0f358487f0c891551281c7de523659218fdc9417beae57f4c1dd3b271275
[root@localhost cgroup]# docker run -itd --name cpu3 --cpu-shares 1024 --cpuset-cpus 3 centos:stress stress -c 1
e4c0159b9730c56f4eb0e094faad819a7cfbc1aea8ef54c4aca673fd4169a6ac
[root@localhost cgroup]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e4c0159b9730 centos:stress "stress -c 1" About a minute ago Up About a minute cpu3
909c0f358487 centos:stress "stress -c 1" 2 minutes ago Up 2 minutes cpu2
14f33e4a25ea centos:stress "/bin/bash" 18 minutes ago Up 18 minutes cpu1
查看容器cpu使用,不同容器使用不同cpu,其设置的权重无意义
内存限额
与操作系统类似,容器可使用的内存包括两部分:物理内存和Swap。
Docker通过下面两组参数来控制容器内存的使用量。
-m或–memory:设置内存的使用限额,例如100M、1024M。
–memory-swap:设置内存+swap 的使用限额。
配置容器最多使用200M内存和300M的swap
[root@localhost ~]# docker run -itd -m 200M --memory-swap=300M centos:stress
3772ee7ff1ddebb0d7778041ac76883a457ff1ca31bab1afc52bbf61c26da691
[root@localhost ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
3772ee7ff1dd kind_poitras 0.00% 392KiB / 200MiB 0.19% 656B / 0B 0B / 0B 1
Block IO的限制
默认情况下,所有容器能平等地读写磁盘,可以通过设置–blkio-weight参数来改变容器block Io 的优先级。–blkio-weight 与 --cpu-shares类似,设置的是相对权重值,默认为500。
[root@localhost ~]# docker run -it --name container_a --blkio-weight 600 centos:stress
[root@fc246f26e151 /]#cat /sys/fs/cgroup/blkio/blkio.weight
600
bps和iops限制
bps:byte per second :每秒读写的数据量
iops:io per second :每秒IO的次数
–device-read-bps #限制读某个设备的bps
–device-write-bps #限制写莫格设备的bps
–device-read-iops #限制读某个设备的iops
–device-write-iops #限制写某个设备的iops
限制容器写/dev/sda的速率是5MB/s
[root@localhost ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress
[root@15b359e6c3ac /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
^C143+0 records in //按Ctrl+c查看
143+0 records out
149946368 bytes (150 MB) copied, 28.6042 s, 5.2 MB/s
无限制的对比:
[root@localhost ~]# docker run -it centos:stress
[root@02bf0ed857a1 /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
^C877+0 records in
877+0 records out
919601152 bytes (920 MB) copied, 0.905606 s, 1.0 GB/s
总结
资源限制主要类型:CPU、磁盘、内存、IO
资源限制方式:构建镜像时指定镜像资源限制,构建容器时指定容器的资源限制,容器启动后在宿主机对应容器目录下修改资源限制
资源限制查询:docker inspect 镜像ID/容器ID,或者直接查看宿主机对应容器ID资源限制文件(/sys/fs/cgroup/*)