玩转docker之Cgroup资源配置

49 篇文章 0 订阅
15 篇文章 2 订阅

玩转docker之Cgroup资源配置

博主为大家找到一篇比较不错的博客哦!有助于大家了解docker 中的cgroup中的资源配置。

对大家有帮助的话,就去关注一下原创哦!

转载地址:https://www.cnblogs.com/xuhao0705/p/14073525.html

 


Top

摘要

Docker通过Cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。

Top

一、Cgroup简介

Cgroup是Control Groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如CPU、内存、磁盘IO等待)的机制,被LXC、docker等很多项目用于实现进程资源控制。Cgroup本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O或内存的分配控制等具体的资源管理是通过该功能来实现的。这些具体的资源管理功能称为Cgroup子系统,有以下几大子系统实现:

blkio:设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及usb等等

CPU:使用调度程序为cgroup任务提供CPU的访问

cpuacct:产生cgroup任务的CPU资源报告

cpuset:如果是多核心的CPU,这个子系统会为cgroup任务分配单独的CPU和内存

devices:允许或拒绝cgroup任务对设备的访问

freezer:暂停和恢复cgroup任务

memory:设置每个cgroup的内存限制以及产生内存资源报告

net_cls:标记每个网络包以供cgroup方便使用

ns:命名空间子系统

perf_event:增加了对每个group的监测跟踪的能力,可以监测属于某个特定的group的所有线程以及运行在特定CPU上的线程

下面开始使用stress压力测试工具来测试CPU和内存使用状况

Top

二、安装stress工具

复制代码
 1 创建stress目录
 2 [root@server1 ~]# mkdir /opt/stress
 3 [root@server1 ~]# cd /opt/stress/
 4 
 5 编写Dockerfile文件
 6 [root@server1 stress]# vim DockerfileFROM centos:7
 7 MAINTAINER xu
 8 RUN yum -y install wget
 9 RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/rep
10 o/epel-7.repo
11 RUN yum -y install stress
12 
13 构建镜像
14 [root@server1 stress]# docker build -t centos:stress .
15 
16 查看镜像
17 [root@server1 stress]# docker images
18 REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
19 centos              stress              821b4e4b3972        5 seconds ago       417MB
复制代码
Top

三、CPU资源分配

默认情况下,每个Docker容器的CPU份额都是1024。单独一个容器的份额是没有意义的。只有在同时运行多个容器时,容器的CPU加权的效果才能体现出来。例如,两个容器A、B的CPU份额分别为1000和500,在CPU进行时间片分配的时候,容器A比容器B多一倍的机会获得CPU的时间片。但分配的结果取决于当时主机和其他容器的运行状态,实际上也无法保证容器A一定能获得CPU时间片。比如容器A的进程一直时空闲的,那么容器B是可以获取比容器A更多的CPU时间片的,极端情况下,例如主机上只运行了一个容器,即使它的CPU份额只有50,它也可以独占整个主机的CPU资源

Cgroup只在容器分配的资源紧缺时,即在需要对容器使用的资源进行限制时,才会生效。因此,无法单纯根据某个容器的CPU份额来确定有多少CPU资源分配给它,资源分配结果取决于同时运行的其他容器的CPU分配和容器中进程运行情况。

可以通过cpu share可以设置容器使用CPU的优先级,比如,启动了两个容器及运行查看CPU使用百分比

3.1、运行两个容器

 

复制代码
1 [root@server1 stress]# docker run -dit --name cpu500 --cpu-shares 500 centos:stress stress -c 10
2 c0083744c59f24ca4ff008b2e5fa25dbd7e3363c7b81362d5f4f87c0ac486c7b
3 [root@server1 stress]# docker run -dit --name cpu1000 --cpu-shares 1000 centos:stress stress -c 10
4 b84cc76469bc7264b26a3c9db846b2e07918a25e425b1bf62bc9688e501dc82f
复制代码

 

3.2、查看内存使用情况

复制代码
 1 进入cpu1000容器
 2 [root@server1 stress]# docker exec -it b84cc76469bc /bin/bash
 3 
 4 查看cpu使用情况
 5 [root@b84cc76469bc /]# top
 6 
 7 进入cpu500容器
 8 [root@server1 stress]# docker exec -it c0083744c59f /bin/bash
 9 
10 查看cpu使用情况
11 [root@c0083744c59f /]# top
复制代码

容器1000cpu使用情况如下

 

 

 容器500cpu使用情况如下

 

 

 

对比后可以得出cpu1000的容器cpu使用率大概是另一个的两倍

Top

四、CPU周期限制

Docker提供了--cpu-period、--cpu-quota两个参数控制容器可以分配到的CPU时钟周期。

  • --cpu-period是用来指定容器对CPU的使用要在多长时间内做一次重新分配。
  • --cpu-quota是用来指定在这个周期内,最多可以有多少时间用来跑这个容器。
  • 与--cpu-shares不同的是,这种配置是指定一个绝对值,容器对CPU资源的使用绝对不会超过配置的值
  • cpu-period和cpu-quota的单位为微秒(μs)。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.1秒),cpu-quota设置为200000(0.2秒)。

复制代码
 1 运行容器并设置周期
 2 [root@server1 stress]# docker run -dit --cpu-period 100000 --cpu-quota 200000 centos:stress 
 3 9449396fc3b0b8a99b1fb8fb211998032bc91933df831b5c3341e435a64beda5
 4 [root@server1 stress]# docker ps -a
 5 CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                        PORTS               NAMES
 6 9449396fc3b0        centos:stress       "/bin/bash"         5 seconds ago       Up 4 seconds                                      goofy_mclean
 7 
 8 进入容器
 9 [root@server1 stress]# docker exec -it 9449396fc3b0 /bin/bash
10 
11 查看周期
12 [root@9449396fc3b0 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 
13 100000
14 [root@9449396fc3b0 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us 
15 200000
复制代码
Top

五、CPU Core控制

对多核 CPU 的服务器,Docker 还可以控制容器运行使用哪些 CPU 内核,即使用--cpuset-cpus 参数。这对具有多 CPU 的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。

5.1、进行CPU Core控制配置

复制代码
 1 表示创建的容器只能用 01两个内核
 2 [root@server1 ~]# docker run -dit --name cpu1 --cpuset-cpus 0-1 centos:stress 
 3 3266be3c50ebfe8e4e34bc3c202e7ad419314aedccdea1b09c941baf029569d1
 4 
 5 查看容器运行状态
 6 [root@server1 ~]# docker ps -a
 7 CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
 8 3266be3c50eb        centos:stress       "/bin/bash"         6 seconds ago       Up 5 seconds                            cpu1
 9 
10 进入容器
11 [root@server1 ~]# docker exec -it 3266be3c50eb /bin/bash
12 
13 生成  cgroup  CPU 内核配置如下
14 [root@3266be3c50eb /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
15 0-1
复制代码

5.2、CPU内核绑定

通过下面指令可以看到容器中进程与 CPU 内核的绑定关系,达到绑定 CPU 内核的目的

1 [root@server1 ~]# docker exec 3266be3c50eb taskset -c -p 1
2 pid 1's current affinity list: 0,1

5.3、压力测试

Top

六、CPU配额参数的混合使用

通过 cpuset-cpus 参数指定容器 A 使用 CPU 内核 1,容器 B 只是用 CPU 内核 3。在主机上只有这两个容器使用对应 CPU 内核的情况,它们各自占用全部的内核资源,cpu-shares 没有明显效果。

cpuset-cpus、cpuset-mems 参数只在多核、多内存节点上的服务器上有效,并且必须与实际的物理配置匹配,否则也无法达到资源控制的目的。

在系统具有多个 CPU 内核的情况下,需要通过 cpuset-cpus 参数为设置容器 CPU 内核才能方便地进行测试

复制代码
 1 CPU配置
 2 [root@server1 ~]# docker run -dit --name cpu3 --cpuset-cpus 1 --cpu-shares 500 centos:stress stress -c 1
 3 275bc9803463abd9098c632d836f605d76bab74467cff2cd57f956762f6fed24
 4 [root@server1 ~]# docker run -dit --name cpu4 --cpuset-cpus 3 --cpu-shares 1000 centos:stress stress -c 1
 5 be61e954017eb398701c9c17440cdf3c72450e4ebb1b76fb2022afeadee277fd
 6 
 7 查看容器运行情况
 8 [root@server1 ~]# docker ps -a 
 9 CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
10 be61e954017e        centos:stress       "stress -c 1"       48 seconds ago       Up 48 seconds                           cpu4
11 275bc9803463        centos:stress       "stress -c 1"       About a minute ago   Up About a minute                       cpu3
12 
13 分别进入两个容器
14 [root@server1 ~]# docker exec -it 275bc9803463 /bin/bash
15 [root@server1 ~]# docker exec -it be61e954017e /bin/bash
16 
17 分别查看CPU使用情况
18 [root@be61e954017e /]# top        #记住按1查看每个核心的占用
复制代码

cpu3容器cpu使用情况

 

cpu4容器cpu使用情况

 

 

 

总结:上面的 centos:stress 镜像安装了 stress 工具,用来测试 CPU 和内存的负载。通过 在两个容器上分别执行 stress -c 1 命令,将会给系统一个随机负载,产生 1 个进程。这 个进程都反复不停的计算由 rand() 产生随机数的平方根,直到资源耗尽。观察到宿主机上的 CPU 使用率,第三个内核的使用率接近 100%, 并且一批进程的 CPU 使用率明显存在 2:1 的使用比例的对比。

Top

七、内存限额

与操作系统类似,容器可使用的内存包括两部分:物理内存和Swap,Docker通过下面两组参数来控制容器内存的使用量

  • -m或--memory:设置内存的使用限额,例如100M、1024M。
  • --memory-swap:设置内存+swap的使用限额

执行如下命令允许该容器最多使用200M的内存和300M的内存+swap

复制代码
 1 内存限额配置
 2 [root@server1 ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
 3 stress: dbug: [1] using backoff sleep of 3000us
 4 stress: dbug: [1] --> hogvm worker 1 [6] forked
 5 stress: dbug: [6] allocating 293601280 bytes ...
 6 stress: dbug: [6] touching bytes in strides of 4096 bytes ...
 7 会一直运行
 8 
 9 --vm 1:启动 1 个内存工作线程。 
10 --vm-bytes 280M:每个线程分配 280M 内存。 
11 默认情况下,容器可以使用主机上的所有空闲内存。
12 
13 如果让工作线程分配的内存超过300M,分配的内存超过限额,stress线程报错,容器退出
14 [root@server1 ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M
15 stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
16 stress: dbug: [1] using backoff sleep of 3000us
17 stress: dbug: [1] --> hogvm worker 1 [6] forked
18 stress: dbug: [6] allocating 325058560 bytes ...
19 stress: dbug: [6] touching bytes in strides of 4096 bytes ...
20 stress: FAIL: [1] (416) <-- worker 6 got signal 9
21 stress: WARN: [1] (418) now reaping child worker processes
22 stress: FAIL: [1] (422) kill error: No such process         #没有进程退出
23 stress: FAIL: [1] (452) failed run completed in 1s
复制代码
Top

八、Block IO的限制

默认情况下,所有容器能平等地读写磁盘,可以通过设置--blkio-weight参数来改变容器block IO的优先级。--blkio-weight与--cpu-shares类似,设置的是相对权重值,默认为500。

在下面的例子中,容器A读写磁盘的带宽是容器B的两倍

复制代码
 1 Block IO 的限制配置
 2 [root@server1 ~]# docker run -dit --name container_A --blkio-weight 400 centos:stress 
 3 6cfcf6a595b729cf77267ad939e70a1e30f973b3197d4aec2903ec3429a78b3b
 4 [root@server1 ~]# docker run -dit --name container_B --blkio-weight 200 centos:stress 
 5 e680d986196c36c4910c7e91fe798c2389e0d298c0c4e5bc7b76d99e288fdf82
 6 
 7 查看容器运行情况
 8 [root@server1 ~]# docker ps -a 
 9 CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS               NAMES
10 e680d986196c        centos:stress       "/bin/bash"              46 seconds ago       Up 46 seconds                                   container_B
11 6cfcf6a595b7        centos:stress       "/bin/bash"              About a minute ago   Up About a minute                               container_A
12 
13 进入容器分别查看
14 [root@server1 ~]# docker exec -it 6cfcf6a595b7 /bin/bash
15 [root@6cfcf6a595b7 /]# cat /sys/fs/cgroup/blkio/blkio.weight
16 400
17 
18 [root@server1 ~]# docker exec -it e680d986196c /bin/bash
19 [root@e680d986196c /]# cat /sys/fs/cgroup/blkio/blkio.weight
20 200
复制代码
Top

九、bps和iops的限制

bps是byte per second,每秒读写的数据量

iops是io per second,每秒IO的次数

可通过以下参数控制容器的bps和iops:

  • --device-read-bps,限制读某个设备的bps
  • --device-write-bps,限制写某个设备的bps
  • --device-read-iops,限制读某个设备的iops
  • --device-write-iops,限制写某个设备的iops 

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

复制代码
 1 bps  iops 的限制配置
 2 [root@server1 ~]# docker run -dit --device-write-bps /dev/sda:5MB centos:stress 
 3 88fa4e4ca86fa3f17ed829d91a597d7b7f6645ca0c11d23af3441406203291f2
 4 
 5 查看容器运行情况
 6 [root@server1 ~]# docker ps -a
 7 CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
 8 88fa4e4ca86f        centos:stress       "/bin/bash"         5 seconds ago       Up 4 seconds                            interesting_mclaren
 9 
10 进入容器
11 [root@server1 ~]# docker exec -it 88fa4e4ca86f /bin/bash
12 
13 进行测试
14 [root@88fa4e4ca86f /]# dd if=/dev/zero of=text bs=1M count=1024 oflag=direct      #
15 可以按ctrl+c中断查看
16 ^C14+0 records in
17 14+0 records out
18 14680064 bytes (15 MB) copied, 2.80506 s, 5.2 MB/s #限速5MB/s
复制代码

通过dd命令测试在容器中写磁盘的速度。因为容器的文件系统是在host /dev/sda上的,在容器中写文件相当于对host /dev/sda进行写操作。另外,oflag=direct指定用direct IO方式写文件,这样 --device-write-bps才能生效

结果表明限速5MB/s左右。作为对比测试,如果不限速,结果如下:

复制代码
1 运行另一个容器
2 [root@server1 ~]# docker run -it centos:stress 
3 
4 [root@ffd2062aa3a4 /]# dd if=/dev/zero of=text bs=1M count=1024 oflag=direct
5 1024+0 records in
6 1024+0 records out
7 1073741824 bytes (1.1 GB) copied, 0.465947 s, 2.3 GB/s  #不限速,2.3GB/s
复制代码

 

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值