Docker原理补充:通过资源限制验证Cgroup

Cgroup 全称Control Group,其作用是限制一个进程组对系统资源的使用上限,包括CPU 、内存、Block I/O等;将一组进程放在一个Cgroup中,通过给这个Cgroup分配指定的可用资源,达到控制这—组进程可用资源的目的;Docker在操作系统的 /sys/fs/cgroup/docker 路径下,为每个容器创建了一个用于资源限制的文件夹,该路径中所有的资源种类均可被cgroup限制。
①、内存限额
容器可使用的内存包括两部分:物理内存和swap分区,如果在启动容器时只指定 -m 的值而不指定–memory-swap 的值, 那么 --memory-swap 默认为 -m 的两倍。

# -m 设置内存的使用限额; --memory-swap 设置内存+swap分区的使用限额

[root@node ~]# docker run -m 200M --memory-swap=300M centos:7

注:容器必须处于运行中,可以在目录 /sys/fs/cgroup/memory/docker/docker_id/下的memory.limit_in_bytes 会显示该容器的内存限额。
使用progrium/stress工具对容器执行压力测试,来探讨内存限额的机制。
❶、使用progrium/stress工具测试内存在不超过限额(内存+swap)的情况下,内存使用的工作机理是:通过给容器分配内存、容器使用、然后释放内存,然后一直循环这个过程;

# --vm 指定启动内存工作线程的个数;--vm-bytes 指定为每个线程分配的内存数

[root@node ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 250M
...
stress: dbug: [8] allocating 262144000 bytes ... #分配内存
stress: dbug: [8] touching bytes in strides of 4096 bytes ...
stress: dbug: [8] freed 262144000 bytes  #释放内存
stress: dbug: [8] allocating 262144000 bytes ... #再次分配内存
stress: dbug: [8] touching bytes in strides of 4096 bytes ..
stress: dbug: [8] freed 262144000 bytes  #再次释放内存

❷、使用progrium/stress工具测试内存在超过限额(内存+swap)的情况下,容器直接无法启动而退出

[root@node ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 350M

...
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 0s

②、CPU份额
默认设置下,所有容器可以平等地使用host CPU 资源并且没有限制;设置的cpu shares 并不是CPU 资源的绝对数量,而是一个相对的权重值;

# -c和--cpu-shares参数一样,都是为容器指定CPU的份额
[root@node ~]# docker run --name container_a -c 1024 centos:7
[root@node ~]# docker run --name container_b --cpu-shares 512 centos:7

注:容器必须处于运行中,可以在目录 /sys/fs/cgroup/memory/docker/docker_id/下的cpu_shares 会显示该容器的CPU份额。
在发生CPU资源抢占的情况下,某个容器最终能分配到的CPU 资源取决于它的cpu share 占所有容器cpu share 总和的比例。
使用progrium/stress工具对容器执行压力测试,来探讨CPU限额的机制。
❶、使用progrium/stress镜像运行两个容器Container_A和Container_B,CPU份额分别设置为1024和512(CPU分配比是2:1)

[root@node ~]# lscpu | grep 'CPU(s)'

CPU(s):                2   #本机有2颗CPU

# --cpu是用来设置工作线程的数量,当前host有2颗CPU,需要2个工作线程来占用CPU资源

[root@node ~]# docker run -d -c 1024 --name Container_A progrium/stress --cpu 2

[root@node ~]# docker run -d -c 512 --name Container_B progrium/stress --cpu 2

❷、使用top查看系统资源使用情况可以看到:在%CPU中呈现出使用分配比为2:1的情况(Container_A分配到的资源是Container_B的两倍),因为是2颗CPU,所以每颗CPU都是按照2:1的比例去分配的。

[root@node ~]# top

...
PID USER      PR  NI    ...SHR S  %CPU %MEM     TIME+ COMMAND   
7167 root      20   0    ...0 R  64.8  0.0   2:56.89 /usr/bin/stress
7164 root      20   0    ...0 R  64.5  0.0   2:56.14 /usr/bin/stress
7416 root      20   0    ...0 R  36.9  0.0   1:10.96 /usr/bin/stress
7417 root      20   0    ...0 R  32.6  0.0   1:11.09 /usr/bin/stress

❸、此时停止Container_A可以看到:运行中的Container_B会独占2颗CPU资源,因为此时并没有发生资源抢占的情况。

[root@node ~]# docker stop  Container_A
Container_A
[root@node ~]# top
...   
PID USER      ...SHR S  %CPU %MEM     TIME+ COMMAND  
7416 root      ...96      0 R  99.7  0.0   3:14.73 stress  
7417 root      ...96      0 R  99.0  0.0   3:15.13 stress 

③、Block IO带宽限制
Block IO 指的是磁盘的读写, docker 可通过设置权重weight、限制bps 和iops 的方式控制容器读写磁盘的带宽。
(1).权重weight
默认情况下,所有容器能平等地读写磁盘,可以通过设置–blkio-weight 参数来改变容器block IO 的优先级;–blkio-weight 与–cpu-shares 类似,设置的是相对权重值,默认为500。
(2).限制bps和iops
bps 是 byte per second,每秒读写的数据量,通过 --device-read-bps / --device-write-bps 来限制设备的bps;
iops 是 io per second,每秒IO 的次数,通过 --device-read-iops / --device-write-iops 来限制设备的iops。
❶、验证带宽限制:运行一个base镜像,在没有进行IO带宽限制的情况下是239 MB/s

[root@node ~]# docker run -it centos:7  
[root@231682cd2622 /]# dd if=/dev/zero of=test.out bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.438719 s, 239 MB/s

❷、将写IO限制在30M的情况下是30MB/s,注意在容器内部写IO的时候必须添加上oflag=direct参数这样–device-write-bps 才能生效。
注:查看容器使用的磁盘sda,所以限制参数只能限制到 /dev/sda上。

[root@node ~]# docker run -it --device-write-bps /dev/sda:30M centos:7 

[root@f8163e8c0552 /]# lsblk  #查看容器使用的磁盘sda
...
sda      8:0    0  100G  0 disk 
|-sda1   8:1    0    1G  0 part 
`-sda2   8:2    0   99G  0 part
[root@f8163e8c0552 /]# dd if=/dev/zero of=test.out bs=1M count=100 
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.412428 s, 254 MB/s

[root@f8163e8c0552 /]# dd if=/dev/zero of=test.out bs=1M count=100 oflag=direct  #添加该参数之后才能生效对bps的限制
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 3.3218 s, 31.6 MB/s
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KnockCloud

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值