8. Docker的資源限制

1 Docker的資源限制

1.1 Docker的資源限制

1.1.1 Docker資源限制介紹

默認(rèn)情況下, 容器沒(méi)有資源的使用限制, 可以使用宿主機(jī)內(nèi)核調(diào)度程序允許的盡可能多的資源
Docker提供了控制容器使用資源的方法, 可以限制容器使用多少內(nèi)存或CPU等, 在docker run命令運(yùn)行時(shí)配置標(biāo)志實(shí)現(xiàn)資源限制功能
其中許多功能都要求宿主機(jī)的內(nèi)核支持, 要檢查是否支持這些功能, 可以使用docker info命令
如果內(nèi)核中禁用了某項(xiàng)功能可能會(huì)在輸出結(jié)尾處看到警告, 如下所示
WARNING: No swap limit support
  • 范例: 修改內(nèi)核參數(shù), 消除以上警告信息
root@Ubuntu-1804-3:~# vim /etc/default/grub
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1 net.ifnames=0"
root@Ubuntu-1804-3:~# update-grub
root@Ubuntu-1804-3:~# reboot

1.1.2 OOM

產(chǎn)生OOM異常時(shí), dockerd會(huì)嘗試通過(guò)調(diào)用docker守護(hù)進(jìn)程上的OOM優(yōu)先級(jí)來(lái)減輕這些風(fēng)險(xiǎn), 以便它比系統(tǒng)上的其他進(jìn)程更不可能被殺死
但是容器的OOM優(yōu)先級(jí)未作調(diào)整的話(huà), 會(huì)使得單個(gè)容器被殺死的可能性比docker守護(hù)程序或其他進(jìn)程殺死的可能性更大, 不推薦通過(guò)在守護(hù)程序或容器上手動(dòng)設(shè)置--oom -score-adj為極端負(fù)數(shù)
可以在容器上設(shè)置-m限制容器使用的最大物理內(nèi)存, 然后通過(guò)容器上設(shè)置--oom-kill-disable來(lái)繞過(guò)這些安全措施, 當(dāng)內(nèi)存不足時(shí), 不kill本容器的進(jìn)程

OOM優(yōu)先級(jí)機(jī)制

Linux會(huì)為每個(gè)進(jìn)程計(jì)算一個(gè)分?jǐn)?shù), 最終將分?jǐn)?shù)最高的殺掉
/proc/PID/oom_score_adj
范圍為 -1000 到 1000, 值越高越容器被宿主機(jī)殺掉, 如果將該值設(shè)為-1000, 那么該進(jìn)程永遠(yuǎn)不會(huì)被宿主機(jī)內(nèi)核殺掉
以sshd進(jìn)程為例, sshd提供遠(yuǎn)程訪(fǎng)問(wèn)宿主機(jī)的功能, 如果隨意被殺死那么就無(wú)法連接到宿主機(jī), 所以sshd的分?jǐn)?shù)被設(shè)定為-1000, 永遠(yuǎn)不會(huì)被殺死
root@Ubuntu-1804-3:~# cat /proc/891/oom_score_adj 
-1000
/proc/PID/oom_adj
范圍是 -17 到 +15, 取值越高越容易被kill, 如果是 -17 表示不能被kill, 該設(shè)置參數(shù)的存在是為了和舊版本的Linux內(nèi)核兼容
sshd的范圍是-17, 永遠(yuǎn)不會(huì)被kill掉
root@Ubuntu-1804-3:~# cat /proc/891/oom_adj 
-17
/proc/PID/oom_score
這個(gè)值是系統(tǒng)綜合進(jìn)程的內(nèi)存消耗量, CPU時(shí)間,(uptime+存活時(shí)間(uptime-start time))和oom_adj計(jì)算出來(lái)的進(jìn)程得分, 消耗內(nèi)存越多得分越高, 容易被宿主機(jī)內(nèi)核強(qiáng)制殺死
以sshd為例
root@Ubuntu-1804-3:~# cat /proc/891/oom_score
0
dockerd的OOM得分
root@Ubuntu-1804-3:~# pidof dockerd
957
root@Ubuntu-1804-3:~# cat /proc/957/oom_adj 
-8
root@Ubuntu-1804-3:~# cat /proc/957/oom_score
0
root@Ubuntu-1804-3:~# cat /proc/957/oom_score_adj
-500

2 Docker的內(nèi)存限制

Docker可以強(qiáng)制硬性?xún)?nèi)存限制, 即只允許容器使用給定的內(nèi)存
Docker也可以執(zhí)行非硬性?xún)?nèi)存限制, 即容器可以使用盡可能多的內(nèi)存, 除非內(nèi)核檢查到主機(jī)上的內(nèi)存不夠用了

2.1 內(nèi)存相關(guān)選項(xiàng)

以下設(shè)置大部分的選項(xiàng)選取正整數(shù), 跟著一個(gè)后綴, b,k,m,表示字節(jié), 千字節(jié), 兆字節(jié),或者千兆字節(jié)
-m, --memory
容器可以使用的最大物理內(nèi)存, 硬限制, 此選項(xiàng)最小允許值為4m, 此選項(xiàng)較為常用, 用來(lái)限制容器可以使用的最大物理內(nèi)存
--memory-swap 
允許此容器交換到磁盤(pán)的內(nèi)存量, 必須先用-m對(duì)內(nèi)存現(xiàn)在才可以使用
-m 4m --memory-swap 4m
--memory-swappiness
設(shè)置容器使用交換分區(qū)的傾向性, 值越高表示越傾向于使用swap分區(qū), 范圍為0-100, 0為能不用就不用, 100為能用就用
--memory-reservation
允許指定小于--memory的軟限制, 當(dāng)Docker檢測(cè)到主機(jī)上的爭(zhēng)用或者內(nèi)存不足時(shí), 會(huì)激活該限制, 如果使--memory-reservation, 則必須將其設(shè)置為低于--memory才能使其優(yōu)先生效. 因?yàn)樗擒浵拗? 所以不能保證容器不超過(guò)限制
--kernek-memory
容器可以使用的最大內(nèi)核內(nèi)存量, 最小為4m, 由于內(nèi)核與用戶(hù)空間內(nèi)存隔離, 因此無(wú)法與用戶(hù)空間內(nèi)存直接交換, 因此內(nèi)核內(nèi)存不足的容器可能會(huì)阻塞宿主機(jī)資源, 這會(huì)對(duì)主機(jī)和其他容器或者其他服務(wù)進(jìn)程產(chǎn)生影響, 因此不要設(shè)置內(nèi)核內(nèi)存大小
--omm-kill-disable
默認(rèn)情況下, 如果發(fā)生內(nèi)存不足(OOM)錯(cuò)誤, 則內(nèi)核將終止容器中的進(jìn)程. 要更改此行為, 可以使用--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)存

范例: MySQL內(nèi)存限制

root@Ubuntu-1804-3:~# docker run -e MYSQL_ROOT_PASSWORD=123456 --rm -it -m 1g --oom-kill-disable mysql:5.7.29
-m MySQL容器最大使用1g物理內(nèi)存, 是硬限制
--oom-kill-disable 表示即使發(fā)生內(nèi)存OOM的情況, 也不會(huì)殺掉該容器

2.2 swap限制

k8s環(huán)境要求關(guān)閉swap
純docker環(huán)境需要限制swap使用
--memory-swap 只有在設(shè)置了 --memory后才會(huì)有意思. 使用swap可以讓容器將超出限制部分的內(nèi)存置換到磁盤(pán)上. 不過(guò)經(jīng)常將內(nèi)存交換到磁盤(pán)的應(yīng)用程序會(huì)降低性能

不同的--memory-swap設(shè)置會(huì)產(chǎn)生不同的效果

--memory-swap   --memory      功能
正數(shù)S             正數(shù)M        容器可用總空間(內(nèi)存和交換分區(qū))為S, 其中內(nèi)存ram為M, 則swap為(S-M), 若S=M, 則無(wú)可用swap資源
0                 正數(shù)M       相當(dāng)于未設(shè)置swap(unset)
unset             正數(shù)M       若主機(jī)(Docker Host)啟用了swap, 則容器的可用swap為2*M
-1                正數(shù)M        若主機(jī)(Docker Host)啟用了swap, 則容器可使用的主機(jī)上的所有swap空間
--memory-swap 值為正數(shù), 那么--memory和--memory-swap都必須要設(shè)置, --memory-swap表示能使用的內(nèi)存和swap分區(qū)的大小的總和, 例如: --memory=300m, --memory-swap=1g, 那么該容器能使用300m物理內(nèi)存和700m swap空間, 即--memory是實(shí)際物理內(nèi)存大小值不變, 而swap的實(shí)際大小計(jì)算方式為(--memory-swap)-(--memory)=容器可用的swap空間
--memory-swap 如果設(shè)置為0, 則忽略該設(shè)置, 并將該值視為未設(shè)置, 即不使用交換分區(qū)
--memory-swap 如果等于--memory的值, 并且--memory設(shè)置為正數(shù), 容器無(wú)權(quán)訪(fǎng)問(wèn)swap
--memory-swap 如果未設(shè)置(unset), 如果宿主機(jī)開(kāi)啟了swap, 則實(shí)際容器的swap值最大為2*(--memory), 即兩倍于物理內(nèi)存大小, 例如, 如果--memory="300m",與--memory-swap沒(méi)有設(shè)置, 該容器可以使用300m總的內(nèi)存和600m交換空間, 但不準(zhǔn)確(在容器中使用free命令所看到的swap空間并不精確, 畢竟每個(gè)容器都可以看到具體大小, 宿主機(jī)的swap是有上限的, 而且不是所有容器看到的累計(jì)大小)
--memory-swap 如果設(shè)置為-1, 如果宿主機(jī)開(kāi)啟了swap, 則容器可使用主機(jī)上swap的最大空間

在容器中執(zhí)行free命令看到的是宿主機(jī)的內(nèi)存和swap使用情況, 而非容器自身的swap使用情況

-m 2g: 容器最多使用2g內(nèi)存
--memory-swap 3g: 容器最多使用的物理內(nèi)存是3g, 包括2個(gè)g的內(nèi)存和1個(gè)g的swap
root@Ubuntu-1804-3:~# docker run -it --rm -m 2g --memory-swap 3g alpine
/ # free -m
              total        used        free      shared  buff/cache   available
Mem:            962         248         301           9         412         569
Swap:          1905 (但是這里顯示容器swap是2個(gè)g的限制)          5        1900
root@Ubuntu-1804-3:~# free -m
              total        used        free      shared  buff/cache   available
Mem:            962         248         300           9         412         569
Swap:          1905           5        1900 # 由此看到容器內(nèi)查看free命令結(jié)果, 顯示的就是宿主機(jī)的內(nèi)存情況

3 容器的CPU限制

Linxu內(nèi)存的進(jìn)程調(diào)度基于CFS(Completely Fair Scheduler), 完全公平調(diào)度

服務(wù)器資源密集型

cpu密集型的場(chǎng)景:
優(yōu)先級(jí)越低越好, 計(jì)算密集型任務(wù)的特點(diǎn)是進(jìn)程大量的計(jì)算, 消耗cpu資源, 比如計(jì)算圓周率, 數(shù)據(jù)處理, 對(duì)視頻進(jìn)行高清解碼等等, 全靠cpu的運(yùn)算能力
IO密集型的場(chǎng)景: 優(yōu)先級(jí)值高點(diǎn), 涉及到網(wǎng)絡(luò), 磁盤(pán)IO的任務(wù)都是IO密集型任務(wù), 這類(lèi)任務(wù)的特點(diǎn)是cpu消耗很少, 任務(wù)的大部分時(shí)間都在等待IO操作完成
因?yàn)镮O的速度遠(yuǎn)遠(yuǎn)低于cpu和內(nèi)存的速度, 比如web應(yīng)用, 高并發(fā), 數(shù)據(jù)量大的動(dòng)態(tài)網(wǎng)站來(lái)說(shuō), 數(shù)據(jù)庫(kù)應(yīng)該為IO密集型

cfs原理

cfd定義了進(jìn)程的調(diào)度新模型, 它給cfs_rq(cfs的run_queue)中的每一個(gè)進(jìn)程安排一個(gè)虛擬時(shí)鐘vruntime. 
如果一個(gè)進(jìn)程得以執(zhí)行, 隨著時(shí)間的增長(zhǎng), 其vruntime將不斷增大, 沒(méi)有得到執(zhí)行的過(guò)程vruntime不變, 而調(diào)度器總是選擇vruntime跑的最慢的那個(gè)進(jìn)程來(lái)執(zhí)行. 這就是所謂的完全公平調(diào)度. 為了區(qū)別不同優(yōu)先級(jí)的進(jìn)程, 優(yōu)先級(jí)高的進(jìn)程vruntime增長(zhǎng)的慢, 以至于它可能得到更多的運(yùn)行機(jī)會(huì).
CFS的意義在于, 在一個(gè)混在著大量計(jì)算型進(jìn)程和IO交互進(jìn)程的系統(tǒng)中, CFS調(diào)度器相對(duì)其他調(diào)度器在對(duì)待IO交互進(jìn)程要更加友善和公平
root@Ubuntu-1804-3:~# cat /sys/block/sda/queue/scheduler 
noop deadline [cfq] 

配置默認(rèn)的CFS調(diào)度程序

默認(rèn)情況下, 每個(gè)容器對(duì)主機(jī)的CPU周期的訪(fǎng)問(wèn)都是不受限制的, 可以設(shè)置各種約束, 以限制給定容器對(duì)主機(jī)CPU周期的訪(fǎng)問(wèn). 
CFS適用于常規(guī)Linux進(jìn)程的Linux內(nèi)核CPU調(diào)度程序, 通過(guò)幾個(gè)運(yùn)行時(shí)標(biāo)志, 可以配置對(duì)容器擁有的CPU資源的訪(fǎng)問(wèn)量. 使用這些設(shè)置時(shí), Docker會(huì)在主機(jī)上修改容器cgroup的設(shè)置
--cpus=
制定一個(gè)容器可以使用多少個(gè)可用的CPU核心資源. 例如: 如果主機(jī)有兩個(gè)CPU, 那么設(shè)置了--cpus="1.5", 則可以保證容器最多使用1.5個(gè)CPU. 如果宿主機(jī)是4核CPU, 那么還可以使用每個(gè)CPU上的一部分, 但是總計(jì)是1.5核心總的CPU.
--cpuset-cpus 進(jìn)行容器和cpu綁定
用于指定容器運(yùn)行的cpu編號(hào), 也就是所謂的cpu綁定. 如果一個(gè)或多個(gè)cpu, 則容器可以使用逗號(hào)分隔的列表或連字符分隔的cpu范圍. 第一個(gè)cpu編號(hào)為0, 有效值可以是0-3, (表示使用第1,2,3,4核cpu)或者1,3表示第2和4核cpu
--cpu-shares
用于設(shè)置cfs中調(diào)度的相對(duì)最大比例權(quán)重, cpu-shares的值越高的容器, 將會(huì)分得更多的時(shí)間片, 比如, 宿主機(jī)多核cpu總數(shù)為100%, 假如容器A為1024, B為2048, 那么容器B將使用最大的CPU分片是容器A可用CPU分配的兩倍)
默認(rèn)的時(shí)間片為1024, 最大是262144, 這是一個(gè)軟限制
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贺待,一起剝皮案震驚了整個(gè)濱河市苞笨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡窖梁,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)夹囚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)纵刘,“玉大人,你說(shuō)我怎么就攤上這事崔兴≌玫迹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵敲茄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我山析,道長(zhǎng)堰燎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任笋轨,我火速辦了婚禮秆剪,結(jié)果婚禮上赊淑,老公的妹妹穿的比我還像新娘。我一直安慰自己仅讽,他們只是感情好陶缺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著洁灵,像睡著了一般饱岸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上徽千,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天苫费,我揣著相機(jī)與錄音,去河邊找鬼双抽。 笑死百框,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的牍汹。 我是一名探鬼主播铐维,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼慎菲!你這毒婦竟也來(lái)了嫁蛇?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤钧嘶,失蹤者是張志新(化名)和其女友劉穎棠众,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體有决,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闸拿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了书幕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片新荤。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖台汇,靈堂內(nèi)的尸體忽然破棺而出苛骨,到底是詐尸還是另有隱情,我是刑警寧澤苟呐,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布痒芝,位于F島的核電站,受9級(jí)特大地震影響牵素,放射性物質(zhì)發(fā)生泄漏严衬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一笆呆、第九天 我趴在偏房一處隱蔽的房頂上張望请琳。 院中可真熱鬧粱挡,春花似錦、人聲如沸俄精。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嫌套。三九已至,卻和暖如春测蘑,著一層夾襖步出監(jiān)牢的瞬間灌危,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工碳胳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留勇蝙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓挨约,卻偏偏與公主長(zhǎng)得像味混,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诫惭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容