Docker的資源限制(內存、CPU、IO)詳細篇

一個docker host. 上會運行若干容器,每個容器都需要CPU、內存和I0資源。對於KVM、VMware 等虛擬化技術,用戶可以控制分配多少CPU、內存資源給每個虛擬機。對於容器,Docker 也提供了類似的機制避免某個容器因佔用太多資源而影響其他容器乃至整個host
的性能。

 

內存限額

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

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

(1)-m 或 --memory :設置內存的使用限額,例如100MB,2GB

(2)--memory-swap:設置內存+swawp的使用限額

 

當我們執行如下的命令時

docker run -m 200M --memory-swap=300M ubuntu

其含義是允許該容器最多使用200MB的內存和100MB 的swap。默認情況下,上面兩組參數爲-1, 即對容器內存和swap的使用沒有限制。

下面我們將使用progrium/stress 鏡像來學習如何爲容器分配內存。該鏡像可用於對容器執行壓力測試。執行如下命令:
 

docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 208M
  • --vm1:啓動1個內存工作線程。
  • --vm-bytes 280M:每個線程分配280MB內存。

 

運行如下圖結果

因爲280MB在可分配的範圍(300MB) 內,所以工作線程能夠正常工作,其過程是:
(1)分配280MB內存。
(2)釋放280MB內存。
(3)再分配280MB內存。
(4)再釋放280MB內存。
(5)一-直循環.....
如果讓工作線程分配的內存超過300MB,結果如圖

docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M

分配的內存超過限額,stress 線程報錯,容器退出。
如果在啓動容器時只指定-m而不指定-memoryswap, 那麼-memory-swap 默認爲-m的兩倍,比如:
 

docker run -it -m 200M ubuntu

容器最多使用200M絨裏內存和200swap

CPU限額

默認設置下,所有容器可以平等地使用host CPU資源並且沒有限制


Docker可以通過-c或-pu-shares設置容器使用CPU的權重。如果不指定,默認值爲1024
與內存限額不同,通過-c設置的cpu share 並不是CPU資源的絕對數量,而是一個相對的權重值。某個容器最終能分配到的CPU資源取決於它的cpu share佔所有容器cpu share總和的比例。
換句話說:通過cpu share可以設置容器使用CPU的優先級。

比如在host中啓動了兩個容器:

docker run --name "cont_A" -c 1024 ubuntu docker run --name "cont_B" -c 512 ubuntu

containerA的cpu share 1024, 是containerB 的兩倍。當兩個容器都需要CPU資源時,containerA可以得到的CPU是containerB 的兩倍。
需要特別注意的是,這種按權重分配CPU只會發生在CPU資源緊張的情況下。如果containerA處於空閒狀態,這時,爲了充分利用CPU資源,containerB 也可以分配到全部可用的CPU.


下面我們繼續用progrium/stress 做實驗。


(1)啓動(container_ A, cpu share爲1024
 

docker run --name "cont_A" -it -c 1024  progrium/stress --cpu 1

--cpu用來設置工作線程的數量。因爲當前host 只有1顆CPU,所以一個工作線程就能將CPU壓滿。如果host有多顆CPU,則需要相應增加--cpu的數量。
 

(2)啓動(container_B, cpu share爲512

docker run --name "cont_B" -it -c 512  progrium/stress --cpu 1

(3)在host中執行top, 查看容器對CPU的使用情況,
 

ps aux|head -1;ps aux|sort -k3nr |head -4

containerA消耗的CPU是containerB 的兩倍。
 

(4)現在暫停container. A

(5) top 顯示containerB在containerA空閒的情況下能夠用滿整顆CPU

Block IO 帶寬限額

Block 10是另一種可以限制容器使用的資源。Block I0指的是磁盤的讀寫,docker 可通過設置權重、限制bps和iops 的方式控制容器讀寫磁盤的帶寬,下 面分別討論。
注:目前Block I0限額只對direct IO (不使用文件緩存)有效。
Block IO權重
默認情況下,所有容器能平等地讀寫磁盤,可以通過設置-blkio-weight參數來改變容器block Io的優先級。
-blkio-weight與--cpu-shares 類似,設置的是相對權重值,默認爲500。 在下面的例子中,containerA 讀寫磁盤的帶寬是containerB 的兩倍。

docker run -it --name cont_A --blkip-weight 600 ubuntu
docker run -it --name cont_B --blkip-weight 300 ubuntu

限制bps和iops

bps是 byte per second ,每秒讀寫的數量

iops是 io per second ,每秒IO的次數

可以同過下面的參數控制容器的bps和iops;

  • --device-read-bps:限制讀某個設備的bps.
  • --devce-write-bps:限制寫某個設備的bps.
  • --device- read-iops:限制讀某個設備的iops.
  • --device-write-iops: 限制寫某個設備的iops。
     

下面這個例子限制容器寫/dev/sda 的速率爲30 MB/s:
 

[root@kvm ~]# docker run -it --device-write-bps /dev/sda:30MB ubuntu
root@10845a98036e:/# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
800+0 records in
800+0 records out
838860800 bytes (839 MB, 800 MiB) copied, 26.6211 s, 31.5 MB/s

real	0m26.623s
user	0m0.000s
sys	0m0.106s
root@10845a98036e:/# 
docker run -it --device-write-bps /dev/sda:30MB ubuntu

有限制

沒有限制

通過dd測試在容器中寫磁盤的速度。因爲容器的文件系統是在host /dev/sda. 上的,在容器中寫文件相當於對host /dev/sda 進行寫操作。另外,oflag= -direct指定用direct I0方式寫文件,這樣--device-write-bps才能生效。
 

看到,沒有限速的話,速度很快,

其他參數,大家也可以試試

 

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