• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

云原生docker-Cgroup资源限制

武飞扬头像
平平无奇打工仔
帮助1

Docker容器的资源控制

Docker通过Cgroup 来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。Caroup 是ControlGroups的缩写,是Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 cpu、内存、磁盘,io等等)的机制,被LXC、docker等很多项目用于实现进程资源控制。Cgroup本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O或内存的分配控制等具体的资源管理是通过该功能来实现的。

资源限制:可以对任务使用的资源总额进行限制。
优先级分配:通过分配的cpu时间片数量以及磁盘IO带宽大小,实际上相当于控制了任务运行优先级。
资源统计:可以统计系统的资源使用量,如cpu时长,内存用量等。
任务控制: cgroup可以对任务 执行挂起、恢复等操作。

 

docker占用宿主机cpu的限制

 Linux通过CFS (Completely Fair Scheduler,完全公平调度器)来调度各个进程对ceu的使用。CFS默认的调度周期是100ms 。我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少CPU时间。

学新通

 使用--cpu-period 即可设置调度周期,使用--cpu-quota即可设置在每个周期内容器能使用的CPU时间。两者可以配合使用。CFS周期的有效范围是 1ms~1s,对应的--cpu-period 的数值范围是1000~1000000。而容器的CPU配额必须不小于1ms,即--cpu-quota的值必须>= 1000。而容器的CPU配额必须不小于1ms,即--cpu-quota的值必须>= 1000。
学新通

 学新通

  1.  
    #正常创建容器(此时容器遵循默认的占用cpu资源规则)
  2.  
    [root@localhost ~]#docker run -id --name c1 centos:7
  3.  
     
  4.  
    [root@localhost ~]#docker ps -a
  5.  
     
  6.  
    [root@localhost ~]#docker exec -it c1 bash
  7.  
     
  8.  
    [root@d6da0a6b999a /]# vi cpu.sh
  9.  
     
  10.  
    #!/bin/bash
  11.  
    i=0
  12.  
    while true
  13.  
    do
  14.  
    let i
  15.  
    done
  16.  
     
  17.  
     
  18.  
    [root@d6da0a6b999a /]# chmod x cpu.sh
  19.  
     
  20.  
    [root@d6da0a6b999a /]# ./cpu.sh
学新通

学新通学新通

 由该结果可以看出,如果在创建容器时不限制它cpu使用的限制,是非常危险的一件事,一旦某个容器的程序异常陷入死循环,将直接导致其他容器中业务的中断 !

 (2)修改默认的容器时间分片上限规则,再次创建启动测试

  1.  
    docker start c1
  2.  
    docker ps -a
  3.  
    #d6da0a6b999aeaac89e2ce883b6ff057abd5f4c2319d9a539635ff8e1f43fe04为容器id
  4.  
    cd/sys/fs/cgroup/cpu/docker/d6da0a6b999aeaac89e2ce883b6ff057abd5f4c2319d9a539635ff8e1f43fe04
  5.  
     
  6.  
    [root@localhost d6da0a6b999aeaac89e2ce883b6ff057abd5f4c2319d9a539635ff8e1f43fe04]#echo 50000 > cpu.cfs_quota_us

学新通

 学新通

 学新通

 (3)创建容器时指定容器的cpu资源占用量上限 

  1.  
    docker run -id --name c2 --cpu-quota 30000 centos:7
  2.  
    [root@localhost docker]#docker exec -it c2 bash
  3.  
    [root@10cfa036ff07 /]# vim cpu.sh
  4.  
    #!/bin/bash
  5.  
    i=0
  6.  
    while true
  7.  
    do
  8.  
    let i
  9.  
    done
  10.  
    [root@10cfa036ff07 /]# vi cpu.sh
  11.  
    [root@10cfa036ff07 /]# chmod x cpu.sh
  12.  
    [root@10cfa036ff07 /]# ./cpu.sh

学新通

 学新通

 (4)多cpu分配容器的使用上限

  1.  
    [root@localhost docker]#docker run -id --name c3 centos:7
  2.  
     
  3.  
    [root@localhost docker]#docker ps -a
  4.  
     
  5.  
    [root@localhost docker]#cd /sys/fs/cgroup/cpu/docker/a1ce6948cdb6167570e6ef2101bb407d7de79407fbd9b9ac737ed40487f91a5a/
  6.  
    [root@localhost a1ce6948cdb6167570e6ef2101bb407d7de79407fbd9b9ac737ed40487f91a5a]#ls
  7.  
     
  8.  
    [root@localhost a1ce6948cdb6167570e6ef2101bb407d7de79407fbd9b9ac737ed40487f91a5a]#echo 200000 > cpu.cfs_quota_us

学新通

  1.  
    [root@localhost ~]#docker exec -it c3 bash
  2.  
    [root@a1ce6948cdb6 /]# vi cpu.bash
  3.  
    #!/bin/bash
  4.  
    i=0
  5.  
    while true
  6.  
    do
  7.  
    let i
  8.  
    done
  9.  
    [root@a1ce6948cdb6 /]# chmod x ./cpu.bash
  10.  
    [root@a1ce6948cdb6 /]# ./cpu.bash

学新通

 学新通

 设置cpu资源的占用比 

注意:该方式需要设置多个容器时才会生效 

 创建容器时可以使用选项  --cpu-shares  数值(该数值要为1024的倍数,1024代表一份,当个容器占用cpu的份额由自身分配的份数除于所有容器占用cpu的份数,就为该容器所占用cpu资源的百分比)

进行分配

  1.  
    [root@localhost ~]#docker run -id --name b1 --cpu-shares 2048 centos:7
  2.  
     
  3.  
    [root@localhost ~]#docker run -id --name b2 --cpu-shares 1024 centos:7
  4.  
     
  5.  
    [root@localhost ~]#docker run -id --name b3 --cpu-shares 1024 centos:7

学新通

 开启三个终端,启动容器压测:

  1.  
    #三个容器均为以下压测操作
  2.  
    #下载压测工具依赖环境
  3.  
    yum install -y epel-release
  4.  
    #下载压测工具
  5.  
    yum install -y stress
  6.  
    #进行四个线程压测
  7.  
    stress -c 4
  8.  
     
  9.  
     
  10.  
    #再开启一个终端查看测试结果
  11.  
    docker stats

学新通

学新通

由测试结果, 可以看到在cPU进行时间片分配的时候,容器b1比容器b2和b3多一倍的机会获得cpu的时间片。但分配的结果取决于当时主机和其他容器的运行状态,实际上也无法保证容器 b2和b3一定能获得cpu时间片

比如容器b2和b3的进程一直是空闲的,那么容器b1是可以获取比容器b2和b3更多的cpu时间片的。极端情况下,例如主机上只运行了一个容器,即使它的cpu份额只有50,它也可以独占整个主机的cpu资源。

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

 设置容器绑定指定的cpu 

  1.  
    top
  2.  
    按数字“1

学新通

 进行绑核创建容器 

[root@localhost ~]#docker run -id --name b4 --cpuset-cpus 2 centos:7

学新通

 压力测试:

  1.  
    yum install -y epel-release
  2.  
    yum insatll -y stress
  3.  
     
  4.  
    stress -c 1

学新通

  测试结果:

学新通

 内存使用的限制

 4.1 限制容器可以使用的最大内存

m (或--memory=)选项用于限制容器可以使用的最大内存 

  1.  
    docker run -itd --name d1 -m 512m centos:7 /bin/bash
  2.  
    docker stats

学新通

 限制容器可用的swap 大小 


 #限制可用的swap 大小,--memory-swap  

●强调一下, --memory-swap是必须要与 --memory(或-m)一起使用的。

●正常情况下, --memory-swap 的值包含容器可用内存和可用swap 。

●所以 -m 300m --memory-swap=1g 的含义为:容器可以使用300M 的物理内存,并且可以使用700M (1G - 300M)的swap。    设置为0或者不设置,则容器可以使用的 swap 大小为 -m 值的两倍。  如果 --memory-swap 的值和 -m 值相同,则容器不能使用swap。  如果 --memory-swap 值为 -1,它表示容器程序使用的内存受限,而可以使用的swap空间使用不受限制(宿主机有多少swap 容器就可以使用多少)。

  1.  
    #--memory-swap 的值包含容器可用内存和可用swap,减去-m的值才是可用swap的值。
  2.  
    #表示容器可以使用512M的物理内存,并且可以使用512M的swap。因为1g减去512m的物理内存,剩余值才是可用swap。
  3.  
    docker run -itd --name d2 -m 512m --memory-swap=1g centos:7 bash
  4.  
  5.  
  6.  
    #--memoryswap值和 -m 的值相同,表示容器无法使用swap
  7.  
    docker run -itd --name d3 -m 512m --memory-swap=512m centos:7 bash
  8.  
  9.  
  10.  
    # --memory-swap 的值设置为0或者不设置,则容器可以使用的 swap 大小为 -m 值的两倍。
  11.  
    docker run -itd --name d4 -m 512m centos:7 bash
  12.  
  13.  
  14.  
    # --memory-swap 值为 -1,它表示容器程序使用的内存受限,但可以使用的swap空间使用不受限制(宿主机有多少swap 容器就可以使用多少)。
  15.  
    docker run -itd --name d5 -m 512m --memory-swap=-1 centos:7 bash
学新通

对磁盘IO的配置控制(blkio)的限制 

-device-read-bps:限制某个设备上的读速度bps ( 数据量),单位可以是kb、mb (M)或者gb。

--device-write-bps : 限制某个设备上的写速度bps ( 数据量),单位可以是kb、mb (M)或者gb。

该速度是指每秒钟进行读写操作1M,1G或者是1kb 

--device-read-iops :限制读某个设备的iops (次数)

--device-write-iops :限制写入某个设备的iops ( 次数)

默认情况下容器的写速度 

  1.  
    [root@localhost ~]#docker run -id --name e1 centos:7
  2.  
    [root@localhost ~]#docker exec -it e1 bash
  3.  
    [root@8657384cb483 /]# dd if=/dev/zero of=/opt/test.txt bs=10M count=5 oflag=direct
  4.  
    ## oflag=direct 规避文件读写系统中所带来的缓存,避免影响测试结果

学新通

 进行写速度限制的容器创建 

  1.  
     
  2.  
    [root@localhost ~]#docker run -it --name e3 --device-write-bps /dev/sda:1M centos:7 /bin/bash
  3.  
    [root@6c1b8bcf6b44 /]# dd if=/dev/zero of=/opt/test.out bs=10M count=5 oflag=direct

学新通

 总结

 对cpu的限制参数

  1.  
    docker run --cpu-period #设置调度周期时间1000~1000000
  2.  
    --cpu-quota #设置容器进程的CPU占用时间,要与调度周期时间成比例
  3.  
    --cpu-shares #设置多个容器之间的CPU资源占用比
  4.  
    --cpuset-cpus #绑核(第一个CPU编号从0开始)

对内存的限制

 -m 物理内存 [--memory-swap=总值]

对磁盘IO的限制

  1.  
    --device-read-bps 设备文件:1mb/1M #限制读速度
  2.  
    --device-write-bps 设备文件:1mb/1M #限制写速度
  3.  
    --device-read-iops #限制读次数
  4.  
    --device-write-iops #限制写次数
  5.  
  6.  
    docker system prune -a #清理磁盘,删除关闭的容器、无用的数据卷和网络。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhghbgba
系列文章
更多 icon
同类精品
更多 icon
继续加载