Docker的系統(tǒng)資源限制及驗(yàn)證

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è)交代!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容