默認情況下,一個容器并沒有資源限制,并且該容器可以使用內(nèi)核調(diào)度的所有資源。Docke提供了在啟動容器時設置一些參數(shù)來控制該容器使用的內(nèi)存、CPU和block IO。
銅川網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、APP開發(fā)、成都響應式網(wǎng)站建設公司等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)公司2013年開創(chuàng)至今到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設就選成都創(chuàng)新互聯(lián)公司。
真正可以控制的只有內(nèi)存和CPU。。
內(nèi)存是不可壓縮資源
在Linxu系統(tǒng)中,如果內(nèi)核探測到宿主機沒有足夠的內(nèi)存來調(diào)用執(zhí)行系統(tǒng)的某些重要功能的時候,那么會拋出一個OOME(Out Of Memory Exception:內(nèi)存異常)殺死某些進程,以此來釋放內(nèi)存。
一旦發(fā)生OOME,任何進程都有可能被殺死,包括docker daemon在內(nèi)。為此,Docker特地調(diào)整了docker daemon的OOM優(yōu)先級,防止其被殺死,但是容器的優(yōu)先級沒有被調(diào)整。在內(nèi)存不足時,內(nèi)核會根據(jù)自己的調(diào)度算法,為每個進程得出一個評分,然后殺死分數(shù)最高的進程來釋放內(nèi)存。
可以在docker run的時候指定--oom-score-adj參數(shù)(默認為0)。這個是容器被殺死的優(yōu)先級,會影響評分,值越大越容易被殺死。這個參數(shù)只是影響最終的評分,優(yōu)先殺死進程是看評分,參數(shù)小的可能計算后分數(shù)仍然最高,依然會被優(yōu)先殺掉。
可以指定–oom-kill-disable=true參數(shù),指定一些特定的重要的容器禁止被OOM殺掉。
--oom-kill-disable Disable OOM Killer
--oom-score-adj int Tune host's OOM preferences (-1000 to 1000)
選項 | 描述 |
---|---|
-m,--memory | 內(nèi)存限制,格式是數(shù)字加單位,單位可以為 b,k,m,g。最小為4M |
--memory-swap | 內(nèi)存+交換分區(qū)大小總限制。格式同上。必須比-m設置的大 |
--memory-swappiness | 默認情況下,主機可以把容器使用的匿名頁(anonymous page)swap 出來,你可以設置一個 0-100 之間的值,代表允許 swap 出來的比例 |
--memory-reservation | 設置一個內(nèi)存使用的 soft limit,如果 docker 發(fā)現(xiàn)主機內(nèi)存不足,會執(zhí)行 OOM 操作。這個值必須小于 --memory 設置的值 |
--kernel-memory | 容器能夠使用的 kernel memory 大小,最小值為 4m |
--oom-kill-disable | 是否運行 OOM 的時候殺死容器。只有設置了 -m,才可以把這個選項設置為 false,否則容器會耗盡主機內(nèi)存,而且導致主機應用被殺死 |
--memory-swap參數(shù)
這個參數(shù)要結(jié)合-m一起生效,表格中的描述比較簡單,是一般的用法。
一般用法:比-m大,內(nèi)存+交換分區(qū)大小總限制
禁用swap:和-m一樣大,這樣--memory和--memory-swap的限制是一樣大,可用的swap資源為0,相當于禁用。
默認設置:設置為0或者不設置,如果主機(Docker Host)啟用了swap,則容器可用的swap為內(nèi)存限制的2倍。
無限制:設置為-1,如果主機(Docker Host)啟用了swap,則容器可使用宿主機所有的swap資源。
在容器內(nèi)使用free命令,看到的swap空間沒有體現(xiàn)出上面這些限制,沒有參考價值。
CPU是可壓縮資源。
默認情況下,每一個容器可以使用宿主機上的所有cpu資源。大多數(shù)系統(tǒng)使用的資源調(diào)度算法是CFS(完全公平調(diào)度器),它公平調(diào)度每一個工作進程。進程可以分2類:CPU密集型(低優(yōu)先級)和IO密集型(高優(yōu)先級)。系統(tǒng)內(nèi)核實時監(jiān)測系統(tǒng)進程,當某個進程占用cpu資源時間過長時,內(nèi)核會調(diào)整該進程的優(yōu)先級。
docker 1.13 之后還支持realtime調(diào)度。
有如下的3種CPU資源分配策略:
選項 | 描述 | |
---|---|---|
-c, --cpu-shares int | cpu資源提供給一組容器使用,組內(nèi)的容器按比例使用cpu資源,當容器處于空閑狀態(tài)時,cpu資源被負載大的容器占用,(按壓縮方式比例分配),當空閑進行運行起來時,cpu資源會被分配到其他容器 | |
--cpus decimal | 指定 cpu的核心數(shù)量,這種方式直接限定了容器可用的cpu資源 | |
--cpuset-cpus string | 指定容器只能運行在哪個cpu核心上(綁定cpu);核心使用0,1,2,3編號 |
docker 為容器設置 CPU share 的參數(shù)是 -c, --cpu-shares,它的值是一個整數(shù)。
docker 允許用戶為每個容器設置一個數(shù)字,代表容器的 CPU share,默認情況下每個容器的 share 是 1024。當主機上有多個容器運行時,每個容器占用的 CPU 時間比例為它的 share 在總額中的比例。舉個例子,如果主機上有兩個一直使用 CPU 的容器(為了簡化理解,不考慮主機上其他進程),其 CPU share 都是 1024,那么兩個容器 CPU 使用率都是 50%;如果把其中一個容器的 share 設置為 512,那么兩者 CPU 的使用率分別為 67% 和 33%;如果刪除 share 為 1024 的容器,剩下來容器的 CPU 使用率將會是 100%。
總結(jié)下來,這種情況下,docker 會根據(jù)主機上運行的容器和進程動態(tài)調(diào)整每個容器使用 CPU 的時間比例。這樣的好處是能保證 CPU 盡可能處于運行狀態(tài),充分利用 CPU 資源,而且保證所有容器的相對公平;缺點是無法指定容器使用 CPU 的確定值。
從 1.13 版本之后,docker 提供了 --cpus 參數(shù)可以限定容器能使用的 CPU 核數(shù)。這個功能可以讓我們更精確地設置容器 CPU 使用量,是一種更容易理解也因此更常用的手段。
--cpus 后面跟著一個浮點數(shù),代表容器最多使用的核數(shù),可以精確到小數(shù)點二位,也就是說容器最小可以使用 0.01 核 CPU。比如,我們可以限制容器只能使用 1.5 核數(shù) CPU。
如果設置的 --cpus 值大于主機的 CPU 核數(shù),docker 會直接報錯。
如果多個容器都設置了 --cpus,并且它們之和超過主機的 CPU 核數(shù),并不會導致容器失敗或者退出,這些容器之間會競爭使用 CPU,具體分配的 CPU 數(shù)量取決于主機運行情況和容器的 CPU share 值。也就是說 --cpus 只能保證在 CPU 資源充足的情況下容器最多能使用的 CPU 數(shù),docker 并不能保證在任何情況下容器都能使用這么多的 CPU(因為這根本是不可能的)。
Docker 允許調(diào)度的時候限定容器運行在哪個 CPU 上。可以通過 --cpuset-cpus 參數(shù)讓容器只運行在某個或某幾個核上。
--cpuset-cpus、-cpus 參數(shù)可以和 -c, --cpu-shares 一起使用,限制容器只能運行在某些 CPU 核上,并且配置了使用率。
限制容器運行在哪些核上并不是一個很好的做法,因為它需要事先知道主機上有多少 CPU 核,而且非常不靈活。除非有特別的需求,一般并不推薦在生產(chǎn)中這樣使用。
選項 | 描述 |
---|---|
--cpu-period int | 指定CFS調(diào)度的周期,一般與--cpu-quota一起使用。默認情況下周期為1 秒,以微秒為單位表示,一般使用默認值。1.13或者更高版本推薦使用 --cpus 標志代替。 |
--cpu-quota int | 在CFS調(diào)度中容器一個周期的cpu時間配額,即每個--cpu-period周期容器可獲得的cpu時間(微秒),cpu-quota/cpu-period。1.13或者更高版本推薦使用 --cpus 標志代替。 |
資源限制的演示
這里用了lscpu和free命令:
[root@Docker ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 1
On-line CPU(s) list: 0
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 60
Model name: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
Stepping: 3
CPU MHz: 3999.996
BogoMIPS: 7999.99
Hypervisor vendor: Microsoft
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 8192K
NUMA node0 CPU(s): 0
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm ssbd ibrs ibpb stibp fsgsbase bmi1 avx2 smep bmi2 erms invpcid xsaveopt spec_ctrl intel_stibp flush_l1d
[root@Docker ~]# free -h
total used free shared buff/cache available
Mem: 936M 260M 340M 6.7M 334M 592M
Swap: 1.6G 0B 1.6G
[root@Docker ~]#
可以在docker hub上搜索stress(壓測)。
下載鏡像,運行查看幫助:
[root@Docker ~]# docker pull lorel/docker-stress-ng
[root@Docker ~]# docker run -it --rm lorel/docker-stress-ng
stress-ng, version 0.03.11
Usage: stress-ng [OPTION [ARG]]
--h, --help show help
......省略......
Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s
Note: Sizes can be suffixed with B,K,M,G and times with s,m,h,d,y
[root@Docker ~]#
主要命令參數(shù):
查看lorel/docker-stress-ng里內(nèi)存相關(guān)的參數(shù)說明:
-m N, --vm N start N workers spinning on anonymous mmap
--vm-bytes N allocate N bytes per vm worker (default 256MB)
默認每個worker是256MB的內(nèi)存,這個保持默認。然后指定--vm,開啟2個worker,并且限制容器的內(nèi)存只能使用256MB,啟動容器:
[root@Docker ~]# docker run --name stress1 -it --rm -m 256m lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm
這個終端已經(jīng)被占用了,另起一個終端使用docker top命令查看容器內(nèi)部正在運行的進程:
[root@Docker ~]# docker top stress1
UID PID PPID C STIME TTY TIME CMD
root 5922 5907 0 21:06 pts/0 00:00:00 /usr/bin/stress-ng --vm 2
root 6044 5922 0 21:06 pts/0 00:00:00 /usr/bin/stress-ng --vm 2
root 6045 5922 0 21:06 pts/0 00:00:00 /usr/bin/stress-ng --vm 2
root 6086 6044 13 21:06 pts/0 00:00:00 /usr/bin/stress-ng --vm 2
root 6097 6045 47 21:06 pts/0 00:00:00 /usr/bin/stress-ng --vm 2
[root@Docker ~]#
這里可以看一下PID和PPID,這里一共5個進程,一個父進程創(chuàng)建了2個子進程,這2個子進程又分別各創(chuàng)建了一個進程。
另外還可以使用命令docker stats查看容器的資源實時使用的情況:
$ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
626f38c4a4ad stress1 18.23% 256MiB / 256MiB 100.00% 656B / 0B 17.7MB / 9.42GB 5
這個是實時刷新的。
限制容器最大只能使用2核,然后同時開啟8個CPU進行壓測,使用下面的命令:
docker run -it --rm --cpus 2 lorel/docker-stress-ng --cpu 8
限制只用0.5核,開啟4個CPU進行壓測:
[root@Docker ~]# docker run --name stress2 -it --rm --cpus 0.5 lorel/docker-stress-ng --cpu 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu
另起一個終端使用docker top命令查看容器內(nèi)部正在運行的進程:
[root@Docker ~]# docker top stress2
UID PID PPID C STIME TTY TIME CMD
root 7198 7184 0 22:35 pts/0 00:00:00 /usr/bin/stress-ng --cpu 4
root 7230 7198 12 22:35 pts/0 00:00:02 /usr/bin/stress-ng --cpu 4
root 7231 7198 12 22:35 pts/0 00:00:02 /usr/bin/stress-ng --cpu 4
root 7232 7198 12 22:35 pts/0 00:00:02 /usr/bin/stress-ng --cpu 4
root 7233 7198 12 22:35 pts/0 00:00:02 /usr/bin/stress-ng --cpu 4
[root@Docker ~]#
一個父進程,創(chuàng)建了4個子進程。
然后再用docker stats命令查看資源占用:
$ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
14a341dd23d1 stress2 50.02% 13.75MiB / 908.2MiB 1.51% 656B / 0B 0B / 0B 5
因為限制了0.5核,所以基本不會超過50%。
開啟3個容器,分別指定不同的--cpu-shares參數(shù),不指定的話默認是1024:
[root@Docker ~]# docker run --name stress3.1 -itd --rm --cpu-shares 512 lorel/docker-stress-ng --cpu 4
800d756f76ca4cf20af9fa726349f25e29bc57028e3a1cb738906a68a87dcec4
[root@Docker ~]# docker run --name stress3.2 -itd --rm lorel/docker-stress-ng --cpu 4
4b88007191812b239592373f7de837c25f795877d314ae57943b5410074c6049
[root@Docker ~]# docker run --name stress3.3 -itd --rm --cpu-shares 2048 lorel/docker-stress-ng --cpu 4
8f103395b6ac93d337594fdd1db289b6462e01c3a208dcd3788332458ec03b98
[root@Docker ~]#
查看3個容器的CPU占用率:
$ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
800d756f76ca stress3.1 14.18% 14.53MiB / 908.2MiB 1.60% 656B / 0B 0B / 0B 5
4b8800719181 stress3.2 28.60% 15.78MiB / 908.2MiB 1.74% 656B / 0B 0B / 0B 5
8f103395b6ac stress3.3 56.84% 15.38MiB / 908.2MiB 1.69% 656B / 0B 0B / 0B 5
占用率基本就是1/2/4,符合期望。