(1)Docker通過 Cgroup 來控制容器使用的資源配額,包括 CPU、內(nèi)存、磁盤三大方面,基本覆蓋了常見的資源配額和使用量控制。
成都創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站設(shè)計、網(wǎng)站建設(shè)與策劃設(shè)計,永順網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:永順等地區(qū)。永順做網(wǎng)站價格咨詢:13518219792
(2)Cgroup 是 Linux 內(nèi)核提供的一種可以限制、記錄、隔離進(jìn)程組所使用的物理資源的機(jī)制。
Cgroup 子系統(tǒng):
1、blkio:設(shè)置限制每個塊設(shè)備的輸入輸出控制;
2、cpu:使用調(diào)度程序為 cgroup 任務(wù)提供 cpu 的訪問;
3、cpuacct:產(chǎn)生 cgroup 任務(wù)的 cpu 資源報告;
4、cpuset:如果是多核心的 cpu,這個子系統(tǒng)會為 cgroup 任務(wù)分配單獨的 cpu 和內(nèi)存;
5、devices:允許或拒絕 cgroup 任務(wù)對設(shè)備的訪問;
6、freezer:暫停和恢復(fù) cgroup 任務(wù);
7、memory:設(shè)置每個 cgroup 的內(nèi)存限制以及產(chǎn)生內(nèi)存資源報告;
8、net_cls:標(biāo)記每個網(wǎng)絡(luò)包以供 cgroup 方便使用;
9、ns:命名空間子系統(tǒng);
10、perf_event:增加了對每個 cgroup 的監(jiān)測跟蹤能力,可以監(jiān)測屬于某個特定的 cgroup 的所有線程及運行在特定 CPU 上的線程。
首先使用 Dockerfile 來創(chuàng)建一個基于 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 . //創(chuàng)建鏡像
(1)使用如下命令創(chuàng)建容器,命令中的 --cpu-shares 參數(shù)值不能保證可以獲得 1 個 vcpu 或者多少 GHz 的CPU 資源,它僅是一個彈性的加權(quán)值。
[root@localhost stress]# docker run -itd --cpu-shares 100 centos:stress
08a203033c051098fd6294cd8ba4e2fa8baa18cefb793c6c4cd655c0f28cabc0
注意:默認(rèn)情況下,每個 Docker 容器的CPU的份額都是1024,單獨一個容器的份額是沒有意義的。只有在同時運行多個容器時,容器的 CPU 加權(quán)的效果才能體現(xiàn)出來。
例如,兩個容器 A、B 的CPU份額分別是 1000 和 500 ,在 CPU 進(jìn)行時間片分配的時候,容器A比容器B多一倍的機(jī)會獲得 CPU 的時間片。但分配的結(jié)果取決于當(dāng)時主機(jī)和其他容器的運行狀態(tài),實際上也無法保證容器 A 一定能獲得CPU 時間片。比如容器 A 的進(jìn)程一直是空閑的,那么容器 B 是可以獲取比容器 A 更多的 CPU 時間片。極端情況下,例如主機(jī)上只運行了一個容器,即使它的 CPU 份額只有 50,它也可以獨占整個主機(jī)的 CPU 資源。
比如:Cgroup 只在容器分配的資源緊缺時,即在需要對容器使用的資源進(jìn)行限制時,才會生效。因此,無法單純根據(jù)某個容器的 CPU 份額來確定有多少 CPU 資源分配給它,資源分配結(jié)果取決于同時運行的其他容器的 CPU 分配和容器中進(jìn)程運行情況??梢酝ㄟ^ cpu share 可以設(shè)置容器使用 CPU 的優(yōu)先級。
比如,啟動了兩個容器及運行查看 CPU 使用百分比:
1、
//容器產(chǎn)生10個子函數(shù)進(jìn)程:
[root@localhost stress]# docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10
99086cce962308fdb5417df189571e39f375ab2c067887cbac48e773225f25c7
//進(jìn)入容器再使用top命令查看cpu使用情況:
[root@localhost stress]# docker exec -it 99086cce9623 bash
[root@99086cce9623 /]# top
.. ..
.. ..
.. ..
.. ..
按 q 退出,
[root@99086cce9623 /]# exit //退出整個容器
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
..
..
..
通過進(jìn)入容器,觀察兩個容器的 %CPU,可以發(fā)現(xiàn)比例是 1:2
Docker 提供了 --cpu-period、–cpu-quota 兩個參數(shù)控制容器可以分配到的 CPU 時鐘周期。
–cpu-period :是用來指定容器對 CPU 的使用要在多長時間內(nèi)做一次重新分配。
–cpu-quota :是用來指定在這個周期內(nèi),最多可以有多少時間用來跑這個容器。
與 --cpu-shares 不同的是。這種配置是指定一個絕對值,容器對 CPU 資源的使用絕對不會超過配置的值。
注意:
cpu-period 和 cpu-quota 的單位是微秒;
cpu-period 的最小值是1000微秒,最大值為1秒,默認(rèn)值為0.1秒。
cpu-quota 的值默認(rèn)是 -1 ,表示不做控制;
cpu-period 和 cpu-quota 參數(shù)一般聯(lián)合使用。
例如:
容器進(jìn)程需要每一秒使用單個 CPU 的0.2秒時間,可以將 cpu-period 設(shè)置為 1000000(即1秒),cpu-quota 設(shè)置為 200000(0.2秒),當(dāng)然,在多核情況下,如果允許容器進(jìn)程完全占有兩個 CPU,則可以將 cpu-period 設(shè)置為 100000(即0.1秒),cpu-quota 設(shè)置為 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
對于多核 CPU 的服務(wù)器,Docker 還可以控制容器運行使用哪些 CPU 內(nèi)核,即使用 --cpuset-cpus 參數(shù)。這對具有多 CPU 的服務(wù)器尤其有用,可以對需要高性能計算的容器進(jìn)行性能最優(yōu)配置。
[root@localhost ~]# docker run -itd --name cpu02 --cpuset-cpus=0-2 centos:stress
76994f5d310de48ee635f69270f7c9b4cba1e65aad935ff1e0d6e098441104eb
//執(zhí)行該命令(需要宿主機(jī)為四核),表示創(chuàng)建的容器只能使用0、1、2 三個內(nèi)核。
[root@localhost ~]# docker exec -it 76994f5d310d bash //進(jìn)入容器
[root@76994f5d310d /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-2
通過下面指令可以看到容器中進(jìn)程與 CPU 內(nèi)核的綁定關(guān)系,達(dá)到 CPU 內(nèi)核的目的:
[root@localhost ~]# docker exec 76994f5d310d taskset -c -p 1
pid 1's current affinity list: 0-2
//容器內(nèi)部第一個進(jìn)程號 pid為1,被綁定到指定CPU上運行。
通過 cpuset-cpus 參數(shù)指定容器 A 使用 CPU 內(nèi)核 0,容器B 只是用 CPU 內(nèi)核1;在主機(jī)上只有這兩個容器使用對應(yīng) CPU 內(nèi)核的情況,它們各自占有全部的內(nèi)核資源,cpu-shares 沒有明顯效果。cpuset-cpus、cpuset-mems 參數(shù)只在多核、多內(nèi)存節(jié)點上的服務(wù)器上有效,并且必須與實際的物理配置匹配,否則也無法達(dá)到資源控制的目的。在系統(tǒng)具有多個 CPU 內(nèi)核的情況下,需要通過 cpuset-cpus 參數(shù)為設(shè)置容器 CPU 內(nèi)核才能方便地進(jìn)行測試。
[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可以看到每個核心的占用情況
我們再創(chuàng)建一個容器:
[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
與操作系統(tǒng)類似,容器可使用的內(nèi)存包括兩部分:物理內(nèi)存 和 Swap;
docker 通過下面兩組參數(shù)來控制容器內(nèi)存的使用量:
-m 或 --memory:設(shè)置內(nèi)存的使用限額,例如 100M、1024M;
–memory-swap:設(shè)置內(nèi)存 +swap 的使用限額。
例如:執(zhí)行如下命令允許該容器最多使用 200M的內(nèi)存,300M 的swap:
[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
// --vm 1:啟動1個內(nèi)存工作線程;
--vm-bytes 280M :每個線程分配280M內(nèi)存;
如果讓工作線程分配的內(nèi)存超過 300M,分配的內(nèi)存超過限額,stress線程報錯,容器退出:
[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M
默認(rèn)情況下,所有容器能平等地讀寫磁盤,可以通過設(shè)置 --blkio-weight 參數(shù)來改變?nèi)萜?block IO 的優(yōu)先級。
–blkio-weight 與 --cpu-shares 類似,設(shè)置的是相對權(quán)重值,默認(rèn)為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
(1)bps :是 byte per second,每秒讀寫的數(shù)據(jù)量;
(2)iops :是 io per second,每秒 IO 的次數(shù);
(3)可以通過以下的參數(shù)來控制 bps 和 iops:
–device-read-bps:限制讀某個設(shè)備的 bps;
device-write-bps:限制寫某個設(shè)備的 bps;
device-read-iops:限制讀某個設(shè)備的 iops;
device-write-iops:限制寫某個設(shè)備的 iops。
例如:
限制容器 寫 /dev/sda 磁盤的速率為 5MB/s:
[root@localhost ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress