docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker Cgroup资源配置

Docker中Cgroup资源配置的实现

作者:margu_168

Cgroup不仅可以限制被namespace 隔离起来的资源,还可以为资源设置权重、计算使用量、操控进程启停等,本文主要介绍了Docker中Cgroup资源配置的实现,感兴趣的可以了解一下

其实在日常的工作中,我们一般都没有对docker容器进行资源限制,也就是默认情况下,可以使用宿主机的所有资源。但是如果你运行的服务有问题,就有可能对宿主机和宿主机上的其他业务造成影响,这还是有一定的风险。那么本文会给大家介绍一下如何对容器进行资源配置管理。

一、Cgroup资源配置简介

Cgroup,全称Control Groups,是一个非常强大的linux内核工具,它不仅可以限制被namespace 隔离起来的资源,还可以为资源设置权重、计算使用量、操控进程启停等等。Docker通过Cgroup 来控制容器使用资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了对常见的资源配额和使用量控制管理。

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

Cgroup子系统作用
blkio用于对块设备的输入输出进行控制。例如:磁盘,光盘等。
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上的线程。

二、CPU时间片的概念

时间片可以理解为CPU分配给各个程序的运行时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。而不会造成CPU资源浪费。

在宏观上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行。但在微观上:假如只有一个CPU,一次只能处理要求的一部分程序,那么如何分配,一种方法就是引入时间片,每个程序在某个时间片段轮流执行。

测试使用环境:centos7,docker-ce-19.03.15,2个物理CPU,总共16核

三、CPU的资源配额

1、资源准备

先制作一个有stress命令的镜像,方便进行压测。并查看当前版本的docker支持的关于cpu方便的配置。Linux通过CFS (Completely Fair Scheduler, 完全公平调度器)来调度各个进程对CPU的使用。

[root@k8s-m1 docker]# cat Dockerfile
FROM centos:7
MAINTAINER margu_168
RUN yum install -y wget && wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo \
    && yum install -y stress
[root@k8s-m1 docker]# docker build -t nginx:stress .
#查看docker run关于cpu的参数
See 'docker run --help'.
[root@k8s-m1 docker]# docker run --help|grep cpu
      --cpu-period int                 Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int                  Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int              Limit CPU real-time period in microseconds
      --cpu-rt-runtime int             Limit CPU real-time runtime in microseconds
  -c, --cpu-shares int                 CPU shares (relative weight)
      --cpus decimal                   Number of CPUs
      --cpuset-cpus string             CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string             MEMs in which to allow execution (0-3, 0,1)

解析:

选项描述
–cpu-period指定CPU CFS调度程序周期,该周期与–cpu-quota一起使用。默认为100000微妙,以微秒表示。大多数用户不会从默认值更改此设置。如果您使用Docker 1.13或更高版本,建议使用–cpus。
–cpu-quota在容器上添加CPU CFS配额。每个–cpu-period允许CPU访问的容器数微秒数。换句话说,cpu-quota / cpu-period。如果您使用Docker 1.13或更高版本,请改用–cpus。
–cpu-rt-period指定CPU实时周期(微秒)
–cpu-rt-runtime指定CPU实时周期(微秒),CPU动态调度是内核的高级功能,一般不需要更改这些值,如果配置不当,可能使主机系统将变得不稳定或者无法使用。该功能默认未开启,具体怎么使用请自行查阅。
-c,–cpu-shares将此标志设置为大于或小于默认值1024的值,以增加或减少容器的重量,并使其能够访问主机CPU周期的更大或更小比例。这仅在CPU周期受到限制时才会执行。当大量CPU周期可用时,所有容器都使用尽可能多的CPU。这样,这是一个软限制。–cpu-shares不会阻止容器在群集模式下进行调度。它优先考虑容器CPU资源的可用CPU周期。它不保证或保留任何特定的CPU访问权限。
–cpus指定容器可以使用多少可用CPU资源。例如,如果主机有两个CPU,并且您设置了–cpus =“1.5”,那么该容器将保证最多可以访问一个半的CPU。这相当于设置–cpu-period =“100000”和–cpu-quota =“150000”。在Docker 1.13和更高版本中可用。
–cpuset-cpus限制容器可以使用的特定CPU或核心。如果有多个CPU,则容器可以使用的逗号分隔列表或连字符分隔的CPU范围。第一个CPU编号为0.设置为0-3(表示使用第一,第二,第三和第四个CPU)或1,3(表示使用第二个和第四个CPU)。
–cpuset-mems通过cpuset-mems设置NUMA架构的CPU的内存使用。很少使用

2、限制可用的cpu个数

1)通过–cpu-period和–cpu-quota 配合限制

[root@k8s-m1 ~]# docker run -it  --cpu-period=100000 --cpu-quota=150000 centos:stress  /bin/bash
[root@a482506a9cdd /]# stress -c 2 &
[1] 17
[root@a482506a9cdd /]# stress: info: [17] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
[root@a482506a9cdd /]# top 
top - 08:38:21 up 1 day,  5:40,  0 users,  load average: 0.56, 0.72, 1.14
Tasks:   5 total,   3 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s): 10.5 us,  0.8 sy,  0.0 ni, 88.2 id,  0.4 wa,  0.0 hi,  0.1 si,  0.0 st
KiB Mem :  8007188 total,   473880 free,  2134940 used,  5398368 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  5308112 avail Mem 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                             
   19 root      20   0    7312     96      0 R  75.1  0.0   0:08.04 stress                                                                                                                              
   18 root      20   0    7312     96      0 R  74.8  0.0   0:08.06 stress                                                                                                                              
    1 root      20   0   11828   1936   1524 S   0.0  0.0   0:00.08 bash                                                                                                                                
   17 root      20   0    7312    424    344 S   0.0  0.0   0:00.00 stress                                                                                                                              
   21 root      20   0   56188   2040   1440 R   0.0  0.0   0:00.01 top   
#可以观察到cpu的使用率加起来在150%左右
##相应的配置也可查看
[root@a482506a9cdd /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 
100000
[root@a482506a9cdd /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us  
150000
补充:可以看到,如果我们如果找到本地的关于cpu配置的文件,是可以实现手动修改文件对CPU进行限制
本地对应文件:
以4c5ee0e0bae0为例:
[root@k8s-m1 system.slice]# docker ps -a|grep stres
4c5ee0e0bae0   centos:stress                                       "/bin/bash"              26 minutes ago       Up 15 minutes                              cpu4
[root@k8s-m1 system.slice]# find /sys/fs/cgroup/ -name *4c5ee0e0bae0*
/sys/fs/cgroup/perf_event/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/freezer/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/memory/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/pids/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/blkio/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/cpuset/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/devices/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/hugetlb/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/cpu,cpuacct/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/net_cls,net_prio/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
/sys/fs/cgroup/systemd/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope
如修改绑定使用的cpu
[root@k8s-m1 system.slice]# echo 3 > /sys/fs/cgroup/cpuset/system.slice/docker-4c5ee0e0bae09c3eb4ffe99b4583410d42a645298edfc544f80cbd5ca471f4a6.scope/cpuset.cpus
##注意只能能echo,不能通过vi打开修改。

2)通过–cpu限制

在 docker 1.13 及更高的版本上,能够更方便限制容器可以使用的宿主机 CPU的个数。只需要通过 --cpus 选项可用很简单设定容器可以使用的 CPU 个数,并且可以设定如1.5 之类的小数。

[root@k8s-m1 docker]# docker run -it --cpus=1.5  centos:stress  /bin/bash
##-c 用于指定进程数,不宜太多,太多使用率分散了不好观察
[root@333169612fe9 /]# stress -c 2 &
[1] 17
[root@333169612fe9 /]# stress: info: [17] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
[root@333169612fe9 /]# top
top - 07:30:18 up 1 day,  4:32,  0 users,  load average: 2.73, 1.97, 2.04
Tasks:   6 total,   3 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s): 10.2 us,  0.8 sy,  0.0 ni, 88.2 id,  0.7 wa,  0.0 hi,  0.1 si,  0.0 st
KiB Mem :  8007188 total,   810564 free,  2058384 used,  5138240 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  5400800 avail Mem 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                             
   28 root      20   0    7312    128     32 R  75.7  0.0   2:24.65 stress                                                                                                                              
   29 root      20   0    7312    128     32 R  75.0  0.0   2:24.07 stress                                                                                                                              
   30 root      20   0   56188   2044   1440 R   0.3  0.0   0:00.10 top                                                                                                                                 
    1 root      20   0   11828   1656   1380 S   0.0  0.0   0:00.06 bash                                                                                                                                
   14 root      20   0   11828   1884   1484 S   0.0  0.0   0:00.05 bash                                                                                                                                
   27 root      20   0    7312    424    344 S   0.0  0.0   0:00.00 stress 
#可以观察到cpu的使用率加起来在150%左右

或者新重新打开一个窗口,使用docker stats container_id 查看。

[root@k8s-m1 ~]# docker stats 333
CONTAINER ID   NAME                CPU %     MEM USAGE / LIMIT     MEM %     NET I/O   BLOCK I/O   PIDS
333169612fe9   ecstatic_poincare   148.90%   1.512MiB / 7.636GiB   0.02%     0B / 0B   0B / 0B     6
CONTAINER ID   NAME                CPU %     MEM USAGE / LIMIT     MEM %     NET I/O   BLOCK I/O   PIDS
333169612fe9   ecstatic_poincare   154.73%   1.512MiB / 7.636GiB   0.02%     0B / 0B   0B / 0B     6
CONTAINER ID   NAME                CPU %     MEM USAGE / LIMIT     MEM %     NET I/O   BLOCK I/O   PIDS
333169612fe9   ecstatic_poincare   154.73%   1.512MiB / 7.636GiB   0.02%     0B / 0B   0B / 0B     6
#看起来更直观,大概就在150%左右
#直接在宿主机执行top
[root@k8s-m1 ~]# top
top - 15:36:10 up 1 day,  4:38,  2 users,  load average: 1.87, 1.89, 1.99
Tasks: 280 total,   3 running, 277 sleeping,   0 stopped,   0 zombie
%Cpu(s):  9.9 us,  0.9 sy,  0.0 ni, 88.4 id,  0.6 wa,  0.0 hi,  0.1 si,  0.0 st
KiB Mem :  8007188 total,   803368 free,  1928904 used,  5274916 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  5395364 avail Mem 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                             
31017 root      20   0    7312    128     32 R  77.2  0.0   6:27.71 stress                                                                                                                              
31018 root      20   0    7312    128     32 R  76.9  0.0   6:24.28 stress                                                                                                                              
 1942 root      20   0 1442696 669188  43032 S  28.9  8.4  29:46.87 kube-apiserver                                                                                                                      
 5680 root      20   0   10.4g 251560  36268 S  16.9  3.1 107:35.39 etcd                 

容器 CPU 的负载为 150%,它的含义为单个 CPU 负载的1.5倍。我们也可以把它理解为有1.5个 CPU 的100%时间都在为它工作。我们通过 top 命令也看到主机 CPU 的真实负载情况,总共16核的服务器,我们设置使用了1.5个CPU,大概就在10%左右,所以id 大概就在90%左右(上面显示的88.4%)。后面150%也是大致平均分在两个cpu上,而不是一个100%+另一个50%。看来所以对于进程来说是没有 CPU个数这一概念的,内核只能通过进程消耗的 CPU 时间片来统计出进程占用 CPU 的百分比。这也是我们看到的各种工具中都使用百分比来说明CPU 使用率的原因。

可以参考docker 的官方文档中https://docs.docker.com/config/containers/resource_constraints/#configure-the-default-cfs-scheduler是如何解释 --cpus 选项的:
Specify how much of the available CPU resources a container can use.

可以看到官方用的是 “how much”,不可数的,而不是how many。并且 --cpus 选项支持设为小数也从侧面说明了对 CPU 的计量只能是百分比。
那么我们为什么还要使用“CPU 个数”这种说法呢?当然是为了更好理解。有兴趣的同学可以读读 --cpus 选项的由来,看看人家对CPU 个数解释。

使用 --cpu-period 即可设置调度周期,使用 --cpu-quota 即可设置在每个周期内容器能使用的CPU时间。两者可以配合使用。
–cpu-period 的数值范围是 1000 ~1000000 (单位微秒)。默认值为100000微秒,即100ms。而容器的–cpu-quota(CPU配额)必须不小于1ms,即 --cpu-quota 的值必须 >= 1000。默认情况下–cpu-quota的值为-1,表示不进行控制。

3、限制CPU相对份额(按比例共享)

由于我的服务器CPU个数比较多,不绑定cpu的话看不到效果,所以我单独指定容器都使用某个CPU。

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

默认情况下,每个Docker容器的CPU份额都是1024,单独一个容器的份额是没有意义的,只有在同时运行多个容器时且需要使用CPU资源时,并且CUP资源比较紧缺的时候,容器CPU的加权效果才能体现出来。比如下面的两个容器–cpu-shares比是1:2,在CPU进行时间片分配时,后者比前者多一倍的机会获得CPU的时间片,但是分配的结果取决于当时主机和其他容器的运行状态。实际上也无法保证该容器一定获得相应的CPU时间片,因为若是cpu2没有进程需要大量使用CPU,那么cpu1也会获取比cpu2更多的CPU时间片。

在极端情况下,例如主机上只运行了一个容器,即使它的CPU份额很小,它也是可以独占整个主机的CPU资源的,因为没有其他容器需要共享CPU。Cgroups只有在容器分配的资源紧缺时,即在需要对容器使用的资源进行限制时,才会生效,因此,无法根据某个容器的CPU份额来确定有多少CPU资源分给给它。

#先运行一个容器,绑定到第一个CPU,份额为默认的1024
[root@k8s-m1 ~]# docker run -it --name cpu1 --cpuset-cpus 0  --cpu-shares 1024 centos:stress /bin/bash
[root@0db26ce9c22a /]# stress -c 2 &
[1] 15
[root@0db26ce9c22a /]# stress: info: [15] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
[root@0db26ce9c22a /]# top
top - 01:09:23 up 1 day, 22:11,  0 users,  load average: 4.26, 3.29, 1.80
Tasks:   5 total,   3 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  7.2 us,  0.7 sy,  0.0 ni, 91.4 id,  0.6 wa,  0.0 hi,  0.1 si,  0.0 st
KiB Mem :  8007188 total,   293740 free,  2166228 used,  5547220 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  5259252 avail Mem 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                               
   16 root      20   0    7312     96      0 R  16.6  0.0   0:22.88 stress                                                                
   17 root      20   0    7312     96      0 R  16.6  0.0   0:22.88 stress                                                                
    1 root      20   0   11828   1932   1520 S   0.0  0.0   0:00.05 bash                                                                  
   15 root      20   0    7312    424    344 S   0.0  0.0   0:00.00 stress                                                                
   18 root      20   0   56208   2012   1440 R   0.0  0.0   0:00.07 top                                                                   
##第二个容器,也绑定到第一个CPU,份额设置为2028
[root@k8s-m1 cpu]# docker run -it --name cpu2 --cpuset-cpus 0 --cpu-shares 2048 centos:stress /bin/bash
[root@d33d2add52a9 /]# 
[root@d33d2add52a9 /]# 
[root@d33d2add52a9 /]# 
[root@d33d2add52a9 /]# stress -c 2 &
[1] 14
[root@d33d2add52a9 /]# stress: info: [14] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
[root@d33d2add52a9 /]# top
top - 01:07:55 up 1 day, 22:10,  0 users,  load average: 4.04, 2.92, 1.54
Tasks:   5 total,   3 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  7.4 us,  0.7 sy,  0.0 ni, 90.7 id,  1.2 wa,  0.0 hi,  0.1 si,  0.0 st
KiB Mem :  8007188 total,   313908 free,  2146436 used,  5546844 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  5279044 avail Mem 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                               
   15 root      20   0    7312     96      0 R  33.2  0.0   0:50.25 stress                                                                
   16 root      20   0    7312     96      0 R  33.2  0.0   0:50.26 stress                                                                
    1 root      20   0   11828   1936   1524 S   0.0  0.0   0:00.06 bash                                                                  
   14 root      20   0    7312    424    344 S   0.0  0.0   0:00.00 stress                                                                
   18 root      20   0   56208   2012   1440 R   0.0  0.0   0:00.01 top

通过上面两个容器对第一个CPU的占用情况可以发现大致比例就为1:2 。满足我们的预期。

4、绑定容器使用指定的CPU(如上)

四、内存资源配额

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

[root@k8s-m1 ~]# docker run -itd --name m12 -m 512m centos:7 /bin/bash
07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3
[root@k8s-m1 system.slice]# docker stats  07
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O   BLOCK I/O   PIDS
07d168a1ef04   m12       0.00%     388KiB / 512MiB     0.07%     0B / 0B   0B / 0B     1
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O   BLOCK I/O   PIDS
07d168a1ef04   m12       0.00%     388KiB / 512MiB     0.07%     0B / 0B   0B / 0B     1
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O   BLOCK I/O   PIDS
对应的cgroup配置文件查找,这些目录下就是当前容器的具体配置,可自行查看。
[root@k8s-m1 cgroup]# pwd
/sys/fs/cgroup
[root@k8s-m1 cgroup]# find . -name *07d168a1*
./perf_event/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./freezer/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./memory/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./pids/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./blkio/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./cpuset/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./devices/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./hugetlb/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./cpu,cpuacct/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./net_cls,net_prio/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
./systemd/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope
[root@k8s-m1 cgroup]# cat ./memory/system.slice/docker-07d168a1ef044e097e87d412e74d1544009f7b393455a6b319bfd93bfd5612b3.scope/memory.limit_in_bytes 
536870912
##536870912即为512M(512M=512*1024K=512*1024*1024B)

2、 限制容器可以使用的最大swap

需要注意以下几点:

五、磁盘IO的资源配额

1、对读写权重进行限制

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

[root@1623b417c1b0 /]# stressrun -it --name blkio1  --blkio-weight 500 centos:stress 
#容器内对应的配置文件,对应在宿主机上的配置文件通过上面的方法查看。
[root@83fca2f7ddef /]# cat /sys/fs/cgroup/blkio/blkio.weight
500
[root@83fca2f7ddef /]# stress --hdd 2 --hdd-bytes 1G --backoff 2000000
stress: info: [14] dispatching hogs: 0 cpu, 0 io, 0 vm, 2 hdd
#开启新的窗口
[root@k8s-m1 ~]# docker run -it --name blkio2  --blkio-weight 1000 centos:stress 
[root@1dcf72b08f88 /]# stress --hdd 2 --hdd-bytes 1G --backoff 2000000
stress: info: [14] dispatching hogs: 0 cpu, 0 io, 0 vm, 2 hdd
#开启另一个窗口
[root@k8s-m1 cpu]# docker stats 83 1dc
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O   BLOCK I/O     PIDS
83fca2f7ddef   blkio1    0.03%     7.184MiB / 7.636GiB   0.09%     0B / 0B   1.98MB / 0B   4
1dcf72b08f88   blkio2    87.41%    7.965MiB / 7.636GiB   0.10%     0B / 0B   3.65MB / 0B   4
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O   BLOCK I/O     PIDS
通过block I/O可以发现速度比例大概就为1:2

2、具体对读写速度的限制

参数作用
–device-read-bpsbyte per second,限制某个设备每秒读的数据量
–device-write-bpsbyte per second, 限制某个设备每秒写的数据量
–device-read-iopsio per second,限制某个设备每秒读IO的次数
–device-write-iopsio per second,限制某个设备每秒写IO的次数

下面的示例是限制容器写/dev/sda的速率为5MB/s,注意此次的/dev/sda是宿主机上的磁盘。具体写什么看你服务器的磁盘规划。
作为对比,先运行一个没有速度限制的容器:

[root@k8s-m1 cgroup]#  docker run -it --name io1 centos:7   /bin/bash
[root@6be94b7b1ab5 /]# dd if=/dev/zero of=/opt/test.out bs=10M count=3 
3+0 records in
3+0 records out
31457280 bytes (31 MB) copied, 0.035242 s, 893 MB/s
#添加oflag参数以规避掉文件系统cache。可以看到生产一个30M的文件花了0.035242 s,速度很快。
[root@k8s-m1 cgrou docker run -it --name io2 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
[root@b84241970c32 /]# dd if=/dev/zero of=/opt/test.out bs=10M count=3  oflag=direct
3+0 records in
3+0 records out
31457280 bytes (31 MB) copied, 30.0261 s, 1.0 MB/s
[root@b84241970c32 /]# 
重新运行一个速度限制为1M的容器,生成一个30M的文件化花了30.0261 s,速度大概就是1M/s。

通过上面的对比,发现设置的参数生效,其他参数请在具体场景中测试使用。

到此这篇关于Docker中Cgroup资源配置的实现的文章就介绍到这了,更多相关Docker Cgroup资源配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文