文章目錄
- 1、docker的資源限制
- 1.1 容器資源限制的介紹
- 1.2 OOM
- 1.3 容器的內存限制
- 1.3.1 內存限制的相關選項
- 1.4 容器的CPU限制介紹
- 2、docker的監控插件
- 2.1 cadvisor
- 2.2 portainer
1、docker的資源限制
1.1 容器資源限制的介紹
默認情況下,容器沒有資源的使用限制,可以使用主機內核調度程序允許的盡可能多的資源
Docker 提供了控制容器使用資源的方法,可以限制容器使用多少內存或 CPU等, 在docker run 命令的運行時配置標志實現資源限制功能。
其中許多功能都要求宿主機的內核支持,要檢查是否支持這些功能,可以使用docker info 命令 ,如果內核中的某項特性可能會在輸出結尾處看到警告, 如下所示:
WARNING: No swap limit support
1.2 OOM
對于 Linux 主機,如果沒有足夠的內存來執行其他重要的系統任務,將會拋出OOM (Out of Memory Exception,內存溢出、內存泄漏、內存異常 ),隨后系統會開始殺死進程以釋放內存, 凡是運行在宿主機的進程都有可能被 kill ,包括 Dockerd和其它的應用程序, 如果重要的系統進程被 Kill,會導致和該進程相關的服務全部宕機。通常越消耗內存比較大的應用越容易被kill,比如: MySQL數據庫,Java程序等
產生 OOM 異常時, Dockerd嘗試通過調整 Docker 守護程序上的 OOM 優先級來減輕這些風險,以便它比系統上的其他進程更不可能被殺死但是容器 的 OOM 優先級未調整, 這使得單個容器被殺死的可能性比 Docker守護程序或其他系統進程被殺死的可能性更大,不推薦通過在守護程序或容器上手動設置-- oom -score-adj為極端負數,或通過在容器上設置 – oom-kill-disable來繞過這些安全措施
OOM優先級機制:
linux會為每個進程算一個分數,最終將分數最高的kill
/proc/PID/oom_score_adj
#范圍為 -1000 到 1000,值越高容易被宿主機 kill掉,如果將該值設置為 -1000 ,則進程永遠不會被宿主機 kernel kill /proc/PID/oom_adj
#范圍為 -17 到+15 ,取值越高越容易被干掉,如果是 -17 , 則表示不能被 kill ,該設置參數的存在是為了和舊版本的 Linux 內核兼容。/proc/PID/oom_score
#這個值是系統綜合進程的內存消耗量、 CPU 時間 (utime + 、存活時間 (uptime - start time) 和 oom_adj 計算出的進程得分 ,消耗內存越多得分越高,容易被宿主機 kernel 強制殺死
查看docker進程相關的oom的值
[root@localhost docker-compose]#cat /proc/24472/oom_score_adj
-500
[root@localhost docker-compose]#cat /proc/24472/oom_adj
-8
[root@localhost docker-compose]#cat /proc/24472/oom_score
0
[root@localhost docker-compose]#
1.3 容器的內存限制
Docker 可以強制執行硬性內存限制,即只允許容器使用給定的內存大小。
Docker 也可以執行非硬性內存限制,即容器可以使用盡可能多的內存,除非內核檢測到主機上的內存不夠用了
1.3.1 內存限制的相關選項
以下設置大部分的選項取正整數,跟著一個后綴 b , k , m , g ,,表示字節,千字節,兆字節或千兆字節
選項 | 描述 |
---|---|
-m , – --memory= | 容器可以使用的最大物理內存量,硬限制,此選項最小允許值為 4m (4 MB),此項較常用 |
–memory-swap | 允許此容器交換到磁盤的內存量,必須先用-m 對內存限制才可以使用,詳 細說明如下 |
–memory-swappiness | 設置容器使用交換分區的傾向性,值越高表示越傾向于使用swap分 區,范圍為0-100,0為能不用就不用,100為能用就用 |
–memory-reservation | 允許指定小于 --memory 的軟限制 ,當 Docker 檢測到主機上的爭用 或內存不足時會激活該限制,如果使-- memory-reservation,則必須 將其設置為低于 --memory 才能使其優先生效。 因為它是軟限制,所 以不能保證容器不超過限制 |
–kernel-memory | 容器可以使用的最大內核內存量,最小為 4m,由于內核內存與用戶空 間內存隔離,因此無法與用戶空間內存直接交換,因此內核內存不足的 容器可能會阻塞宿主機資源,這會對主機和其他容器或者其他服務進程 產生影響,因此不建議設置內核內存大小 |
–oom-kill-disable | 默認情況下,如果發生內存不足(OOM)錯誤,則內核將終止容器中 的進程。要更改此行為,請使用該 --oom-kill-disable 選項。僅在設 置了該 -m/–memory 選項的容器上禁用OOM。如果 -m 未設置該標志, 則主機可能會用完內存,內核可能需要終止主機系統的進程以釋放內存 |
例子:啟動容器不會被優化
docker run -e MYSQL_ROOT_PASSWORD=123456 -it --rm -m 1g --oom-kill-disable mysql:5.7.29
例子: 限制容器使用的最大內存 默認啟動容器是不會 限制的
[root@localhost ~]#docker run -itd --name test1 -m 512m centos:7 /bin/bash
#限制容器最大內存為 512m[root@localhost ~]#docker stats --no-stream test1
# 查看容器的最大值
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
b6472ee1f67e test8 0.00% 1.617MiB / 512MiB 0.32% 648B / 0B 9.3MB / 0B 1
例子: 限制使用swap 的大小
–memory-swap
[root@localhost ~]# docker run -itd --name test10 -m 512m --memory-swap=1g centos:7強調一下,--memory-swap 是必須要與 --memory 一起使用的。正常情況下,--memory-swap 的值包含容器可用內存和可用 swap。
所以 -m 512m --memory-swap=1g 的含義為:容器可以使用 512M 的物理內存,
并且可以使用 700M(1G - 300)的 swap。如果 --memory-swap 設置為 0 或者 不設置,則容器可以使用的 swap 大小為 -m 值的兩倍。
如果 --memory-swap 的值和 -m 值相同,則容器不能使用 swap。
如果 --memory-swap 值為 -1,它表示容器程序使用的內存受限,
而可以使用的 swap 空間使用不受限制(宿主機有多少 swap 容器就可以使用多少)
1.4 容器的CPU限制介紹
一個宿主機,有幾十個核心的CPU,但是宿主機上可以同時運行成百上千個不同的進程用以處理不同的任務,多進程共用一個 CPU 的核心為可壓縮資源,即一個核心的 CPU 可以通過調度而運行多個進程,但是同一個單位時間內只能有一個進程在 CPU 上運行,那么這么多的進程怎么在 CPU 上執行和調度的呢?
Linux kernel 進程的調度基于CFS(Completely Fair Scheduler),完全公平調度
服務器資源密集型
- CPU 密集型的場景: 優先級越低越好,計算密集型任務的特點是要進行大量的計算,消耗CPU 資源,比如計算圓周率、數據處理、對視頻進行高清解碼等等,全靠CPU 的運算能力。
- IO 密集型的場景: 優先級值高點,涉及到網絡、磁盤IO 的任務都是IO 密集型任務,這類任務的特點是 CPU 消耗很少,任務的大部分時間都在等待 IO 操作完成(因為 IO 的速度遠遠低于 CPU 和內存的速度),比如 Web 應用,高并發,數據量大的動態網站來說,數據庫應該為IO 密集型
CFS原理
cfs定義了進程調度的新模型,它給cfs_rq(cfs的run queue)中的每一個進程安排一個虛擬時鐘vruntime。如果一個進程得以執行,隨著時間的增長,其vruntime將不斷增大。沒有得到執行的進程vruntime不變, 而調度器總是選擇vruntime跑得最慢的那個進程來執行。這就是所謂的“完全公平”。為了區別不同優先級的進程,優先級高的進程vruntime增長得慢,以至于它可能得到更多的運行機會。CFS的意義在于, 在一個混雜著大量計算型進程和IO交互進程的系統中,CFS調度器相對其它調度器在對待IO交互進程要更加友善和公平。
[root@localhost ~]#cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
選項 | 描述 |
---|---|
–cpus= | 指定一個容器可以使用多少個可用的CPU核心資源。例如,如果主機有兩個 CPU,如果設置了 --cpus=“1.5” ,則可以保證容器最多使用1.5個的CPU(如果 是4核CPU,那么還可以是4核心上每核用一點,但是總計是1.5核心的CPU)。這 相當于設置 --cpu-period=“100000” 和 --cpu-quota=“150000” 。此設置可在 Docker 1.13及更高版本中可用,目的是替代–cpu-period和–cpu-quota兩個參 數,從而使配置更簡單,但是最大不能超出宿主機的CPU總核心數(在操作系統 看到的CPU超線程后的數值),此項較常用 |
–cpu-period= | 過時選項,指定CPU CFS調度程序周期,必須與 --cpu-quota 一起使用 。默認為 100微秒。大多數用戶不會更改默認設置。如果使用Docker 1.13或更高版本, 請改用 --cpus |
–cpu-quota= | 過時選項,在容器上添加 CPU CFS 配額,計算方式為 cpu-quota / cpu-period的 結果值,docker1.13 及以上版本通常使用–cpus 設置此值 |
–cpuset-cpus | 用于指定容器運行的 CPU 編號,也就是所謂的CPU綁定。如果一個或多個 CPU,則容器可以使用逗號分隔的列表或用連字符分隔的CPU范圍。第一個 CPU的編號為0。有效值可能是 0-3 (使用第一,第二,第三和第四CPU)或 1,3 (使用第二和第四CPU) |
–cpu-shares | 用于設置 cfs 中調度的相對最大比例權重,cpu-share 的值越高的容器,將會分 得更多的時間片(宿主機多核 CPU 總數為 100%,假如容器 A 為1024,容器 B 為 2048,那么容器 B 將最大是容器 A 的可用 CPU 的兩倍 ),默認的時間片 1024,最大 262144。這是一個軟限制。 |
例子:設置CPU使用率上限
使用 --cpu-period 即可設置調度周期,使用 --cpu-quota 即可設置在每個周期內容器能使用的CPU時間。兩者可以配合使用。
CFS 周期的有效范圍是 1ms~1s,對應的 --cpu-period 的數值范圍是 1000~1000000。
而容器的 CPU 配額必須不小于 1ms,即 --cpu-quota 的值必須 >= 1000。
[root@localhost ~]#docker run -itd --name test5 centos:7 /bin/bash[root@localhost ~]#docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5f5ab75d9f1a centos:7 "/bin/bash" 8 seconds ago Up 7 seconds test5[root@localhost ~]#cd /sys/fs/cgroup/cpu/docker/5f5ab75d9f1add29fd4441c88abc70f84cbc083d1fd5e77b99c94e5c8440d213/
[root@localhost 5f5ab75d9f1add29fd4441c88abc70f84cbc083d1fd5e77b99c94e5c8440d213]#
[root@localhost 5f5ab75d9f1add29fd4441c88abc70f84cbc083d1fd5e77b99c94e5c8440d213]#cat cpu.cfs_quota_us
-1
[root@localhost 5f5ab75d9f1add29fd4441c88abc70f84cbc083d1fd5e77b99c94e5c8440d213]#cat cpu.cfs_period_us
100000cpu.cfs_period_us: 表示 CFS 調度周期的長度,以微秒為單位。
在每個周期內,容器可以使用指定比例的 CPU 時間。默認情況下,cpu.cfs_period_us 的值是 100000(即 100 毫秒)。cpu.cfs_quota_us: 表示容器在 cpu.cfs_period_us 周期內能夠使用的 CPU 時間量,同樣以微秒為單位。
它定義了一個相對于周期的配額。如果設置為 -1,表示沒有限制。如果設置為正值,表示在周期內的配額。
例如,如果 cpu.cfs_quota_us 設置為 50000,那么容器在一個周期內最多可以使用 50 毫秒的 CPU 時間。在 Linux 的 CFS 調度器中,cpu.cfs_period_us 參數定義了一個周期,
而這個周期實際上是用來調度任務(包括容器)的基本時間單位。
然而,具體的一次調度的時間是由調度器決定的,并且這個時間在一般情況下是動態變化的。
進入容器模擬測試
[root@localhost ~]#docker exec -it test5 bash[root@5f5ab75d9f1a /]# vi cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done
[root@5f5ab75d9f1a /]# ./cpu.sh &
加入選項 --cpu-quota 50000
docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash
或者直接修改 配置文件
cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
echo 50000 > cpu.cfs_quota_us
docker exec -it 3ed82355f811 /bin/bash
./cpu.sh
例子: 設置容器 綁定cpu
docker run -itd --name test7 --cpuset-cpus 1,3 centos:7 /bin/bash
2、docker的監控插件
2.1 cadvisor
docker自帶的監控組件,可以把cadvisor下載下來,以一個UI界面,輸出出來,方便資源管理
在監控的知識體系中cadvisor也稱為指標暴露器
docker run -d --name wxj -p 8080:8080 -v /:/rootfs:ro -v /var/run/:/var/run/:rw -v /sys/:/sys/:ro -v /var/lib/docker/:/var/lib/docker/:ro -v /dev/disk/:/dev/disk/:ro google/cadvisor:v0.32.0
2.2 portainer
docker run -p 9000:9000 -p 8000:8000 --name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /mydata/portainer/data:/data \
-d portainer/portainer