Docker管理控制相關資源

一臺宿主機能夠放多個容器,默認的狀況下,Docker 沒有對容器進行硬件資源的限制,當容器負載太高時會盡量的佔用宿主機資源,因此有時候咱們須要對容器的資源使用設置一個上限,這裏就須要管理 Docker 使用的資源。真正能夠控制的只有內存和CPU。mysql

查看宿主機資源使用狀況

Docker 使用 cgroups 歸類運行在容器中的進程,這就使得咱們能夠管理一組進程使用的資源。運行 systemd-cgls命令 就能夠查看 cgroups樹 :c++

├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
├─docker
│ ├─93d5ecbdf58ff840f737c41adff9d0f9506aac036a1fd2f0c3f31edf696ce7f1
│ │ ├─24291 mysqld
│ │ ├─29404 bash
│ │ └─29480 mysql -uroot -px xxxx
│ ├─b1f53779101af8778ba8e8dfd0946a84e8c69b3d8b0b35cd8753c46d966ffba5
│ │ ├─23893 mysqld
│ │ ├─25112 bash
│ │ └─28740 mysql -uroot -px xxxx
│ └─57aff029f6c65c6bbe0edcb3f9b61b4c3a6253bd1093d2dfc8ec318dd2cc4b9b
│   ├─23667 mysqld
│   ├─24709 bash
│   └─29649 mysql -uroot -px xxxx
......

使用 systemd-cgtop 命令能夠看到使用最多資源的進程。算法

1、CPU

默認狀況下,每個容器可使用宿主機上的全部 CPU 資源,但大多數系統使用的資源調度算法是CFS(徹底公平調度器),它公平調度每個工做進程。進程分CPU密集型IO密集型兩類。系統內核會實時監測系統進程,當某個進程佔用 CPU 資源時間過長時,內核會調整該進程的優先級。sql

參數

參數名 做用
--cpu-share cpu資源提供給一組容器使用,組內的容器按比例使用cpu資源,當容器處於空閒狀態時,cpu資源被負載大的容器佔用,(按壓縮方式比例分配),當空閒進行運行起來時,cpu資源會被分配到其餘容器
--cpus= value 指定 cpu的核心數量
--cpuset-cpus 指定容器只能運行在哪一個cpu核心上(綁定cpu);核心使用0,1,2,3編號;
–cpu-share 隨機指定cpu

實例:docker

docker run -di --name=os --cpus=2 centos:latest bash

2、設置內存

默認狀況下,docker 並無對容器內存進行限制,也就是說容器可使用主機提供的全部內存。這固然是很是危險的事情,若是某個容器運行了惡意的內存消耗軟件,或者代碼有內存泄露,極可能會致使主機內存耗盡,所以致使服務不可用。對於這種狀況,docker 會設置 docker daemon 的 OOM(out of memory) 值,使其在內存不足的時候被殺死的優先級下降。另外,就是你能夠爲每一個容器設置內存使用的上限,一旦超過這個上限,容器會被殺死,而不是耗盡主機的內存。centos

限制內存上限雖然能保護主機,可是也可能會傷害到容器裏的服務。若是爲服務設置的內存上限過小,會致使服務還在正常工做的時候就被 OOM 殺死;若是設置的過大,會由於調度器算法浪費內存。所以,合理的作法包括:bash

  • 爲應用作內存壓力測試,理解正常業務需求下使用的內存狀況,而後才能進入生產環境使用
  • 必定要限制容器的內存使用上限
  • 儘可能保證主機的資源充足,一旦經過監控發現資源不足,就進行擴容或者對容器進行遷移
  • 若是能夠(內存資源充足的狀況),儘可能不要使用 swap,swap 的使用會致使內存計算複雜,對調度器很是不友好

docker 限制容器內存使用量app

在 docker 啓動參數中,和內存限制有關的包括(參數的值通常是內存大小,也就是一個正數,後面跟着內存單位 bkmg,分別對應 bytes、KB、MB、和 GB):函數

參數 做用
-m 或 --memory 容器能使用的最大內存大小,最小值爲 4m
--memory-swap 容器可以使用的 swap 大小
--memory-swappiness 默認狀況下,主機能夠把容器使用的匿名頁(anonymous page)swap 出來,你能夠設置一個 0-100 之間的值,表明容許 swap 出來的比例
--memory-reservation 設置一個內存使用的 soft limit,若是 docker 發現主機內存不足,會執行 OOM 操做。這個值必須小於 --memory 設置的值
--kernel-memory 容器可以使用的 kernel memory 大小,最小值爲 4m。
--oom-kill-disable 是否運行 OOM 的時候殺死容器。只有設置了 -m,才能夠把這個選項設置爲 false,不然容器會耗盡主機內存,並且致使主機應用被殺死

關於 --memory-swap 的設置必須解釋一下,--memory-swap 必須在 --memory 也配置的狀況下才能有用。工具

  • 若是 --memory-swap 的值大於 --memory,那麼容器能使用的總內存(內存 + swap)爲 --memory-swap 的值,能使用的 swap 值爲 --memory-swap 減去 --memory 的值
  • 若是 --memory-swap 爲 0,或者和 --memory 的值相同,那麼容器能使用兩倍於內存的 swap 大小,若是 --memory 對應的值是 200M,那麼容器可使用 400M swap
  • 若是 --memory-swap 的值爲 -1,那麼不限制 swap 的使用,也就是說主機有多少 swap,容器均可以使用

實例:

docker run -di --name=os -m=1g centos:latest bash

3、測試

1) 安裝 Docker 容器

$ docker pull centos:latest

2) 運行容器並指定CPU 和內存

$ docker run -di --name=os --cpus=0.2 -m=512MB  centos:latest bash

3) 進入容器並安裝壓測工具

$ docker exec -it os bash

$ yum install wget gcc gcc-c++ make -y
$ yum install -y epel-release
$ yum install stress -y

4) 壓測前觀察 Docker 資源使用狀況

$ docker stats

  5) 壓測CPU

stress --cpu 2 --timeout 600

增長2個 CPU 進程,處理 sqrt() 函數函數,以提升系統CPU負荷,測試600S

6) 觀察 Docker 資源使用狀況

$ docker stats

能夠看到容器 CPU 基本上不能彪到 20%以上了。

7)壓測內存 

$ stress --vm 1 --vm-bytes 1g --timeout 600

新增1個 IO 進程,內存大小爲 1G,發現進程直接被 kill 掉了

相關文章
相關標籤/搜索