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

client配置 docker docker cgroup配置_linux

说明:

默认情况下,每个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

client配置 docker docker cgroup配置_client配置 docker_02

查看容器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/*)