Docker---資源控制之cgroups

一.cgroup的簡介

cgroups概念

  • cgroups(Control groups)是linux內核提供的一種機制,這種機制可以根據需求把一系列的系統任務以及子系統任務整合(或者分隔)到資源劃分等級的不同的組內,從而爲系統資源管理提供了一個統一的框架。
  • 簡單來說,cgroups可以限制、記錄任務組所使用的物理資源,本質上來說,cgroups是內核附加在程序上的一系列鉤子(hook),通過程序運行時對資源的調度觸發相應的鉤子以達到資源追蹤和限制的目的。
  • 在以容器技術爲代表的虛擬化技術大行其道的時代下,瞭解cgroups技術是很有必要的!比如我們可以很方便的限制某個容器可以使用的cpu、內存等資源。

cgroups的作用

  • 實現cgroups的主要目的是爲了不同用戶層面的資源管理提供一個統一化的接口。
  • 從單個任務資源控制到操作系統層面的虛擬化,cgroups提供了四大功能:

資源限制:cgroups可以對任務要的資源總額進行限制。比如設定任務運行時使用的內存上限,一旦超出就發OOM。

優先級分配:通過分配的cpu時間片數量和磁盤IO帶寬,實際上就等同於控制了任務運行的優先級。

資源統計:cgroups可以統計系統的資源使用量,比如cpu的使用時長,內存用量等。這個功能非常合適當前雲端產品按使用量計費的方式。

任務控制:cgroups可以對任務執行掛起、恢復等操作

相關概念

  • Task(任務):在linux系統中,內核本身的調度和管理並不對進程和線程進行區分,只是根據clone時傳入的參數的不同來從概念上區分進程和線程。
  • Cgroups(控制組):cgroups中的資源控制以cgroup爲單位實現。cgroup表示按照某種資源控制標準劃分而成的任務組,包含一個或者多個子系統。一個任務可以加入某個cgroup,也可以從某個cgroup遷移到另外一個cgroup。
  • Subsystem(子系統):cgroups中的子系統就是一個資源調度控制器(又叫作controllers)。比如cpu子系統可以控制cpu的時間分配,內存子系統可以限制內存的使用量
[root@cloud ~]# cat /proc/cgroups
#subsys_name	hierarchy	num_cgroups	enabled
cpuset	8	2	1        ##給cgroup中的任務分配獨立的cpu資源報告,與cpu掛載在同一目錄
cpu	4	52	1            ##cpu限制cpu時間片的分配,與cpuset掛載在同一目錄
cpuacct	4	52	1        ##生成cgroup中的任務佔用cpu資源的報告,與cpu掛載在同一個目錄
memory	3	52	1        ##對cgroup中任務的可用內存進行限制,並且自動生成資源佔用報告
devices	6	52	1        ##允許或者禁止cgroup中的任務訪問設備
freezer	10	2	1        ##暫停/恢復cgroup中的任務
net_cls	5	2	1        ##使用等級識別符(classid)標記網絡數據包,這讓Linux流量控制器(tc指令)可以識別來自特定cgroup任務的數據包,並且進行網絡限制
blkio	9	52	1        ##對塊設備的IO進行限制
perf_event	11	2	1    ##允許使用perf工具來監控cgroup
hugetlb	2	2	1
pids	7	52	1        ##限制任務的數量
net_prio	5	2	1
[root@cloud ~]# 
  • Hierachy(層級):層級有一系列的cgroup以一個樹狀結構排列而成,每個層級通過綁定對應的子系統進行資源控制。層級中的cgroup節點可以包含0個或者多個子節點,子節點繼承父節點掛載的子系統。一個操作系統中可以有多個層級

cgroups的文件系統接口

  • cgroups以文件的方式提供應用接口,我們可以通過mount命令來查看cgroups默認的掛載點
[root@cloud ~]# mount | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
[root@cloud ~]# 
//第一行的tmpfs說明/sys/fs/cgroup 目錄下的文件都是存在於內存中的臨時文件。
//第二行的掛載點/sys/fscgroup/systemd用於systemd系統對cgroups的支持
//其餘掛載點則是內核支持的各個子系統的根級層級結構

systemd依賴於cgroups:要理解systemd與cgroups的關係,我們需要先區分cgroups的兩個方面:層級結構(A)和資源控制(B)。首先cgroups是以層級結構組織並且標識進程的一種方式,同時它也是在該層級結構上執行資源限制的一種方式。我們簡單的把cgroups的層級結構稱爲A,把cgroups的資源控制能力稱爲B。

對於systemd來說,層級結構是必須的,如果沒有層級結構,systemd將不能很好的工作。而資源限制則是可選的,如果你不需要對資源進行控制,那麼在編譯Linux內核時完全可以去掉B相關的編譯選項。

以下都是對cgroup的資源限制的相關操作。

二.stress工具測試容器cpu和內存

  • stress是用來測試cpu內存的負載,通過在兩個容器分別執行stress -c 1,這將會給系統一個隨機負載,產生一個進程,這個進程會反覆不停地計算由rand()產生地隨機數的平方根,直到資源耗盡。
  • 首先使用Dockerfile創建一個基於centos的stress的工具鏡像
[root@cloud ~]# ls
stress
[root@cloud ~]# cd stress/
[root@cloud stress]# cat Dockerfile 
FROM centos
MAINTAINER this is stress images
RUN yum install -y wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum install -y stress
[root@cloud stress]# docker build -t centos:stress .
Successfully built f188ad991193
Successfully tagged centos:stress
[root@cloud stress]# 


[root@cloud stress]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              stress              f188ad991193        20 seconds ago      342MB
centos              latest              470671670cac        2 months ago        237MB
[root@cloud stress]# 

三cpu的權重限制

  • 默認情況下,每個docker容器的cpu份額都是1024,單獨一個容器的份額是沒有意義的,只有在同時運行多個容器時,容器cpu的加權效果才能體現出現。
  • 例如,兩個容器A、B的cpu份額分別爲1000和500,在cpu進行時間片分配的時候,容器A比容器B多一倍的機會獲得cpu的時間片,但是分配的結果取決於當時主機和其他容器的運行狀態,實際上也無法保證容器A一定能夠獲得cpu的時間片。比如容器A的進程一直是空閒的,那麼容器B是可以獲取比容器A更多的cpu時間片的,極端情況下,例如主機上只運行的一個容器,即使它的cpu份額只有50,它也可以獨佔整個主機的cpu資源
  • cgroups只在容器分配的資源緊缺時,即需要對容器使用的資源進行限制時,纔會生效。因此,無法單純的根據某個容器的份額的cpu份額來確定有多少cpu資源分配給它,可以通過cpu share參數可以設置容器使用cpu的優先級,比如啓動了兩個容器及運行查看cpu的cpu的使用百分比
  • 具體操作如下:
##創建兩個容器
##--cpu-shares 指定使用cpu的權重
##stress -c 指定產生子進程
[root@cloud ~]# docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10
e1d1bbd21244d7c0649da898039c6c64a5ebdf7a14d80f261edd258bf4936b27
[root@cloud ~]# docker run -itd --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10
c1e7da9144d2c2428ee95b122d5dadcc587739c6da68c8caf797e1698fc1cce1
[root@cloud ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
c1e7da9144d2        centos:stress       "stress -c 10"      About a minute ago   Up 58 seconds                           cpu1024
e1d1bbd21244        centos:stress       "stress -c 10"      2 minutes ago        Up 2 minutes                            cpu512
[root@cloud ~]# 

##進入容器使用top命令查看cpu的使用率
[root@cloud ~]# docker exec -it cpu512 bash
[root@e1d1bbd21244 /]# top
top - 01:19:55 up 11 days, 19:17,  0 users,  load average: 20.58, 12.94, 5.65
Tasks:  13 total,  11 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu0  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3789.2 total,   1879.2 free,    227.2 used,   1682.8 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   3308.7 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                  
   11 root      20   0    7936     96      0 R  11.0   0.0   0:29.73 stress                                   
   12 root      20   0    7936     96      0 R   7.3   0.0   0:29.56 stress                                   
    7 root      20   0    7936     96      0 R   6.0   0.0   0:29.63 stress                                   
    9 root      20   0    7936     96      0 R   6.0   0.0   0:30.65 stress                                   
   13 root      20   0    7936     96      0 R   5.7   0.0   0:29.82 stress                                   
   15 root      20   0    7936     96      0 R   5.7   0.0   0:29.51 stress                                   
    8 root      20   0    7936     96      0 R   5.3   0.0   0:30.71 stress                                   
   10 root      20   0    7936     96      0 R   5.3   0.0   0:29.16 stress                                   
   14 root      20   0    7936     96      0 R   5.3   0.0   0:30.44 stress                                   
   16 root      20   0    7936     96      0 R   5.3   0.0   0:29.88 stress                                   
    1 root      20   0    7936    712    616 S   0.0   0.0   0:00.02 stress                                   
   17 root      20   0   12012   2060   1552 S   0.0   0.1   0:00.02 bash                                     
   30 root      20   0   48404   2104   1500 R   0.0   0.1   0:00.00 top                                      
[root@e1d1bbd21244 /]# exit
exit
[root@cloud ~]# docker exec -it cpu1024 bash
[root@c1e7da9144d2 /]# top
top - 01:20:18 up 11 days, 19:17,  0 users,  load average: 20.44, 13.52, 6.04
Tasks:  13 total,  11 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.8 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
MiB Mem :   3789.2 total,   1878.5 free,    227.8 used,   1682.9 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   3308.0 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                  
   12 root      20   0    7936     92      0 R  18.6   0.0   0:38.73 stress                                   
   14 root      20   0    7936     92      0 R  18.3   0.0   0:37.74 stress                                   
    7 root      20   0    7936     92      0 R  14.3   0.0   0:39.03 stress                                   
    9 root      20   0    7936     92      0 R  12.3   0.0   0:37.71 stress                                   
   13 root      20   0    7936     92      0 R  12.3   0.0   0:38.96 stress                                   
   10 root      20   0    7936     92      0 R  12.0   0.0   0:38.53 stress                                   
   11 root      20   0    7936     92      0 R  12.0   0.0   0:39.82 stress                                   
   15 root      20   0    7936     92      0 R  11.6   0.0   0:38.18 stress                                   
    8 root      20   0    7936     92      0 R  11.3   0.0   0:37.46 stress                                   
    6 root      20   0    7936     92      0 R  11.0   0.0   0:39.00 stress                                   
    1 root      20   0    7936    708    616 S   0.0   0.0   0:00.01 stress                                   
   16 root      20   0   12012   2076   1552 S   0.0   0.1   0:00.02 bash                                     
   29 root      20   0   48404   2104   1500 R   0.0   0.1   0:00.00 top                                      



##分別進入cpu512和cpu1024之後可以看到,%cpu的比例差不多是1:2
##符合我們設置的--cpu-shares參數

 

四.cpu週期限制

  • Docker提供了 --cpu-period、--cpu-quota兩個參數控制容器可以分配到cpu的時鐘週期。
  • --cpu-period是用來指定容器對於cpu的使用要在多長時間內分配一次
  • --cpu-quota是用來指定在這個週期內,最多可以有多少時間跑這個容器,與--cpu-shares(權重)不同的是,這種配置指定一個絕對值,容器對cpu資源使用絕對不會超過配置的值。
  • cpu-period和cpu-quota的單位爲微秒。cpu-period的最小值爲1000微秒(0.001秒),最大值爲1秒(1000000微秒),默認爲0.1秒(100000微秒)
  • cpu-quota的值默認爲-1,表示不做控制。cpu-peiod和cpu-quota參數一般聯合使用。
  • 例如:容器進程需要每一秒鐘使用單個cpu的0.2時間,可以將 --cpu-period設置爲1000000(1秒),--cpu-quota設置爲200000(0.2秒)。
  • 當然。在多核情況下,如果允許容器進程完全佔用兩個cpu,則可以將cpu-period設置爲100000(0.1秒),cpu-quota設置爲200000(0.2秒)
  • 具體操作如下

 

##查看系統的cpu具體情況
[root@cloud ~]# top
top - 15:13:16 up  4:57,  1 user,  load average: 0.06, 0.06, 0.05
Tasks:  79 total,   2 running,  77 sleeping,   0 stopped,   0 zombie
%Cpu0  :  1.1 us,  0.0 sy,  0.0 ni, 98.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  1.1 us,  0.0 sy,  0.0 ni, 98.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3880172 total,  3274484 free,   187132 used,   418556 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  3476152 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND           
 1069 root      10 -10  123944  11424   8768 S   2.2  0.3   3:06.32 AliYunDun         
    1 root      20   0   43548   3908   2604 S   0.0  0.1   0:01.25 systemd           
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kthreadd          
    4 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H      
    5 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kworker/u4:0      
    6 root      20   0       0      0      0 S   0.0  0.0   0:00.02 ksoftirqd/0       
    7 root      rt   0       0      0      0 S   0.0  0.0   0:00.00 migration/0       
    8 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcu_bh            
    9 root      20   0       0      0      0 S   0.0  0.0   0:01.45 rcu_sched         
   10 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 lru-add-drain     
   11 root      rt   0       0      0      0 S   0.0  0.0   0:00.05 watchdog/0        
   12 root      rt   0       0      0      0 S   0.0  0.0   0:00.06 watchdog/1        
   13 root      rt   0       0      0      0 S   0.0  0.0   0:00.05 migration/1       
   14 root      20   0       0      0      0 S   0.0  0.0   0:00.00 ksoftirqd/1       
   16 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/1:0H      
   18 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kdevtmpfs         
[root@cloud ~]# 
##下列命令表示每0.1秒切換一次,使用時間爲0.2秒
[root@cloud ~]# docker run -itd --cpu-period 100000 --cpu-quota 200000 centos:stress 
155ce9a00a69672c47082c2650b2bdafa2a4feaab611bf32b6bbdde3083efafa
[root@cloud ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
155ce9a00a69        centos:stress       "/bin/bash"         4 seconds ago       Up 4 seconds                            inspiring_williamson
[root@cloud ~]# docker exec -it 155ce9a00a69 bash
[root@155ce9a00a69 /]# cd /sys/fs/cgroup/cpu             
[root@155ce9a00a69 cpu]# ls
cgroup.clone_children  cpu.cfs_period_us  cpu.rt_runtime_us  cpuacct.stat	   notify_on_release
cgroup.event_control   cpu.cfs_quota_us   cpu.shares	     cpuacct.usage	   tasks
cgroup.procs	       cpu.rt_period_us   cpu.stat	     cpuacct.usage_percpu
[root@155ce9a00a69 cpu]# cat cpu.cfs_quota_us 
200000
[root@155ce9a00a69 cpu]# cat cpu.cfs_period_us
100000
[root@155ce9a00a69 cpu]# 

 

五.cpu core控制

  • 對於多核cpu的服務器,docker還可以控制容器運行使用哪些cpu內核,以及使用--cpuset-cpus參數,這對於具有多cpu服務器尤其有用,可以對需要高性能計算的容器進行性能最優的配置。
//執行以下命令需要宿主機爲雙核,表示創建的容器只能使用0、1兩個內核,最終生成cgroup的cpu內核配置如下:
[root@cloud ~]# docker run -itd --name cpu1 --cpuset-cpus 0-1 centos:stress 
6805394fd83bf79fd4b7b7bf854a654f10a464ea2e4a27f01f0ce81e93c3d06a
[root@cloud ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6805394fd83b        centos:stress       "/bin/bash"         6 seconds ago       Up 5 seconds                            cpu1
[root@cloud ~]# docker exec -it cpu1 bash
[root@6805394fd83b /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-1
[root@6805394fd83b /]# 

//通過下列指令可以看到容器中進程與cpu內核的綁定關係,達到綁定cpu內核的目的
//容器內部的第一個進程號pid爲1,被綁定到指定到的cpu上運行
[root@cloud ~]# docker exec 6805394fd83b taskset -c -p 1
pid 1's current affinity list: 0,1
[root@cloud ~]# 

 

六.cpu配額控制參數混合使用

  • 通過cpuset-cpus參數指定容器A使用cpu內核0,容器B使用cpu內核1。
  • 在主機上只有這個兩個容器使用對應的cpu內核情況,它們各自佔用全部的內核資源,cpu-shares沒有明顯的效果。
  • cpuset-cpus、cpuset-mems參數只在多核、內存節點上服務器有效,並且必須與實際的物理配置匹配,否則也無法達到資源控制的目的。
  • 在系統具有多個cpu內核的情況下,需要通過cpuset-cpus參數爲設置容器cpu內核才能方便進行測試
  • 具體測試如下
##宿主機系統修改爲4核心
[root@192 ~]# top
top - 17:23:32 up  1:03,  1 user,  load average: 0.00, 0.01, 0.05
Tasks: 159 total,   2 running, 157 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   999720 total,   149312 free,   307964 used,   542444 buff/cache
KiB Swap:  2095100 total,  2079800 free,    15300 used.   443268 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND              
  2650 root      20   0  533232  32332   7028 S   1.8  3.2   0:59.00 containerd           
   618 root      20   0  305296   2616   1964 S   0.9  0.3   0:05.93 vmtoolsd             
     1 root      20   0   46152   5480   2848 S   0.0  0.5   0:06.06 systemd              
     2 root      20   0       0      0      0 S   0.0  0.0   0:00.01 kthreadd             
     3 root      20   0       0      0      0 S   0.0  0.0   0:00.15 ksoftirqd/0          
     5 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H         
     7 root      rt   0       0      0      0 S   0.0  0.0   0:00.42 migration/0          
     8 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcu_bh               
     9 root      20   0       0      0      0 S   0.0  0.0   0:02.19 rcu_sched            
    10 root      rt   0       0      0      0 S   0.0  0.0   0:00.02 watchdog/0           
    11 root      rt   0       0      0      0 S   0.0  0.0   0:00.02 watchdog/1           
    12 root      rt   0       0      0      0 S   0.0  0.0   0:00.38 migration/1          
    13 root      20   0       0      0      0 S   0.0  0.0   0:00.14 ksoftirqd/1          
    15 root       0 -20       0      0      0 S   0.0  0.0   0:00.05 kworker/1:0H         
[root@192 ~]# 

##創建容器,限制cpu資源
[root@192 ~]# docker run -itd --name cpu3 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1
3fcc1b1f7b08ef1f17102c6656de31e227f79d029c9d0411f230aecafb062422
[root@192 ~]# docker run -itd --name cpu4 --cpuset-cpus 3 --cpu-shares 1024 centos:stress stress -c 1
24c836b8b6d64020c439c973eb612e8a7dc945a9a0d6935e512b16e5be1f733b
[root@192 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
24c836b8b6d6        centos:stress       "stress -c 1"       6 seconds ago       Up 5 seconds                            cpu4
3fcc1b1f7b08        centos:stress       "stress -c 1"       55 seconds ago      Up 54 seconds                           cpu3
[root@192 ~]# 

##分別進入cpu3和cpu4查看cpu使用率,有下面數據可知,cpu1和3使用率達到了100%,權重對它們沒有影響
[root@192 ~]# docker exec -it cpu3 bash
[root@3fcc1b1f7b08 /]# top
top - 09:28:01 up  1:08,  0 users,  load average: 1.90, 0.93, 0.40
Tasks:   4 total,   2 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.6 sy,  0.0 ni, 99.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   999720 total,   136580 free,   442808 used,   420332 buff/cache
KiB Swap:  2095100 total,  2078428 free,    16672 used.   403724 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND              
     6 root      20   0    7312    100      0 R 100.0  0.0   3:27.48 stress               
     1 root      20   0    7312    428    344 S   0.0  0.0   0:00.08 stress               
     7 root      20   0   11828   1892   1492 S   0.0  0.2   0:00.03 bash                 
    20 root      20   0   56180   1948   1436 R   0.0  0.2   0:00.01 top                  

[root@3fcc1b1f7b08 /]# exit
[root@192 ~]# docker exec -it cpu4 bash
[root@24c836b8b6d6 /]# top
top - 09:28:31 up  1:08,  0 users,  load average: 1.94, 1.03, 0.45
Tasks:   4 total,   2 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   999720 total,   113200 free,   442472 used,   444048 buff/cache
KiB Swap:  2095100 total,  2078428 free,    16672 used.   404160 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND              
     6 root      20   0    7312    100      0 R 100.0  0.0   3:08.88 stress               
     1 root      20   0    7312    428    344 S   0.0  0.0   0:00.02 stress               
     7 root      20   0   11828   1896   1492 S   0.0  0.2   0:00.01 bash                 
    20 root      20   0   56180   1952   1436 R   0.0  0.2   0:00.00 top                  

[root@24c836b8b6d6 /]# exit

 

七.內存限制

  • 容器與操作系統類似,容器也可以使用物理內存和swap
  • 容器通過 -m或--memory設置內存的使用限額,例如:-m 300M;通過--memory-swap設置內存+swap的使用限制
  • 實例如下,允許容器最多使用200M的內存和300M的swap
docker run -itd -m 200M --memory-swap=300M centos --vm 1 --vm-bytes 280M

## --vm 1 ,代表啓動一個內存工作線程
## --vm-bytes 280 M ,代表每個線程可以分配280M內存
  • 默認情況下,容器可以使用主機上的所有空閒內存。
  • 上述配置與cpu的cgroup的配置類似,Docker會自動爲容器目錄/sys/fs/cgroup/memory/docker/<容器ID> ,中創建相應的cgroup的配置文件

注:如果分配的內存超過限額,stress線程就會報錯,容器會自動退出

 

八.Block IO的限制

  • 默認情況下,所有容器能夠平等的讀寫磁盤,可以通過設置--blkio-weight參數來改變容器block IO的優先級。
  • --blkio-weight與--cpu-shares類似,設置的是相對的權重值,默認爲500
  • 實例如下
[root@192 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@192 ~]# docker run -it --name container_A --blkio-weight 600 centos:stress 
[root@21278c0715c3 /]# cat /sys/fs/cgroup/blkio/blkio.weight
600
[root@21278c0715c3 /]# exit
exit
[root@192 ~]# docker run -it --name container_B --blkio-weight 300 centos:stress 
[root@e19785e9b978 /]# cat /sys/fs/cgroup/blkio/blkio.weight
300
[root@e19785e9b978 /]# 

 

九.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

  • 實例如下
##我們再第一臺容器上限制磁盤寫的上限是10MB/s
##通過dd命令測試在容器中寫磁盤的速度,因爲容器的文件系統實在 host /dev/sda 上的,
#在容器中寫文件相當於對host /dev/sda 進行寫操作,另外,oflag=direct IO的方式寫文件,
#這樣 --device-write-bps才能生效。

[root@192 ~]# docker run -it --device-write-bps /dev/sda:10MB centos:stress 
[root@2db327571e10 /]# dd if=/dev/zero of=test bs=1M count=1000 oflag=direct
^C57+0 records in
57+0 records out
59768832 bytes (60 MB) copied, 5.65425 s, 10.6 MB/s

##當我們不進行磁盤限速時,容器寫數據時佔用了大量的帶寬
##在生成環境中,我們需要對容器磁盤的寫速率限制,以便業務的高效化

[root@2db327571e10 /]# exit
exit
[root@192 ~]# docker run -it centos:stress 
[root@c0918c4ea1f2 /]# dd if=/dev/zero of=test bs=1M count=1000 oflag=direct
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 1.52004 s, 690 MB/s
[root@c0918c4ea1f2 /]# 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章