伺服器版本 | docker軟體版本 | CPU架構 |
---|---|---|
CentOS Linux release 7.4.1708 (Core) | Docker version 20.10.12 | x86_64 |
預設情況下,容器沒有資源限制,並且可以使用主機核心排程程式允許的儘可能多的給定資源。Docker 提供了控制容器可以使用多少記憶體或 CPU 的方法。
重要的是不要讓正在執行的容器消耗過多的主機記憶體。在 Linux 主機上,如果核心檢測到沒有足夠的記憶體來執行重要的系統功能,它會丟擲一個OOME或 Out Of Memory Exception,並開始殺死程序以釋放記憶體。任何程序都可能被殺死,包括 Docker 和其他重要的應用程式。如果錯誤的程序被殺死,這可以會導致關閉整個系統。
Docker 可以強制執行記憶體硬限制,允許容器使用不超過給定數量的使用者或系統記憶體,或軟限制,允許容器根據需要使用盡可能多的記憶體,除非滿足某些條件,例如何時核心檢測到主機記憶體不足或爭用。其中一些選項在單獨使用或設定多個選項時具有不同的效果。這些選項中的大多數採用正整數,後跟b, k, m, g, 字尾來表示位元組、千位元組、兆位元組或千兆位元組。
常用的引數有:
引數 | 引數解釋 |
---|---|
-m或者--memory= | 容器可以使用的最大記憶體量。如果設定此選項,則允許的最小值為6m(6 兆位元組)。也就是說,您必須將該值設定為至少 6 兆位元組。 |
--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 kill。如果-m未設定該標誌,主機可能會耗盡記憶體,核心可能需要終止主機系統的程序以釋放記憶體。 |
本次主要使用hub.c.163.com/library/centos:latest映象測試,沒有該映象需要自己docker pull一下
[root@k8smaster harbor]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hub.c.163.com/library/centos latest 328edcd84f1b 4 years ago 193MB
上傳memload-7.0-1.r29766.x86_64.rpm安裝包,用於模擬記憶體的使用
[root@k8smaster ~]# mkdir /memload
[root@k8smaster ~]# mv memload-7.0-1.r29766.x86_64.rpm /memload/
使用centos建立一個臨時容器,-v /memload:/memload進行資料卷掛載,使容器/memload目錄下有memload-7.0-1.r29766.x86_64.rpm安裝包
[root@k8smaster ~]# docker run -it --rm -v /memload:/memload hub.c.163.com/library/centos:latest
#在容器裡安裝memload
[root@3c9083a7b318 /]# rpm -ivh /memload/memload-7.0-1.r29766.x86_64.rpm
Preparing... ################################# [100%]
Updating / installing...
1:memload-7.0-1.r29766 ################################# [100%]
#memload 1000使記憶體使用1000M
[root@3c9083a7b318 /]# memload 1000
Attempting to allocate 1000 Mebibytes of resident memory...
^C
[root@3c9083a7b318 /]# exit
exit
當在容器執行memload 1000時,開啟另外一個Linux終端,使用docker stats檢視該容器的記憶體使用,發現此容器使用了1013MiB記憶體,3.32GiB表示物理機的最大記憶體
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
3c9083a7b318 friendly_roentgen 100.71% 1013MiB / 3.32GiB 29.79% 648B / 0B 32.5MB / 19.5MB 2
使用-m對容器的記憶體進行限制,-m 512m:表示容器記憶體最大使用512M,這時如果我們執行memload 1000,使用docker stats檢視,最大記憶體也只能是512M
[root@k8smaster ~]# docker run -it --rm -m 512m -v /memload:/memload hub.c.163.com/library/centos:latest
[root@a81686360ba1 /]#
[root@a81686360ba1 /]# exit
exit
預設情況下,每個容器對主機 CPU 週期的存取是無限制的。您可以設定各種約束來限制給定容器對主機 CPU 週期的存取。大多數使用者使用和設定 預設的 CFS 排程程式。您還可以設定實時排程程式。
CFS 是用於普通 Linux 程序的 Linux 核心 CPU 排程程式。幾個執行時標誌允許您設定對容器擁有的 CPU 資源的存取量。當您使用這些設定時,Docker 會修改主機上容器的 cgroup 的設定。
常用的引數有:
引數 | 引數解釋 |
---|---|
--cpus= |
指定容器可以使用多少可用 CPU 資源。例如,如果主機有兩個 CPU,並且您設定--cpus="1.5"了 ,則容器最多可以保證一個半的 CPU。這相當於設定--cpu-period="100000"和--cpu-quota="150000"。 |
--cpu-period= |
指定 CPU CFS 排程程式週期,它與 --cpu-quota. 預設為 100000 微秒(100 毫秒)。大多數使用者不會更改預設設定。對於大多數用例,--cpus是一種更方便的選擇。 |
--cpu-quota= |
對容器施加 CPU CFS 配額。--cpu-period容器在被限制之前被限制的每微秒數。因此充當有效上限。對於大多數用例,--cpus是一種更方便的選擇。 |
--cpuset-cpus | 限制容器可以使用的特定 CPU 或核心。如果您有多個 CPU,則容器可以使用的逗號分隔列表或連字元分隔的 CPU 範圍。第一個 CPU 編號為 0。有效值可能是0-3(使用第一個、第二個、第三個和第四個 CPU)或1,3(使用第二個和第四個 CPU)。 |
--cpu-shares | 將此標誌設定為大於或小於預設值 1024 的值,以增加或減少容器的重量,並允許它存取或多或少比例的主機 CPU 週期。這僅在 CPU 週期受到限制時才會強制執行。當有足夠多的 CPU 週期可用時,所有容器都會根據需要使用盡可能多的 CPU。這樣,這是一個軟限制。--cpu-shares不會阻止容器以 swarm 模式排程。它優先考慮可用 CPU 週期的容器 CPU 資源。它不保證或保留任何特定的 CPU 存取許可權。 |
對CPU的限制一般是設定CPU的親和性,檢視cpu資訊:兩個CPU:On-line CPU(s) list: 0,1
[root@k8smaster ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 2
座: 1
NUMA 節點: 1
廠商 ID: GenuineIntel
CPU 系列: 6
型號: 142
型號名稱: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
步進: 10
CPU MHz: 1991.381
BogoMIPS: 3984.01
超管理器廠商: VMware
虛擬化型別: 完全
L1d 快取: 32K
L1i 快取: 32K
L2 快取: 256K
L3 快取: 8192K
NUMA 節點0 CPU: 0,1
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec arat
使用centos映象建立容器,裡面執行5個cat程序
[root@k8smaster ~]# docker run -it --rm -v /memload:/memload hub.c.163.com/library/centos:latest
[root@1a4fff793014 /]#
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[1] 15
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[2] 16
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[3] 17
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[4] 18
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[5] 19
[root@1a4fff793014 /]# exit
exit
當在容器執行5個cat程序之後,開啟另外一個Linux終端,檢視每個cat程序執行在哪個CPU上,可以看到cat程序都執行在0號和1號CPU上
[root@k8smaster ~]# ps mo pid,comm,psr `pgrep cat`
PID COMMAND PSR
130120 cat -
- - 0
130143 cat -
- - 1
130144 cat -
- - 0
130145 cat -
- - 1
130146 cat -
- - 1
--cpuset-cpus=0 設定容器裡的程序都執行在0號CPU上
[root@k8smaster ~]# docker run -it --rm --cpuset-cpus=0 -v /memload:/memload hub.c.163.com/library/centos:latest
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[1] 15
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[2] 16
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[3] 17
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[4] 18
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[5] 19
[root@0c3b37f8e679 /]#
[root@0c3b37f8e679 /]# exit
exit
--cpuset-cpus=1 設定容器裡的程序都執行在1號CPU上
[root@k8smaster ~]# docker run -it --rm --cpuset-cpus=1 -v /memload:/memload hub.c.163.com/library/centos:latest
[root@dac513abce35 /]#
[root@dac513abce35 /]# cat /dev/zero > /dev/null &
[1] 15
[root@dac513abce35 /]# cat /dev/zero > /dev/null &
[2] 16
[root@dac513abce35 /]#
[root@dac513abce35 /]# cat /dev/zero > /dev/null &
[3] 17
[root@dac513abce35 /]# cat /dev/zero > /dev/null &
[4] 18
[root@dac513abce35 /]# exit
exit
--cpuset-cpus=0,1 設定容器裡的程序都執行在0,1號CPU上
[root@k8smaster ~]# docker run -it --rm --cpuset-cpus=0,1 -v /memload:/memload hub.c.163.com/library/centos:latest
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[1] 15
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[2] 16
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[3] 17
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[4] 18
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[5] 19
[root@244fe7eb8707 /]#
[root@244fe7eb8707 /]# exit
exit
--cpuset-cpus=0-7,14 設定容器裡的程序都執行在0-7,14號CPU上,由於沒有那麼多CPU所以報錯
[root@k8smaster ~]# docker run -it --rm --cpuset-cpus=0-7,14 -v /memload:/memload hub.c.163.com/library/centos:latest
docker: Error response from daemon: Requested CPUs are not available - requested 0-7,14, available: 0-1.
See 'docker run --help'.
注意:還可以設定容器對NVIDIA GPU 的存取,不過目前暫時沒用到。