一個 docker host 上會運行若干容器,每個容器都需要 CPU、內存和 IO 資源。對於 KVM,VMware 等虛擬化技術,用戶可以控制分配多少 CPU、內存資源給每個虛擬機。對於容器,Docker 也提供了類似的機制避免某個容器因占用太多資源而影響其他容器乃至整個 host 的性能。 |
內存限額
與操作系統類似,容器可使用的內存包括兩部分:物理內存和 swap。 Docker 通過下面兩組參數來控制容器內存的使用量
-m或--memory:設置內存的使用限額,例如 100M, 2G。
--memory-swap:設置內存+swap的使用限額
Eg1:
docker run -it -m 200M --memory-swap=300M --name test ubuntu:16.04 |
其含義是允許該容器最多使用 200M 的內存和 100M 的 swap。默認情況下,上面兩組參數為 -1,即對容器內存和 swap 的使用沒有限制。
Eg2:
docker run -it -m 300M --memory-swap -1 --name con1 u-stress /bin/bash |
上面的 docker run 命令中通過 -m 選項限制容器使用的內存上限為 300M。同時設置 memory-swap 值為 -1,它表示容器程序使用內存的受限,而可以使用的 swap 空間使用不受限制(宿主機有多少 swap 容器就可以使用多少),把 --memory-swap 設置為 0 和不設置是一樣的
Eg3:
--memory="300m" --memory-swap="1g" 的含義為: |
容器可以使用 300M 的物理內存,並且可以使用 700M(1G -300M) 的 swap。--memory-swap 居然是容器可以使用的物理內存和可以使用的 swap 之和!
壓力測試工具 stress
安裝:apt-get install stress
下面的 stress 命令會創建一個進程並通過 malloc 函數分配內存:
stress --vm 1 --vm-bytes 500M
Docker對cpu的限制和使用
1.CPU份額控制:
Docker 提供了 -c或者–cpu-shares參數,在創建容器時指定容器所使用的 CPU 份額值。如果不指定,默認值為1024。
docker run -tid --cpu-shares 100 ubuntu:stress
兩個容器A、B的 CPU 份額分別為1000和500,在 CPU 進行時間片分配的時候,容器 A 比容器 B 多一倍的機會獲得 CPU 的時間片,但分配的結果取決於當時主機和其他容器的運行狀態,實際上也無法保證容器A一定能獲得 CPU 時間片。比如容器A的進程一直是空閑的,那么容器B是可以獲取比容器A更多的 CPU 時間片的。極端情況下,比如說主機上只運行了一個容器,即使它的 CPU 份額只有 50,它也可以獨占整個主機的 CPU 資源。
cgroups 只在容器分配的資源緊缺時,也就是說在需要對容器使用的資源進行限制時,才會生效。因此,無法單純根據某個容器的 CPU 份額來確定有多少 CPU 資源分配給它,資源分配結果取決於同時運行的其他容器的 CPU 分配和容器中進程運行情況。
換句話說:通過 cpu share 可以設置容器使用 CPU 的優先級。
2.CPU周期控制
docker 提供了--cpu-period、--cpu-quota兩個參數控制容器可以分配到的 CPU 時鍾周期。 --cpu-period是用來指定容器對 CPU 的使用要在多長時間內做一次重新分配。
--cpu-quota是用來指定在這個周期內,最多可以有多少時間用來跑這個容器。跟 –cpu-shares 不同的是這種配置是指定一個絕對值,而且沒有彈性在里面,容器對 CPU 資源的使用絕對不會超過配置的值。
使用示例:[ cpu-period 設置為1000000(即1秒),cpu-quota 設置為 200000(0.2秒)]
docker run -tid --cpu-period 100000 --cpu-quota 200000 ubuntu
3.限制CPU個數:
在 docker 1.13 及更高的版本上,能夠很容易的限制容器可以使用的主機 CPU 個數。只需要通過 --cpus 選項指定容器可以使用的 CPU 個數就可以了,並且還可以指定如 1.5 之類的小數。
通過下面的命令創建容器,--cpus=2 表示容器最多可以使用主機上兩個 CPU:
$ docker run -it --rm --cpus=1.5 ubuntu:16.04 /bin/bash
使用特定0-1的cpu:
docker run -idt --name a1 --cpuset-cpus=0-1 ubuntu:18.04 /bin/bash
安裝壓力測試工具:
# apt-get install stress
然后由 stress 命令創建四個繁忙的進程消耗 CPU 資源:
# stress -c 4
如果多個容器使用,可能會平均分配cpu [同時壓力測試]
一個結束后,另外那個會使用盡可能使用cpu,直到到限制的cpu為止
對 Block IO 的限制[https://blog.51cto.com/wzlinux/2046566?source=drt]
Block IO 是另一種可以限制容器使用的資源。Block IO 指的是磁盤的讀寫,docker 可通過設置權重、限制 bps 和 iops 的方式控制容器讀寫磁盤的帶寬
block IO 權重
默認情況下,所有容器能平等地讀寫磁盤,可以通過設置--blkio-weight參數來改變容器 block IO 的優先級。
--blkio-weight 與 --cpu-shares 類似,設置的是相對權重值,默認為 500。在下面的例子中,container_A 讀寫磁盤的帶寬是 container_B 的兩倍。
docker run -it --name container_A --blkio-weight 600 ubuntu
docker run -it --name container_B --blkio-weight 300 ubuntu
限制 bps 和 iops
同樣的,我們可以在 /sys/fs/cgroup/blkio/docker 看到 block IO 的數值。
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。
例子:【限制容器寫 /dev/sda 的速率為 30 MB/s】
docker run -it --device-write-bps /dev/sda:30MB --name u2 ubuntu:18.04
通過 dd 測試在容器中寫磁盤的速度。因為容器的文件系統是在 host /dev/sda 上的,在容器中寫文件相當於對 host /dev/sda 進行寫操作。另外,oflag=direct 指定用 direct IO 方式寫文件,這樣 --device-write-bps 才能生效。
結果表明,bps 23.4 MB/s 沒有超過 30 MB/s 的限速。
測試對比:
docker run -it --name u1 ubuntu:18.04