1?、限制容器的資源
默認(rèn)情況下,容器沒(méi)有資源限制?,可以使用主機(jī)內(nèi)核調(diào)度程序允許的盡可能多的給定資源。?Docker?提供了控制容器可以使用多少內(nèi)存或?CPU?的方法?,設(shè)置?docker run?命令的運(yùn)行時(shí)配置標(biāo)志。本篇提供有關(guān)何時(shí)應(yīng)設(shè)置此類限制的詳細(xì)信息以及設(shè)置這些限制的可能含義。
其中許多功能都要求您的內(nèi)核支持?Linux?功能?。要檢查支持,可以使用該?docker info?命令。如果內(nèi)核中禁用了某項(xiàng)功能,您可能會(huì)在輸出結(jié)尾處看到一條警告,如下所示:?WARNING: No swap limit support?,請(qǐng)參閱操作系統(tǒng)的文檔以啟用它們,了解更多?。
[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?、內(nèi)存
2.1?內(nèi)存不足的風(fēng)險(xiǎn)
重要的是不要讓正在運(yùn)行的容器占用太多的主機(jī)內(nèi)存。在?Linux?主機(jī)上,如果內(nèi)核檢測(cè)到?jīng)]有足夠的內(nèi)存來(lái)執(zhí)行重要的系統(tǒng)功能,它會(huì)拋出一個(gè)OOME或者Out Of Memory Exception,并開(kāi)始查殺進(jìn)程以釋放內(nèi)存?。任何進(jìn)程都會(huì)被殺死?,包括?Docker?和其他重要的應(yīng)用程序。如果錯(cuò)誤的進(jìn)程被殺死,這可以有效地降低整個(gè)系統(tǒng)。
Docker?嘗試通過(guò)調(diào)整?Docker?守護(hù)程序上的OOM?優(yōu)先級(jí)?來(lái)降低這些風(fēng)險(xiǎn),以便它比系統(tǒng)上的其他進(jìn)程更不可能被殺死?。容器上的?OOM?優(yōu)先級(jí)未調(diào)整。這使得單個(gè)容器被殺死的可能性比?Docker?守護(hù)程序或其他系統(tǒng)進(jìn)程被殺死的可能性更大。您不應(yīng)試圖通過(guò)--oom-score-adj在守護(hù)程序或容器上手動(dòng)設(shè)置為極端負(fù)數(shù)或通過(guò)設(shè)置容器來(lái)繞過(guò)這些安全措施--oom-kill-disable。
有關(guān)?Linux?內(nèi)核的?OOM?管理的更多信息,請(qǐng)參閱內(nèi)存不足管理?。
您可以通過(guò)以下方式降低?OOME?導(dǎo)致系統(tǒng)不穩(wěn)定的風(fēng)險(xiǎn):
在將應(yīng)用程序投入生產(chǎn)之前,請(qǐng)執(zhí)行測(cè)試?以了解應(yīng)用程序的內(nèi)存要求。
確保您的應(yīng)用程序僅在具有足夠資源?的主機(jī)上運(yùn)行。
限制容器可以使用的內(nèi)存量?,如下所述。
在?Docker?主機(jī)上配置交換時(shí)要小心。交換比內(nèi)存更慢且性能更低,但可以提供緩沖?以防止系統(tǒng)內(nèi)存耗盡。
??考慮將容器轉(zhuǎn)換為?服務(wù)?,并使用服務(wù)級(jí)別約束和節(jié)點(diǎn)標(biāo)簽來(lái)確保應(yīng)用程序僅在具有足夠內(nèi)存的主機(jī)上運(yùn)行
2.2?限制容器對(duì)內(nèi)存設(shè)有的設(shè)置
Docker?可以強(qiáng)制執(zhí)行硬內(nèi)存限制?,允許容器使用不超過(guò)給定數(shù)量的用戶或系統(tǒng)內(nèi)存或軟限制,這允許容器使用盡可能多的內(nèi)存,除非滿足某些條件,例如內(nèi)核檢測(cè)到主機(jī)上的低內(nèi)存或爭(zhēng)用。當(dāng)單獨(dú)使用或設(shè)置了多個(gè)選項(xiàng)時(shí),其中一些選項(xiàng)會(huì)產(chǎn)生不同的效果。
大部分的選項(xiàng)取正整數(shù),跟著一個(gè)后綴?b?,?k?,??m?,?g?,,表示字節(jié),千字節(jié),兆字節(jié)或千兆字節(jié)。
選項(xiàng)描述
-m?or?--memory=容器可以使用的最大內(nèi)存量。如果設(shè)置此選項(xiàng),則允許的最小值為4m。
--memory-swap*允許此容器交換到磁盤的內(nèi)存量。
--memory-swappiness默認(rèn)情況下,主機(jī)內(nèi)核可以交換容器使用的匿名頁(yè)面的百分比。您可以設(shè)置--memory-swappiness0?到?100?之間的值,以調(diào)整此百分比。
--memory-reservation允許您指定小于軟件限制的軟限制--memory,當(dāng)?Docker?檢測(cè)到主機(jī)上的爭(zhēng)用或內(nèi)存不足時(shí),該限制將被激活。如果使用--memory-reservation,則必須將其設(shè)置為低于--memory優(yōu)先級(jí)。因?yàn)樗擒浵拗?,所以不保證容器不超過(guò)限制。
--kernel-memory容器可以使用的最大內(nèi)核內(nèi)存量。允許的最小值是4m。由于內(nèi)核內(nèi)存無(wú)法換出,因此內(nèi)核內(nèi)存不足的容器可能會(huì)阻塞主機(jī)資源,這可能會(huì)對(duì)主機(jī)和其他容器產(chǎn)生副作用。
--oom-kill-disable默認(rèn)情況下,如果發(fā)生內(nèi)存不足(?OOM?)錯(cuò)誤,內(nèi)核會(huì)終止容器中的進(jìn)程。要更改此行為,請(qǐng)使用該--oom-kill-disable選項(xiàng)。僅在已設(shè)置-m/--memory選項(xiàng)的容器上禁用?OOM?殺手。如果-m未設(shè)置該標(biāo)志,則主機(jī)可能會(huì)耗盡內(nèi)存,并且內(nèi)核可能需要終止主機(jī)系統(tǒng)的進(jìn)程才能釋放內(nèi)存。
2.2.1 --memory-swap?設(shè)置
(?1?)介紹
--memory-swap?是一個(gè)修飾符標(biāo)志,只有在?--memory?設(shè)置時(shí)才有意義。使用?swap允許容器在容器耗盡可用的所有?RAM?時(shí)將多余的內(nèi)存需求寫入磁盤。對(duì)于經(jīng)常將內(nèi)存交換到磁盤的應(yīng)用程序,性能會(huì)受到影響。
(?2?)它的設(shè)置會(huì)產(chǎn)生復(fù)雜的效果:
如果?--memory-swap?設(shè)置為正整數(shù)?,那么這兩個(gè)?--memory?和?--memory-swap必須設(shè)置。--memory-swap?表示可以使用的?memory and swap?,并--memory控制非交換內(nèi)存?(?物理內(nèi)存?)?使用的量。所以如果?--memory="300m"?和?--memory-swap="1g"?,容器可以使用?300?米的內(nèi)存和?700?米(1g - 300m)?swap?。
如果--memory-swap?設(shè)置為?0?,則忽略該設(shè)置?,并將該值視為未設(shè)置。
如果--memory-swap?設(shè)置為與值相同的值?--memory?,并且--memory?設(shè)置為正整數(shù)?,則容器無(wú)權(quán)訪問(wèn)?swap?。請(qǐng)參考下面阻止容器使用交換。
如果--memory-swap?未設(shè)置?并--memory?設(shè)置?,則容器可以使用兩倍于?--memory?設(shè)置?的?swap?,主機(jī)容器需要配置有?swap?。例如,如果設(shè)置?--memory="300m"?和?--memory-swap?未設(shè)置,容器可以使用?300?米的內(nèi)存和?600?米的?swap。
如果--memory-swap?明確設(shè)置為?-1?,則允許容器使用無(wú)限制?swap?,最多可達(dá)宿主機(jī)系統(tǒng)上可用的數(shù)量?。
在容器內(nèi)部,工具如?free?報(bào)告主機(jī)的?swap?,而不是容器內(nèi)真正可用的內(nèi)存。不要依賴?free?或類似工具來(lái)確定是否存在?swap?。
(?3?)防止容器使用交換
如果--memory?和?--memory-swap?設(shè)置為相同的值?,則可以防止容器使用?swap。這是因?yàn)?--memory-swap?可以使用的?memory and swap?,而?--memory?只是可以使用的物理內(nèi)存量。
2.2.2 --memory-swappiness?設(shè)置
??值為?0?將關(guān)閉匿名頁(yè)面交換。
??值?100?將所有匿名頁(yè)面設(shè)置為可交換。
??默認(rèn)情況下,如果未設(shè)置?--memory-swappiness?,則值將從主機(jī)繼承。
2.2.3 --kernel-memory?設(shè)置
(?1?)介紹
內(nèi)核內(nèi)存限制以分配給容器的總內(nèi)存表示。請(qǐng)考慮以下方案:
無(wú)限內(nèi)存,無(wú)限內(nèi)核內(nèi)存?:這是默認(rèn)設(shè)置。
無(wú)限內(nèi)存,有限的內(nèi)核內(nèi)存?:當(dāng)所有?cgroup?所需的內(nèi)存量大于主機(jī)上實(shí)際存在的內(nèi)存量時(shí),這是合適的。您可以將內(nèi)核內(nèi)存配置為永遠(yuǎn)不會(huì)覆蓋主機(jī)上可用的內(nèi)容,而需要更多內(nèi)存的容器需要等待它。
有限的內(nèi)存,無(wú)限的內(nèi)核內(nèi)存?:整體內(nèi)存有限,但內(nèi)核內(nèi)存不受限制。
有限的內(nèi)存,有限的內(nèi)核內(nèi)存?:限制用戶和內(nèi)核內(nèi)存對(duì)于調(diào)試與內(nèi)存相關(guān)的問(wèn)題非常有用。如果容器使用意外數(shù)量的任一類型的內(nèi)存,則內(nèi)存不足而不會(huì)影響其他容器或主機(jī)。在此設(shè)置中,如果內(nèi)核內(nèi)存限制低于用戶內(nèi)存限制,則內(nèi)核內(nèi)存不足會(huì)導(dǎo)致容器遇到?OOM?錯(cuò)誤。如果內(nèi)核內(nèi)存限制高于用戶內(nèi)存限制,則內(nèi)核限制不會(huì)導(dǎo)致容器遇到?OOM?。
當(dāng)您打開(kāi)任何內(nèi)核內(nèi)存限制時(shí),主機(jī)會(huì)根據(jù)每個(gè)進(jìn)程跟蹤?“?高水位線?”?統(tǒng)計(jì)信息,因此您可以跟蹤哪些進(jìn)程(在本例中為容器)正在使用多余的內(nèi)存。通過(guò)?/proc/<PID>/status?在主機(jī)上查看,可以在每個(gè)過(guò)程中看到這一點(diǎn)。
3?、?CPU
默認(rèn)情況下,每個(gè)容器對(duì)主機(jī)?CPU?周期的訪問(wèn)權(quán)限是不受限制的?。
??您可以設(shè)置各種約束來(lái)限制給定容器訪問(wèn)主機(jī)的?CPU?周期。
??大多數(shù)用戶使用和配置?默認(rèn)?CFS?調(diào)度程序。
??在?Docker 1.13?及更高版本中,您還可以配置 實(shí)時(shí)調(diào)度程序。
3.1?配置默認(rèn)?CFS?調(diào)度程序
CFS?是用于普通?Linux?進(jìn)程的?Linux?內(nèi)核?CPU?調(diào)度程序。多個(gè)運(yùn)行時(shí)標(biāo)志允許您配置容器具有的?CPU?資源訪問(wèn)量。使用這些設(shè)置時(shí),?Docker?會(huì)修改主機(jī)上容器的?cgroup?的設(shè)置。
選項(xiàng)描述
--cpus=<value>指定容器可以使用的可用?CPU?資源量?。例如,如果主機(jī)有兩個(gè)?CPU?并且你已設(shè)置?--cpus="1.5"?,則容器最多保證一個(gè)半?CPU?。這相當(dāng)于設(shè)置?--cpu-period="100000"和?--cpu-quota="150000"???稍?Docker 1.13?及更高版本中使用。
--cpu-period=<value>指定?CPU CFS?調(diào)度程序周期,它與并用??--cpu-quota。默認(rèn)為?100?微秒。大多數(shù)用戶不會(huì)更改默認(rèn)設(shè)置。如果您使用?Docker 1.13?或更高版本,請(qǐng)?--cpus?使用。
--cpu-quota=<value>對(duì)容器施加?CPU CFS?配額。?--cpu-period?限制前容器限制為每秒的微秒數(shù)。作為有效上限。如果您使用?Docker 1.13?或更高版本,請(qǐng)?--cpus?改用。
--cpuset-cpus限制容器可以使用的特定?CPU?或核心?。如果您有多個(gè)CPU?,則容器可以使用逗號(hào)分隔列表或連字符分隔的?CPU?范圍。第一個(gè)?CPU?編號(hào)為?0.?有效值可能是?0-3?(使用第一個(gè),第二個(gè),第三個(gè)和第四個(gè)?CPU?)或?1,3?(使用第二個(gè)和第四個(gè)?CPU?)。
--cpu-shares將此標(biāo)志設(shè)置為大于或小于默認(rèn)值?1024?的值,以增加或減少容器的重量,并使其可以訪問(wèn)主機(jī)的?CPU?周期的較大或較小比例。僅在?CPU?周期受限時(shí)才會(huì)強(qiáng)制執(zhí)行此操作。當(dāng)有足夠的?CPU?周期時(shí),所有容器都會(huì)根據(jù)需要使用盡可能多的?CPU?。這樣,這是一個(gè)軟限制。?--cpu-shares?不會(huì)阻止容器以群集模式進(jìn)行調(diào)度。它為可用的?CPU?周期優(yōu)先考慮容器?CPU?資源。它不保證或保留任何特定的?CPU?訪問(wèn)權(quán)限。
4?、操作演示
4.1?準(zhǔn)備工作
(?1?)先查詢宿主機(jī)的資源:
[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? 內(nèi)存、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?下載一個(gè)用于壓測(cè)的鏡像
[root@docker ~]# docker pull lorel/docker-stress-ng
(?3?)該壓測(cè)鏡像的使用方法
[root@docker ~]# docker run --name stress --rm lorel/docker-stress-ng:latest stress --help
使用?--help?可以查詢此壓測(cè)鏡像的用法
例:
stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s
語(yǔ)法:
?-c N, --cpu N?啟動(dòng)?N?個(gè)子進(jìn)程(?cpu?)
?--vm N?啟動(dòng)?N?個(gè)進(jìn)程對(duì)內(nèi)存進(jìn)行壓測(cè)
?--vm-bytes 128M?每個(gè)子進(jìn)程使用多少內(nèi)存(默認(rèn)?256M?)
4.2?測(cè)試內(nèi)存限制
(?1?)現(xiàn)在最大使用內(nèi)存啟動(dòng)容器
[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?內(nèi)存;
?--vm 2 ???啟動(dòng)壓測(cè)容器,使用?256x2=512m?的內(nèi)存;
?docker stats?結(jié)果查詢,容器實(shí)際使用內(nèi)存不能超過(guò)?256m
4.3?測(cè)試?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?核數(shù)
[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
歡迎歡迎學(xué)Java的朋友們加入java架構(gòu)交流: 855835163
群內(nèi)提供免費(fèi)的Java架構(gòu)學(xué)習(xí)資料(里面有高可用、高并發(fā)、高性能及分布式、Jvm性能調(diào)優(yōu)、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個(gè)知識(shí)點(diǎn)的架構(gòu)資料)合理利用自己每一分每一秒的時(shí)間來(lái)學(xué)習(xí)提升自己,不要再用"沒(méi)有時(shí)間“來(lái)掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來(lái)的自己一個(gè)交代!