Docker的系統資源限制及驗證

1 、限制容器的資源

默認狀況下, 容器沒有資源限制 ,可使用主機內核調度程序容許的儘量多的給定資源。 Docker 提供了控制容器能夠 使用多少內存或 CPU 的方法 ,設置 docker run 命令的運行時配置標誌。本篇提供有關什麼時候應設置此類限制的詳細信息以及設置這些限制的可能含義。html

其中許多功能都要求您的 內核支持 Linux 功能 。要檢查支持,可使用該 docker info 命令。若是內核中禁用了某項功能,您可能會在輸出結尾處看到一條警告,以下所示: WARNING: No swap limit support ,請參閱操做系統的文檔以啓用它們, 瞭解更多 java

[root@along ~]# docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 43
Server Version: 17.03.2-ce
Storage Driver: overlay
 Backing Filesystem: xfs
 Supports d_type: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 4ab9917febca54791c5f071a9d1f404867857fcc
runc version: 54296cf40ad8143b62dbcaa1d90e520a2136ddfe
init version: 949e6fa
Security Options:
 seccomp
  Profile: default
Kernel Version: 3.10.0-514.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 976.5 MiB
Name: along
ID: KGWA:GDGT:PTK7:PAX4:A3JZ:LV6N:U5QD:UQCY:AGZV:P32E:V73T:JJHR
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: alongedu
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
 docker2:80
 127.0.0.0/8
Registry Mirrors:
 https://registry.docker-cn.com
Live Restore Enabled: false

2 、內存

2.1 內存不足的風險

重要的是不要讓正在運行的容器佔用太多的主機內存。在 Linux 主機上,若是內核檢測到沒有足夠的內存來執行重要的系統功能,它會拋出一個 OOME 或者 Out Of Memory Exception ,並 開始查殺進程以釋放內存 。 任何進程都會被殺死 ,包括 Docker 和其餘重要的應用程序。若是錯誤的進程被殺死,這能夠有效地下降整個系統。node

Docker 嘗試經過調整 Docker 守護程序上的 OOM 優先級 來下降這些風險, 以便它比系統上的其餘進程更不可能被殺死 。容器上的 OOM 優先級未調整。這使得單個容器被殺死的可能性比 Docker 守護程序或其餘系統進程被殺死的可能性更大。您不該試圖經過 --oom-score-adj 在守護程序或容器上手動設置爲極端負數或經過設置容器來繞過這些安全措施 --oom-kill-disable 。linux

有關 Linux 內核的 OOM 管理的更多信息,請參閱 內存不足管理 sql

您能夠經過如下方式下降 OOME 致使系統不穩定的風險:docker

  •   在將應用程序投入生產以前,請執行 測試 以瞭解應用程序的內存要求。
  •   確保您的應用程序 僅在具備足夠資源 的主機上運行。
  •   限制容器可使用的內存量 ,以下所述。
  •   在 Docker 主機上配置交換時要當心。交換比內存更慢且性能更低,但能夠 提供緩衝 以防止系統內存耗盡。
  •   考慮將容器轉換爲 服務 ,並使用服務級別約束和節點標籤來確保應用程序僅在具備足夠內存的主機上運行

2.2 限制容器對內存設有的設置

Docker 能夠 強制執行硬內存限制 ,容許容器使用不超過給定數量的用戶或系統內存或軟限制,這容許容器使用盡量多的內存,除非知足某些條件,例如內核檢測到主機上的低內存或爭用。當單獨使用或設置了多個選項時,其中一些選項會產生不一樣的效果。json

大部分的選項取正整數,跟着一個後綴 b , k ,  m , g ,,表示字節,千字節,兆字節或千兆字節。安全

選項

描述

-m or --memory=

容器可使用的最大內存量。若是設置此選項,則容許的最小值爲 4m 。架構

--memory-swap*

容許此容器交換到磁盤的內存量。併發

--memory-swappiness

默認狀況下,主機內核能夠交換容器使用的匿名頁面的百分比。您能夠設置 --memory-swappiness 0 到 100 之間的值,以調整此百分比。

--memory-reservation

容許您指定小於軟件限制的軟限制 --memory ,當 Docker 檢測到主機上的爭用或內存不足時,該限制將被激活。若是使用 --memory-reservation ,則必須將其設置爲低於 --memory 優先級。由於它是軟限制,因此不保證容器不超過限制。

--kernel-memory

容器可使用的最大內核內存量。容許的最小值是 4m。因爲內核內存沒法換出,所以內核內存不足的容器可能會阻塞主機資源,這可能會對主機和其餘容器產生反作用。

--oom-kill-disable

默認狀況下,若是發生內存不足( OOM )錯誤,內核會終止容器中的進程。要更改此行爲,請使用該 --oom-kill-disable 選項。僅在已設置 -m/--memory 選項的容器上禁用 OOM 殺手。若是 -m 未設置該標誌,則主機可能會耗盡內存,而且內核可能須要終止主機系統的進程才能釋放內存。

2.2.1 --memory-swap 設置

( 1 )介紹

--memory-swap 是一個修飾符標誌,只有在 --memory 設置時纔有意義。使用 swap容許容器在容器耗盡可用的全部 RAM 時將多餘的內存需求寫入磁盤。對於常常將內存交換到磁盤的應用程序,性能會受到影響。

( 2 )它的設置會產生複雜的效果:

  •   若是 - -memory-swap 設置爲正整數 ,那麼這兩個 --memory 和 --memory-swap必須設置。 --memory-swap 表示可使用的 memory and swap ,並 --memory控制非交換內存 ( 物理內存 ) 使用的量。因此若是 --memory="300m" 和 --memory-swap="1g" ,容器可使用 300 米的內存和 700 米( 1g - 300m ) swap 。
  •   若是 --memory-swap 設置爲 0 ,則 忽略該設置 ,並將該值視爲未設置。
  •   若是 --memory-swap 設置爲與值相同的值 --memory ,而且 --memory 設置爲正整數 ,則 容器無權訪問 swap 。請參考下面阻止容器使用交換。
  •   若是 --memory-swap 未設置 並 --memory 設置 ,則容器能夠 使用兩倍於 --memory 設置 的 swap ,主機容器須要配置有 swap 。例如,若是設置 --memory="300m" 和 --memory-swap 未設置,容器可使用 300 米的內存和 600 米的 swap。
  •   若是 --memory-swap 明確設置爲 -1 ,則容許 容器使用無限制 swap ,最多可達宿主機系統上可用的數量 
  •   在容器內部,工具如 free 報告主機的 swap ,而不是容器內真正可用的內存。 不要依賴 free   或相似工具來肯定是否存在 swap 。

( 3 )防止容器使用交換

若是 --memory 和 --memory-swap 設置爲相同的值 ,則 能夠防止容器使用 swap。這是由於 --memory-swap 可使用的 memory and swap ,而 --memory 只是可使用的物理內存量。

2.2.2 --memory-swappiness 設置

  •   值爲 0 將關閉匿名頁面交換。
  •   值 100 將全部匿名頁面設置爲可交換。
  •   默認狀況下,若是未設置 --memory-swappiness ,則值將從主機繼承。

2.2.3 --kernel-memory 設置

( 1 )介紹

內核內存限制以分配給容器的總內存表示。請考慮如下方案:

  •   無限內存,無限內核內存 :這是默認設置。
  •   無限內存,有限的內核內存 :當全部 cgroup 所需的內存量大於主機上實際存在的內存量時,這是合適的。您能夠將內核內存配置爲永遠不會覆蓋主機上可用的內容,而須要更多內存的容器須要等待它。
  •   有限的內存,無限的內核內存 :總體內存有限,但內核內存不受限制。
  •   有限的內存,有限的內核內存 :限制用戶和內核內存對於調試與內存相關的問題很是有用。若是容器使用意外數量的任一類型的內存,則內存不足而不會影響其餘容器或主機。在此設置中,若是內核內存限制低於用戶內存限制,則內核內存不足會致使容器遇到 OOM 錯誤。若是內核內存限制高於用戶內存限制,則內核限制不會致使容器遇到 OOM 。

當您打開任何內核內存限制時,主機會根據每一個進程跟蹤 「 高水位線 」 統計信息,所以您能夠跟蹤哪些進程(在本例中爲容器)正在使用多餘的內存。經過 /proc/<PID>/status 在主機上查看,能夠在每一個過程當中看到這一點。

3 、 CPU

  •   默認狀況下,每一個容器對主機 CPU 週期的訪問權限是 不受限制的 
  •   您能夠設置各類約束來限制給定容器訪問主機的 CPU 週期。
  •   大多數用戶使用和配置 默認 CFS 調度程序。
  •   在 Docker 1.13 及更高版本中,您還能夠配置 實時調度程序。

3.1 配置默認 CFS 調度程序

CFS 是用於普通 Linux 進程的 Linux 內核 CPU 調度程序。多個運行時標誌容許您配置容器具備的 CPU 資源訪問量。使用這些設置時, Docker 會修改主機上容器的 cgroup 的設置。

選項

描述

--cpus=<value>

指定容器 可使用的可用 CPU 資源量 。例如,若是主機有兩個 CPU 而且你已設置 --cpus="1.5" ,則容器最多保證一個半 CPU 。這至關於設置 --cpu-period="100000"和 --cpu-quota="150000" 。可在 Docker 1.13 及更高版本中使用。

--cpu-period=<value>

指定 CPU CFS 調度程序週期,它與並用  --cpu-quota。默認爲 100 微秒。大多數用戶不會更改默認設置。若是您使用 Docker 1.13 或更高版本,請 --cpus 使用。

--cpu-quota=<value>

對容器施加 CPU CFS 配額。 --cpu-period 限制前容器限制爲每秒的微秒數。做爲有效上限。若是您使用 Docker 1.13 或更高版本,請 --cpus 改用。

--cpuset-cpus

限制容器能夠 使用的特定 CPU 或核心 。若是您有多個CPU ,則容器可使用逗號分隔列表或連字符分隔的 CPU 範圍。第一個 CPU 編號爲 0. 有效值多是 0-3 (使用第一個,第二個,第三個和第四個 CPU )或 1,3 (使用第二個和第四個 CPU )。

--cpu-shares

將此標誌設置爲大於或小於默認值 1024 的值,以增長或減小容器的重量,並使其能夠訪問主機的 CPU 週期的較大或較小比例。僅在 CPU 週期受限時纔會強制執行此操做。當有足夠的 CPU 週期時,全部容器都會根據須要使用盡量多的 CPU 。這樣,這是一個軟限制。 --cpu-shares 不會阻止容器以羣集模式進行調度。它爲可用的 CPU 週期優先考慮容器 CPU 資源。它不保證或保留任何特定的 CPU 訪問權限。

4 、操做演示

4.1 準備工做

( 1 )先查詢宿主機的資源:

[root@docker ~]# lscpu   CPU資源
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             4
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 60
Model name:            Intel(R) Xeon(R) CPU E3-1231 v3 @ 3.40GHz
Stepping:              3
CPU MHz:               3395.854
BogoMIPS:              6792.17
Hypervisor vendor:     VMware
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-3
[root@docker ~]# free -h   內存、swap資源
              total        used        free      shared  buff/cache   available
Mem:           7.8G        193M        7.2G        8.6M        438M        7.3G
Swap:          2.0G        400K        2.0G

 

( 2 )在 dockerhub 下載一個用於壓測的鏡像

[root@docker ~]# docker pull lorel/docker-stress-ng

 

( 3 )該壓測鏡像的使用方法

[root@docker ~]# docker run --name stress --rm lorel/docker-stress-ng:latest stress --help

使用 --help 能夠查詢此壓測鏡像的用法

例:

stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s

語法:

  •  -c N, --cpu N 啓動 N 個子進程( cpu )
  •  --vm N 啓動 N 個進程對內存進行壓測
  •  --vm-bytes 128M 每一個子進程使用多少內存(默認 256M )

4.2 測試內存限制

( 1 )如今最大使用內存啓動容器

[root@docker ~]# docker run --name stress --rm -m 256m lorel/docker-stress-ng:latest stress --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

[root@docker ~]# docker stats stress
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
e1fdb0520bad        stress              8.22%               254MiB / 256MiB     99.22%              648B / 0B           46.9MB / 3.63GB     5

註釋:

  •  -m 256m 限制此容器最大隻能使用 256m 內存;
  •  --vm 2    啓動壓測容器,使用 256x2=512m 的內存;
  •  docker stats 結果查詢,容器實際使用內存不能超過 256m

4.3 測試 CPU 限制

( 1 )限制最大使用 2 核 CPU

[root@docker ~]# docker run --name stress --rm --cpus 2 lorel/docker-stress-ng:latest stress --cpu 8
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 8 cpu

[root@docker ~]# docker stats stress
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
ca86c0de6431        stress              199.85%             15.81MiB / 7.781GiB   0.20%               648B / 0B           0B / 0B             9

 

( 2 )不限制使用 CPU 核數

[root@docker ~]# docker run --name stress --rm lorel/docker-stress-ng:latest stress --cpu 8
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 8 cpu

[root@docker ~]# docker stats stress
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
167afeac7c97        stress              399.44%             15.81MiB / 7.781GiB   0.20%               508B / 0B           0B / 0B             9

歡迎歡迎學Java的朋友們加入java架構交流: 855835163 羣內提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用本身每一分每一秒的時間來學習提高本身,不要再用"沒有時間「來掩飾本身思想上的懶惰!趁年輕,使勁拼,給將來的本身一個交代!

相關文章
相關標籤/搜索