偷偷学 Docker 系列 | 资源控制 - Cgroup

前言 - Cgroup

默认情况下,容器是没有资源限制的,会尽可能的使用宿主机的资源,笔者之前练习时开启了两个 while 无限循环输出的容器,那笔记本的风扇直接就疯狂的转动了起来~

针对于此,Docker 提供了一种资源控制的方式,即 Cgroup

Cgroup 是 Control group 的简写,是 Linux 内核提供的一种限制所使用物理资源的机制,包括 CPU、内存 和 IO 这三大方面,基本覆盖了常见的资源配额和使用量控制


一、对 CPU 的控制

1.使用 stress 工具测试

[root@docker ~]# mkdir /opt/stress
[root@docker ~]# vim /opt/stress/Dockerfile
FROM centos:7
RUN yum -y install wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo		'//epel源,可以使用扩展软件包(stress)'
RUN yum -y install stress		'//可以指定产生线程,使用循环语句,测试用'

--
[root@docker ~]# cd /opt/stress/
[root@docker ~]# systemctl restart docker.service		'//建议重启docker,不然下面的操作可能会失败,卡在wget'
[root@docker stress]# docker build -t centos:stress .		'//生成镜像'
...
...
Successfully built 175239ff1fce
Successfully tagged centos:stress
[root@docker stress]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                          PORTS     NAMES
50913883c239   8652b9f0cb4c   "/bin/sh -c 'yum -y …"   2 minutes ago   Exited (1) About a minute ago             amazing_swartz
[root@docker stress]# docker images 
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
centos       stress    175239ff1fce   18 minutes ago   456MB
centos       7         8652b9f0cb4c   4 months ago     204MB

--
'//以下可以使用该镜像为基础产生的容器进行测试:'

2.限制 CPU 使用周期速率

1.查看CPU的资源限制
命令格式:
cat /sys/fs/cgroup/cpu/docker/[容器ID]/cpu.cfs_quota_us

例:
[root@docker ~]# docker run -itd --name test2 centos:7 /bin/bash
2964d084535d0670cdf79233a0d2e2a99620d1f0c93854ac8ca73944d4affd5e
[root@docker ~]# cat /sys/fs/cgroup/cpu/docker/2964d084535d0670cdf79233a0d2e2a99620d1f0c93854ac8ca73944d4affd5e/cpu.cfs_quota_us 
-1
'//-1代表不进行任何限制'

--
2.手动修改文件以实现修改CPU限制
[root@docker ~]# echo 20000 > /sys/fs/cgroup/cpu/docker/2964d084535d0670cdf79233a0d2e2a99620d1f0c93854ac8ca73944d4affd5e/cpu.cfs_quota_us 
[root@docker ~]# cat /sys/fs/cgroup/cpu/docker/2964d084535d0670cdf79233a0d2e2a99620d1f0c93854ac8ca73944d4affd5e/cpu.cfs_quota_us 
20000

--
3.在运行容器的同时指定CPU限制条件
'以下这两个参数一般联合使用,控制容器可以分配到的CPU时钟周期'
'--cpu-period是用来指定容器对CPU的使用要在多长时间内做一次重新分配'
'--cpu-quota是用来指定在这个周期内,最多可以有多少时间来跑这个容器'

例:
'容器进程需要每秒使用单个CPU的0.2秒时间,可以将period设为1000000(1s)'
'若在多核琴科给下,允许容器进程完全占用两个CPU,可以将period设置为100000(0.1s)'
[root@docker stress]# docker run -itd --name cpu01 --cpu-period=100000 --cpu-quota=200000 centos:stress
7c3a352375a46df1c93e2cf575cbc8cc833f00b13db237e7e184efad3e7464be
[root@docker stress]# docker exec -it 7c3 bash
[root@7c3a352375a4 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 
100000
[root@7c3a352375a4 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us  
200000

3.多任务比例分享 CPU

当有多个容器任务同时运行时,很难计算 CPU 的使用率,我们可以设置 CPU 按照比例共享 CPU 资源,以实现使用率的动态调整

[root@docker stress]# docker run -itd --name cpu1 --cpu-shares 1024 centos:stress stress -c 10		'//-c 10表示产生10个子线程,测试用'
624954cbbc38df08422edcd4e4e1f28708e4d098e4baceea83fe1632a17c0784
[root@docker stress]# docker exec -it 624 bash
[root@624954cbbc38 /]# top		'//查看CPU使用率'

--新开一个终端--
[root@docker stress]# docker run -itd --name cpu2 --cpu-shares 2048 centos:stress stress -c 10
6d32a73b608b035f0400b5290628e3973089ca72121a2abfc277e59660be0aeb
[root@docker stress]# docker exec -it 6d3 bash
[root@6d32a73b608b /]# top		'//对比CPU使用率,是1:2'

使用【–cpu-shares】,分配两个容器使用CPU资源占用权重为1:2

  1. 默认情况下,每个Docker容器的CPU份额都是1024,单独一个容器的份额是没有意义的,只有在同时运行多个容器时,容器CPU的加权效果才能体现出来
  2. 比如以上的两个容器是1:2,在CPU进行时间片分配时,后者比前者多一倍的机会获得CPU的时间片,但是分配的结果取决于当时主机和其他容器的运行状态
  3. 实际上也无法保证该容器一定获得相应的CPU时间片,因为若是该的进程一直是空闲的,那么cpu1就可以获取比cpu2更多的CPU时间片
  4. 在极端情况下,例如主机上只运行了一个容器,即使它的CPU份额较小,也是可以独占整个主机的CPU资源的
  5. Cgroups只在容器分配的资源紧缺时,即在需要对容器使用的资源进行限制时,才会生效,因此,无法根据某个容器的CPU份额来确定有多少CPU资源分给给它
  6. 即资源分配的结果取决于同时运行的其他容器CPU分配和容器中进程的运行情况

4.限制 CPU 内核使用

可以通过配置,使得某些程序独享 CPU 内核,以提高其处理速度

[root@docker ~]# cat /sys/fs/cgroup/cpuset/docker/d00a2563e936dd1198a80869efaf5d7d2b5c4d751d5bec4e80a6bdfdbbfcfd8c/cpuset.cpus
0-7
'//若该服务器有8个核心,那么CPU编号为0-7,表示该容器内的进程在核心上皆可运行,这是默认配置'
'//可查看/proc/cpuinfo中的CPU编号(processor)'

--
[root@docker ~]# docker run -itd --name a1 --cpuset-cpus 0-1 centos:7
'//表示创建的容器只能使用0、1两个内核,其后可以使用top命令按1查看CPU使用'

--
[root@docker ~]# docker exec [容器ID] taskset -c -p 1
'//表示绑定至指定CPU上运行'

在实际使用中,尽量使用绑定内核的方式分配 CPU 资源,然后再配合【–cpu-share】选项来动态调整 CPU 使用资源的比例
住意,这里若是两个容器各自指定不同的CPU内核,则–cpu-share基本没有效果


二、对内存使用的限制

'与操作系统类似,容器可使用的内存包括两部分:物理内存和 Swap'
'-m 或 --memory:设置内存的使用限额'
'--memory-swap:设置内存+swap 的使用限额'

--
docker run -itd -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
'//--vm 1:启动1个内存工作线程'
'//--vm-bytes 280M:每个线程分配280M内存'

--
'相应的Cgroup配置文件:/sys/fs/cgroup/memory/memory.limit_in_bytes'

docker run -itd -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
'//如果让工作线程分配的内存超过300M,分配的内存超过了限额,stress线程会报错,容器退出'

--
'注意!一旦容器Cgroup使用的内存超过了限制的容量,Linux内核就会尝试收回这些内存'
'如果仍旧无法控制内存使用在这个设置的范围之内,就会杀死该进程!'

三、对磁盘 IO 资源的限制

如果实在一台服务器上进行容器的混合部署,那么可能会出现同时有几个程序写磁盘数据的情况,那么如何进行限制呢?

bps:byte per second(每秒读写的字节数)
iops:io per second(每秒IO的次数)

--
1.限制某个程序写入的bps数据量
docker run -d --device-write-bps /dev/sda:30M centos:7


2.限制读取某个程序的bps数据量
docker run -d --device-read-bps /dev/sda:30M centos:7


3.限制读取某个程序的iops次数
--device-read-iops


4.限制写入某个程序的iops次数
--device-write-iops

示例:限制容器写 /dev/sda 的速率为 5MB/s

[root@docker ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress
[root@0c729425a662 /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct		
'//dd复制,从zero拿文件test,每次拿1MB,写1024次即1GB大小'
'oflag=direct表示指定用direct IO 方式写文件,这样--device-write-bps才能生效'
^C53+0 records in		'//ctrl+c中途退出'
53+0 records out
55574528 bytes (56 MB) copied, 10.6067 s, 5.2 MB/s

结果显示为5.2MB,以下再来对比测试一下不限速的

[root@0c729425a662 /]# exit
exit
[root@docker ~]# 
[root@docker ~]# docker run -it centos:stress
[root@8640cab42b0a /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 3.66132 s, 293 MB/s
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Xucf1

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

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

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

打赏作者

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

抵扣说明:

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

余额充值