Docker——Cgroup資源限制

一、Cgroup

(1)Docker通過 Cgroup 來控制容器使用的資源配額,包括 CPU、內存、磁盤三大方面,基本覆蓋了常見的資源配額和使用量控制。

(2)Cgroup 是 Linux 內核提供的一種可以限制、記錄、隔離進程組所使用的物理資源的機制。

Cgroup 子系統:

1、blkio:設置限制每個塊設備的輸入輸出控制;
2、cpu:使用調度程序爲 cgroup 任務提供 cpu 的訪問;
3、cpuacct:產生 cgroup 任務的 cpu 資源報告;
4、cpuset:如果是多核心的 cpu,這個子系統會爲 cgroup 任務分配單獨的 cpu 和內存;
5、devices:允許或拒絕 cgroup 任務對設備的訪問;
6、freezer:暫停和恢復 cgroup 任務;
7、memory:設置每個 cgroup 的內存限制以及產生內存資源報告;
8、net_cls:標記每個網絡包以供 cgroup 方便使用;
9、ns:命名空間子系統;
10、perf_event:增加了對每個 cgroup 的監測跟蹤能力,可以監測屬於某個特定的 cgroup 的所有線程及運行在特定 CPU 上的線程。

二、使用 stress 工具測試 CPU 和內存

首先使用 Dockerfile 來創建一個基於 Centos 的 stress 的工具鏡像:

[root@localhost ~]# mkdir /opt/stress
[root@localhost ~]# cd /opt/stress/

[root@localhost stress]# vim Dockerfile
FROM centos:7
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@localhost stress]# docker build -t centos:stress .    //創建鏡像

(1)使用如下命令創建容器,命令中的 --cpu-shares 參數值不能保證可以獲得 1 個 vcpu 或者多少 GHz 的CPU 資源,它僅是一個彈性的加權值。

[root@localhost stress]# docker run -itd --cpu-shares 100 centos:stress
08a203033c051098fd6294cd8ba4e2fa8baa18cefb793c6c4cd655c0f28cabc0

注意:默認情況下,每個 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 使用百分比
1、

//容器產生10個子函數進程:
[root@localhost stress]# docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10
99086cce962308fdb5417df189571e39f375ab2c067887cbac48e773225f25c7

//進入容器再使用top命令查看cpu使用情況:
[root@localhost stress]# docker exec -it 99086cce9623 bash
[root@99086cce9623 /]# top
.. ..
.. ..
.. ..
.. ..
按 q 退出,
[root@99086cce9623 /]# exit        //退出整個容器

Docker——Cgroup資源限制
2、此時,我們可以再開啓另外一個容器做比較:

[root@localhost stress]# docker run -itd --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10
81e29988fce779c6b3e10fb8570ae2358db4090e1987202bb7919260287eca66

[root@localhost stress]# docker exec -it 81e29988fce7 bash
[root@81e29988fce7 /]# top
..
..
..

Docker——Cgroup資源限制
通過進入容器,觀察兩個容器的 %CPU,可以發現比例是 1:2

三、CPU 週期限制:

Docker 提供了 --cpu-period、–cpu-quota 兩個參數控制容器可以分配到的 CPU 時鐘週期。

–cpu-period :是用來指定容器對 CPU 的使用要在多長時間內做一次重新分配。
–cpu-quota :是用來指定在這個週期內,最多可以有多少時間用來跑這個容器。
與 --cpu-shares 不同的是。這種配置是指定一個絕對值,容器對 CPU 資源的使用絕對不會超過配置的值。
注意:
cpu-period 和 cpu-quota 的單位是微秒;
cpu-period 的最小值是1000微秒,最大值爲1秒,默認值爲0.1秒。
cpu-quota 的值默認是 -1 ,表示不做控制;
cpu-period 和 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秒)。

[root@localhost stress]# docker run -itd --cpu-period 100000 --cpu-quota 200000 centos:stress
3f2a577cf6a281347338cbf9734440b3b8a29e771dc4890a9f243eb0773f6c09

[root@localhost stress]# docker exec -it 3f2a577cf6a2 bash

[root@3f2a577cf6a2 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 
100000
[root@3f2a577cf6a2 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us  
200000

Docker——Cgroup資源限制

四、CPU Core 控制:

對於多核 CPU 的服務器,Docker 還可以控制容器運行使用哪些 CPU 內核,即使用 --cpuset-cpus 參數。這對具有多 CPU 的服務器尤其有用,可以對需要高性能計算的容器進行性能最優配置。

[root@localhost ~]# docker run -itd --name cpu02 --cpuset-cpus=0-2 centos:stress
76994f5d310de48ee635f69270f7c9b4cba1e65aad935ff1e0d6e098441104eb
//執行該命令(需要宿主機爲四核),表示創建的容器只能使用0、1、2 三個內核。 

[root@localhost ~]# docker exec -it 76994f5d310d bash    //進入容器
[root@76994f5d310d /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-2

Docker——Cgroup資源限制
通過下面指令可以看到容器中進程與 CPU 內核的綁定關係,達到 CPU 內核的目的:

[root@localhost ~]# docker exec 76994f5d310d taskset -c -p 1
pid 1's current affinity list: 0-2
//容器內部第一個進程號 pid爲1,被綁定到指定CPU上運行。

Docker——Cgroup資源限制

五、CPU 配額控制參數的混合使用:

通過 cpuset-cpus 參數指定容器 A 使用 CPU 內核 0,容器B 只是用 CPU 內核1;在主機上只有這兩個容器使用對應 CPU 內核的情況,它們各自佔有全部的內核資源,cpu-shares 沒有明顯效果。cpuset-cpus、cpuset-mems 參數只在多核、多內存節點上的服務器上有效,並且必須與實際的物理配置匹配,否則也無法達到資源控制的目的。在系統具有多個 CPU 內核的情況下,需要通過 cpuset-cpus 參數爲設置容器 CPU 內核才能方便地進行測試。

[root@localhost ~]# docker run -itd --name cpu3 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1
d6e122af832297a05b6993ea3146a2a62969557989933ac9f1bf59f2a1de5c50

[root@localhost ~]# docker exec -it d6e122af8322 bash
[root@d6e122af8322 /]# top  //top查看後,按1可以看到每個核心的佔用情況

Docker——Cgroup資源限制
我們再創建一個容器:

[root@localhost ~]# docker run -itd --name cpu4 --cpuset-cpus 3 --cpu-shares 1024 centos:stress stress -c 1
d375a1ba761a711d55a01d95c7a5d494e62f86d447d36422be666cacf6483ca1

[root@localhost ~]# docker exec -it d375a1ba761a bash
[root@d375a1ba761a /]# top

Docker——Cgroup資源限制

六、內存限額:

與操作系統類似,容器可使用的內存包括兩部分:物理內存 和 Swap;

docker 通過下面兩組參數來控制容器內存的使用量:

-m 或 --memory:設置內存的使用限額,例如 100M、1024M;
–memory-swap:設置內存 +swap 的使用限額。
例如:執行如下命令允許該容器最多使用 200M的內存,300M 的swap:

[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
// --vm 1:啓動1個內存工作線程;
   --vm-bytes 280M :每個線程分配280M內存;

如果讓工作線程分配的內存超過 300M,分配的內存超過限額,stress線程報錯,容器退出:
[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M

Docker——Cgroup資源限制

七:Block IO 的限制:

默認情況下,所有容器能平等地讀寫磁盤,可以通過設置 --blkio-weight 參數來改變容器 block IO 的優先級。

–blkio-weight 與 --cpu-shares 類似,設置的是相對權重值,默認爲500
在下面的例子中,容器 A 讀寫磁盤的帶寬是容器 B 的兩倍:

[root@localhost ~]# docker run -it --name container_A --blkio-weight 600 centos:stress
[root@0f9b8d716206 /]# cat /sys/fs/cgroup/blkio/blkio.weight

[root@localhost ~]# docker run -it --name container_B --blkio-weight 300 centos:stress
[root@55bdce1cab5d /]# cat /sys/fs/cgroup/blkio/blkio.weight

Docker——Cgroup資源限制

八、bps 和 iops 的限制:

(1)bps :是 byte per second,每秒讀寫的數據量;

(2)iops :是 io per second,每秒 IO 的次數;

(3)可以通過以下的參數來控制 bps 和 iops:

–device-read-bps:限制讀某個設備的 bps;
device-write-bps:限制寫某個設備的 bps;
device-read-iops:限制讀某個設備的 iops;
device-write-iops:限制寫某個設備的 iops。
例如:

限制容器 寫 /dev/sda 磁盤的速率爲 5MB/s:

[root@localhost ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress 

Docker——Cgroup資源限制

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