是阿裡巴巴集團開源的高效、企業級容器引擎技術,擁有隔離性強、可移植性高、資源占用少等特點。可以幫助企業快速實作存量業務容器化,同時提高超大規模下資料中心的實體資源使用率。
資源管理是容器運作時的一個重要的部分,本文将給大家介紹PouchContainer資源管理的常用接口和其對應的底層核心接口,為了讓讀者加深了解,本文為部分接口提供了測試用例。
1. PouchContainer資源管理常用接口
接口 | 描述 |
---|---|
--blkio-weight | 塊裝置IO相對權重,取值範圍為0到100之間的整數。 |
--blkio-weight-device | 指定的塊裝置的IO相對權重 |
--cpu-period | 完全公平算法中的period值 |
--cpu-quota | 完全公平算法中的quota值 |
--cpu-share | CPU份額 (相對權重) |
--cpuset-cpus | 限制容器使用的cpu核 |
--cpuset-mems | 限制容器使用的記憶體節點,該限制僅僅在NUMA系統中生效。 |
--device-read-bps | 限制對某個裝置的讀取速率 ,數字需要使用正整數,機關是kb, mb, or gb中的一個。 |
--device-read-iops | 限制對某個裝置每秒IO的讀取速率,數字需要使用正整數。 |
--device-write-bps | 限制對某個裝置的寫速率 ,數字需要使用正整數,機關是kb, mb, or gb中的一個。 |
--device-write-iops | 限制對某個裝置每秒IO的寫速率,數字需要使用正整數。 |
-m, --memory | 記憶體使用限制。 數字需要使用整數,對應的機關是b, k, m, g中的一個。 |
--memory-swap | 總記憶體使用限制 (實體記憶體 + 交換分區,數字需要使用整數,對應的機關是b, k, m, g中的一個。 |
--memory-swappiness | 調節容器記憶體使用交換分區的選項,取值為0和100之間的整數(含0和100)。 |
--memory-wmark-ratio | |
--oom-kill-disable | 記憶體耗盡時是否殺掉容器 |
--oom-score-adj | 設定容器程序觸發OOM的可能性,值越大時越容易觸發容器程序的OOM。 |
--pids-limit | 用于限制容器内部的pid數量。 |
2. PouchContainer資源管理底層的核心技術
2.1 Memory資管管理
對應的核心接口 | 核心接口描述 | |
---|---|---|
| 設定記憶體上限,機關是位元組,也可以使用k/K、m/M或者g/G表示要設定數值的機關。 | |
| 設定記憶體加上交換分區的使用總量。通過設定這個值,可以防止程序把交換分區用光。 | |
cgroup/memory/memory.swappiness | 控制核心使用交換分區的傾向。取值範圍是0至100之間的整數(包含0和100)。值越小,越傾向使用實體記憶體。 | |
| | |
| 如果設定為0,那麼在記憶體使用量超過上限時,系統不會殺死程序,而是阻塞程序直到有記憶體被釋放可供使用時,另一方面,系統會向使用者态發送事件通知,使用者态的監控程式可以根據該事件來做相應的處理,例如提高記憶體上限等。 | |
| 設定程序觸發OOM的可能性,值越大時越容易觸發容器程序的OOM。 |
2.2 cpu資管管理
對應的cgroup接口 | cgroup接口描述 | |
---|---|---|
| 負責CPU帶寬限制,需要與 搭配使用。我們可以将period設定為1秒,将quota設定為0.5秒,那麼cgroup中的程序在1秒内最多隻能運作0.5秒,然後就會被強制睡眠,直到下一個1秒才能繼續運作。 | |
| 搭配使用。 | |
cgroup/cpu/cpu.shares | 負責CPU比重配置設定的接口。假設我們在cgroupfs的根目錄下建立了兩個cgroup(C1和C2),并且将cpu.shares分别配置為512和1024,那麼當C1和C2争用CPU時,C2将會比C1得到多一倍的CPU占用率。要注意的是,隻有當它們争用CPU時CPU share才會起作用,如果C2是空閑的,那麼C1可以得到全部的CPU資源。 | |
cgroup/cpuset/cpuset.cpus | 允許程序使用的CPU清單(例如:0-4,9)。 | |
cgroup/cpuset/cpuset.mems | 允許程序使用的記憶體節點清單(例如:0-1)。 |
2.3 io資管管理
cgroup/blkio/blkio.weight | 設定權重值,取值範圍是10至1000之間的整數(包含10和1000)。這跟cpu.shares類似,是比重配置設定,而不是絕對帶寬的限制,是以隻有當不同的cgroup在争用同一個塊裝置的帶寬時,才會起作用。 | |
cgroup/blkio/blkio.weight_device | 對具體的裝置設定權重值,這個值會覆寫上述的blkio.weight。 | |
| 對具體的裝置,設定每秒讀塊裝置的帶寬上限。 | |
| 設定每秒寫塊裝置的帶寬上限。同樣需要指定裝置。 | |
| 設定每秒讀塊裝置的IO次數的上限。同樣需要指定裝置。 | |
| 設定每秒寫塊裝置的IO次數的上限。同樣需要指定裝置。 |
2.4 其他資源管理接口
cgroup/pids/pids.max | 限制程序數 |
3. PouchContainer資源管理接口詳解與測試方法
以下内容針對各資源管理接口做了詳盡的說明。為了加深讀者了解,部分接口提供有測試用例。用例中的PouchContainer版本為0.4.0。如果在你的鏡像中stress指令不可用,你可以通過sudo apt-get install stress來安裝stress工具。
3.1 Memory資管管理
3.1.1 -m, --memory
可以限制容器使用的記憶體量,對應的cgroup檔案是
cgroup/memory/memory.limit_in_bytes
。
機關:b,k,m,g
在預設情況下,容器可以占用無限量的記憶體,直至主機記憶體資源耗盡。
運作如下指令來确認容器記憶體的資源管理對應的cgroup檔案。
# pouch run -ti --memory 100M reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/memory/memory.limit_in_bytes"
104857600
可以看到,當記憶體限定為100M時,對應的cgroup檔案數值為104857600,該數值的機關為位元組,即104857600位元組等于100M。
本機記憶體環境為:
# free -m
total used free shared buff/cache available
Mem: 257755 2557 254234 1 963 254903
Swap: 2047 0 2047
我們使用stress工具來驗證記憶體限定是否生效。stress是一個壓力工具,如下指令将要在容器内建立一個程序,在該程序中不斷的執行占用記憶體(malloc)和釋放記憶體(free)的操作。在理論上如果占用的記憶體少于限定值,容器會工作正常。注意,如果試圖使用邊界值,即試圖在容器中使用stress工具占用100M記憶體,這個操作通常會失敗,因為容器中還有其他程序在運作。
下面嘗試對一個限制記憶體使用為100M的容器執行一個占用150M記憶體的操作,但容器運作是正常的,沒有出現OOM。
# pouch run -ti --memory 100M reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04stress stress --vm 1 --vm-bytes 150M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
通過以下指令看一下系統的記憶體使用量,你會發現Swap的記憶體占用量有所增加,說明--memory選項沒有限制Swap記憶體的使用量。
#free -m
total used free shared buff/cache available
Mem: 257755 2676 254114 1 965 254783
Swap: 2047 41 2006
嘗試使用
swapoff -a
指令關閉Swap時我們再次執行早先的指令。從以下log中可以看到,當容器使用記憶體超過限制時會觸發錯誤。
# pouch run -ti --memory 100M reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04stress stress --vm 1 --vm-bytes 150M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [1](422) kill error: No such process
stress: FAIL: [1](452) failed run completed in 0s
esses
stress: FAIL: [1](422) kill error: No such process
stress: FAIL: [1](452) failed run completed in 0s
3.1.2 --memory-swap
可以限制容器使用交換分區和記憶體的總和,對應的cgroup檔案是
cgroup/memory/memory.memsw.limit_in_bytes
取值範圍:大于記憶體限定值
運作如下指令來确認容器交換分區的資源管理對應的cgroup檔案。可以看到,當memory-swap限定為1G時,對應的cgroup檔案數值為1073741824,該數值的機關為位元組,即1073741824B等于1G。
# pouch run -ti -m 300M --memory-swap 1G reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"
1073741824
如下所示,當嘗試占用的記憶體數量超過memory-swap值時,容器出現異常。
# pouch run -ti -m 100M --memory-swap 200M reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04stress bash -c "stress --vm 1 --vm-bytes 300M"
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [1](416) <-- worker 10 got signal 9
stress: WARN: [1](418) now reaping child worker processes
stress: FAIL: [1](422) kill error: No such process
stress: FAIL: [1](452) failed run completed in 0s
3.1.3 --memory-swappiness
該接口可以設定容器使用交換分區的趨勢,取值範圍為0至100的整數(包含0和100)。0表示容器不使用交換分區,100表示容器盡可能多的使用交換分區。對應的cgroup檔案是cgroup/memory/memory.swappiness。
# pouch run -ti --memory-swappiness=100 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c 'cat /sys/fs/cgroup/memory/memory.swappiness'
100
3.1.4 --memory-wmark-ratio
用于計算low_wmark,
low_wmark = memory.limit_in_bytes * MemoryWmarkRatio
。當
memory.usage_in_bytes
大于low_wmark時,觸發核心線程進行記憶體回收,當回收到
memory.usage_in_bytes
小于high_wmark時停止。對應的cgroup接口是
cgroup/memory/memory.wmark_ratio
# pouch run -ti --memory-wmark-ratio=60 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c 'cat /sys/fs/cgroup/memory/memory.wmark_ratio'
60
3.1.5 --oom-kill-disable
當out-of-memory (OOM)發生時,系統會預設殺掉容器程序,如果你不想讓容器程序被殺掉,可以使用該接口。接口對應的cgroup檔案是
cgroup/memory/memory.oom_control
當容器試圖使用超過限定大小的記憶體值時,就會觸發OOM。此時會有兩種情況,第一種情況是當接口--oom-kill-disable=false的時候,容器會被殺掉;第二種情況是當接口--oom-kill-disable=true的時候,容器會被挂起。
以下指令設定了容器的的記憶體使用限制為20M,将--oom-kill-disable接口的值設定為true。檢視該接口對應的cgroup檔案,
oom_kill_disable
的值為1。
# pouch run -m 20m --oom-kill-disable=true reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c 'cat /sys/fs/cgroup/memory/memory.oom_control'
oom_kill_disable 1
under_oom 0
oom_kill_disable
:取值為0或1,當值為1的時候表示當容器試圖使用超出記憶體限制時(即20M),容器會挂起。
under_oom:取值為0或1,當值為1的時候,OOM已經出現在容器中。
通過
x=a; while true; do x=$x$x$x$x; done
指令來耗盡記憶體并強制觸發OOM,log如下所示。
# pouch run -m 20m --oom-kill-disable=false reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c 'x=a; while true; do x=$x$x$x$x; done'
[[email protected] /root]
#echo $?
137
通過上面的log可以看出,當容器的記憶體耗盡的時候,容器退出,退出碼為137。因為容器試圖使用超出限定的記憶體量,系統會觸發OOM,容器會被殺掉,此時under_oom的值為1。我們可以通過系統中cgroup檔案(
/sys/fs/cgroup/memory/docker/${container_id}/memory.oom_control
)檢視
under_oom
的值(
oom_kill_disable
1,under_oom 1)。
當--oom-kill-disable=true的時候,容器不會被殺掉,而是被系統挂起。
3.1.6 --oom-score-adj
參數--oom-score-adj可以設定容器程序觸發OOM的可能性,值越大時越容易觸發容器程序的OOM。當值為-1000時,容器程序完全不會觸發OOM。該選項對應着底層的
/proc/$pid/oom_score_adj
接口。
# pouch run -ti --oom-score-adj=300 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04stress bash -c "cat /proc/self/oom_score_adj"
300
3.2 cpu資源管理
3.2.1 --cpu-period
核心預設的Linux 排程CFS(完全公平排程器)周期為100ms,我們通過--cpu-period來設定容器對CPU的使用周期,同時--cpu-period接口需要和--cpu-quota接口一起來使用。--cpu-quota接口設定了CPU的使用值。CFS(完全公平排程器) 是核心預設使用的排程方式,為運作的程序配置設定CPU資源。對于多核CPU,根據需要調整--cpu-quota的值。
對應的cgroup檔案是
cgroup/cpu/cpu.cfs_period_us
。以下指令建立了一個容器,同時設定了該容器對CPU的使用時間為50000(機關為微秒),并驗證了該接口對應的cgroup檔案對應的值。
# pouch run -ti --cpu-period 50000 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/cpu/cpu.cfs_period_us"
50000
以下指令将--cpu-period的值設定為50000,--cpu-quota的值設定為25000。該容器在運作時可以擷取50%的cpu資源。
# pouch run -ti --cpu-period=50000 --cpu-quota=25000 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04stress stress -c 1
stress: info: [1] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
從log的最後一行中可以看出,該容器的cpu使用率約為50.0%,與預期相符。
# top -n1
top - 17:22:40 up 1 day, 57 min, 3 users, load average: 0.68, 0.16, 0.05
Tasks: 431 total, 2 running, 429 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.1 sy, 0.0 ni, 99.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 26354243+total, 25960588+free, 1697108 used, 2239424 buff/cache
KiB Swap: 2096636 total, 0 free, 2096636 used. 25957392+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
53256 root 20 0 7324 100 0 R 50.0 0.0 0:12.95 stress
3.2.2 --cpu-quota
cgroup/cpu/cpu.cfs_quota_us
# pouch run -ti --cpu-quota 1600 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us"
1600
--cpu-quota接口設定了CPU的使用值,通常情況下它需要和--cpu-period接口一起來使用。具體使用方法請參考--cpu-period選項。
3.2.3 --cpu-share
對應的cgroup檔案是cgroup/cpu/cpu.shares。
# pouch run -ti --cpu-quota 1600 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/cpu/cpu.shares"
1600
通過--cpu-shares可以設定容器使用CPU的權重,這個權重設定是針對CPU密集型的程序的。如果某個容器中的程序是空閑狀态,那麼其它容器就能夠使用本該由空閑容器占用的CPU資源。也就是說,隻有當兩個或多個容器都試圖占用整個CPU資源時,--cpu-shares設定才會有效。
我們使用如下指令來建立兩個容器,它們的權重分别為1024和512。
# pouch run -d --cpuset-cpus=0 --cpu-share 1024 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04stress stress -c 1
c7b99f3bc4cf1af94da35025c66913d4b42fa763e7a0905fc72dce66c359c258
[[email protected] /root]
# pouch run -d --cpuset-cpus=0 --cpu-share 512 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04stress stress -c 1
1ade73df0dd9939cc65e05117e3b0950b78079fb36f6cc548eff8b20e8f5ecb9
從如下top指令的log可以看到,第一個容器産生的程序PID為10513,CPU占用率為65.1%,第二個容器産生程序PID為10687,CPU占用率為34.9%。兩個容器CPU占用率約為2:1的關系,測試結果與預期相符。
#top
top - 09:38:24 up 3 min, 2 users, load average: 1.20, 0.34, 0.12
Tasks: 447 total, 3 running, 444 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.1 us, 0.0 sy, 0.0 ni, 96.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 26354243+total, 26187224+free, 964068 used, 706120 buff/cache
KiB Swap: 2096636 total, 2096636 free, 0 used. 26052548+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10513 root 20 0 7324 100 0 R 65.1 0.0 0:48.22 stress
10687 root 20 0 7324 96 0 R 34.9 0.0 0:20.32 stress
3.2.4 --cpuset-cpus
該接口對應的cgroup檔案是cgroup/cpuset/cpuset.cpus。
在多核CPU的虛拟機中,啟動一個容器,設定容器隻使用CPU核1,并檢視該接口對應的cgroup檔案會被修改為1,log如下所示。
# pouch run -ti --cpuset-cpus 1 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/cpuset/cpuset.cpus"
1
通過以下指令指定容器使用cpu核1,并通過stress指令加壓。
# pouch run -ti --cpuset-cpus 1 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 stress -c 1
檢視CPU資源的top指令的log如下所示。需要注意的是,輸入top指令并按Enter鍵後,再按數字鍵1,終端才能顯示每個CPU的狀态。
#top
top - 17:58:38 up 1 day, 1:33, 3 users, load average: 0.51, 0.11, 0.04
Tasks: 427 total, 2 running, 425 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 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 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
從以上log得知,隻有CPU核1的負載為100%,而其它CPU核處于空閑狀态,結果與預期結果相符。
3.2.5 --cpuset-mems
該接口對應的cgroup檔案是cgroup/cpuset/cpuset.mems。
# pouch run -ti --cpuset-mems=0 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/cpuset/cpuset.mems"
0
以下指令将限制容器程序使用記憶體節點1、3的記憶體。
# pouch run -ti --cpuset-mems="1,3" reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash
以下指令将限制容器程序使用記憶體節點0、1、2的記憶體。
# pouch run -ti --cpuset-mems="0-2" reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash
3.3 io資管管理
3.3.1 --blkio-weight
通過--blkio-weight接口可以設定容器塊裝置IO的權重,有效值範圍為10至1000的整數(包含10和1000)。預設情況下,所有容器都會得到相同的權重值(500)。對應的cgroup檔案為cgroup/blkio/blkio.weight。以下指令設定了容器塊裝置IO權重為10,在log中可以看到對應的cgroup檔案的值為10。
# pouch run -ti --rm --blkio-weight 10 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/blkio/blkio.weight"
10
通過以下兩個指令來建立不同塊裝置IO權重值的容器。
# pouch run -it --name c1 --blkio-weight 300 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 /bin/bash
# pouch run -it --name c2 --blkio-weight 600 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 /bin/bash
如果在兩個容器中同時進行塊裝置操作(例如以下指令)的話,你會發現所花費的時間和容器所擁有的塊裝置IO權重成反比。
# time dd if=/mnt/zerofile of=test.out bs=1M count=1024 oflag=direct
3.3.2 --blkio-weight-device
通過--blkio-weight-device="裝置名:權重"接口可以設定容器對特定塊裝置IO的權重,有效值範圍為10至1000的整數(包含10和1000)。
對應的cgroup檔案為cgroup/blkio/blkio.weight_device。
# pouch run --blkio-weight-device "/dev/sda:1000" reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/blkio/blkio.weight_device"
8:0 1000
以上log中的"8:0"表示sda的裝置号,可以通過stat指令來擷取某個裝置的裝置号。從以下log中可以檢視到/dev/sda對應的主裝置号為8,次裝置号為0。
#stat -c %t:%T /dev/sda
8:0
如果--blkio-weight-device接口和--blkio-weight接口一起使用,那麼Docker會使用--blkio-weight值作為預設的權重值,然後使用--blkio-weight-device值來設定指定裝置的權重值,而早先設定的預設權重值将不在這個特定裝置中生效。
# pouch run --blkio-weight 300 --blkio-weight-device "/dev/sda:500" reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/blkio/blkio.weight_device"
8:0 500
通過以上log可以看出,當--blkio-weight接口和--blkio-weight-device接口一起使用的時候,/dev/sda裝置的權重值由--blkio-weight-device設定的值來決定。
3.3.3 --device-read-bps
該接口用來限制指定裝置的讀取速率,機關可以是kb、mb或者gb。對應的cgroup檔案是
cgroup/blkio/blkio.throttle.read_bps_device
# pouch run -it --device /dev/sda:/dev/sda --device-read-bps /dev/sda:1mb reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"
8:0 1048576
以上log中顯示8:0 1000,8:0表示/dev/sda, 該接口對應的cgroup檔案的值為1048576,是1MB所對應的位元組數,即1024的平方。
建立容器時通過--device-read-bps接口設定裝置讀取速度為500KB/s。從以下log中可以看出,讀取速度被限定為498KB/s,與預期結果相符合。
# pouch run -it --device /dev/sda:/dev/sda --device-read-bps /dev/sda:500k reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash
root@r10f10195:/# dd iflag=direct,nonblock if=/dev/sda of=/dev/null bs=5000k coun
1+0 records in
1+0 records out
5120000 bytes (5.1 MB) copied, 10.2738 s, 498 kB/s
3.3.4 --device-write-bps
該接口用來限制指定裝置的寫速率,機關可以是kb、mb或者gb。對應的cgroup檔案是
cgroup/blkio/blkio.throttle.write_bps_device
# pouch run -it --device /dev/sda:/dev/sda --device-write-bps /dev/sda:1mB reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"
8:0 1048576
以上log中顯示8:0 1000,8:0表示/dev/sda, 該接口對應的cgroup檔案的值為1048576,是1MB所對應的位元組數,即1024的平方。
建立容器時通過--device-write-bps接口設定裝置寫速度為1MB/s。從以下log中可以看出,讀取速度被限定為1.0MB/s,與預期結果相符合。
限速操作:
# pouch run -it --device /dev/sdb:/dev/sdb --device-write-bps /dev/sdb:1mB reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash
root@r10d08216:/# dd oflag=direct,nonblock of=/dev/sdb if=/dev/urandom bs=10K count=1000
1024+0 records in
1024+0 records out
10485760 bytes (10 MB) copied, 10.0022 s, 1.0 MB/s
3.3.5 --device-read-iops
該接口設定了裝置的IO讀取速率,對應的cgroup檔案是
cgroup/blkio/blkio.throttle.read_iops_device
# pouch run -it --device /dev/sda:/dev/sda --device-read-iops /dev/sda:400 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"
8:0 400
可以通過"--device-read-iops /dev/sda:400"來限定sda的IO讀取速率(400次/秒),log如下所示。
# pouch run -it --device /dev/sda:/dev/sda --device-read-iops /dev/sda:400 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash
root@r10d08216:/# dd iflag=direct,nonblock if=/dev/sda of=/dev/null bs=1k count=1024
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 2.51044 s, 418 kB/s
root@r10d08216:/#
通過上面的log資訊可以看出,容器每秒IO的讀取次數為400,共需要讀取1024次(log第二行:count=1024),測試結果顯示執行時間為2.51044秒,與預期值2.56(1024/400)秒接近,符合預期。
3.3.6 --device-write-iops
該接口設定了裝置的IO寫速率,對應的cgroup檔案是
cgroup/blkio/blkio.throttle.write_iops_device
# pouch run -it --device /dev/sda:/dev/sda --device-write-iops /dev/sda:400 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash -c "cat /sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"
8:0 400
可以通過"--device-write-iops /dev/sda:400"來限定sda的IO寫速率(400次/秒),log如下所示。
# pouch run -it --device /dev/sdb:/dev/sdb --device-write-iops /dev/sdb:400 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04 bash
root@r10d08216:/# dd oflag=direct,nonblock of=/dev/sdb if=/dev/urandom bs=1K count=1024
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 2.50754 s, 418 kB/s
通過上面的log資訊可以看出,容器每秒IO的寫入次數為400,共需要寫1024次(log第二行:count=1024),測試結果顯示執行時間為2.50754秒,與預期值2.56(1024/400)秒接近,符合預期。
3.4 其他資源管理接口
--pids-limit用于限制容器内部的pid數量,對應的cgroup接口是cgroup/pids/pids.max。
# pouch run -ti --pids-limit 100 reg.docker.alibaba-inc.com/sunyuan/ubuntu:14.04stress bash -c "cat /sys/fs/cgroup/pids/pids.max"
100
如果在容器内部不斷建立新的程序,系統會提示如下錯誤。
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
4. 總結
PouchContainer的資源管理依賴于Linux底層的核心技術,感興趣的讀者可以根據自己興趣補充一些有針對性的測試。關于其依賴的核心技術的實作已經遠超本文的範疇。感興趣的讀者可以自行閱讀核心手冊。