所謂OOM就是當系統上的應用申請記憶體資源時,發現申請不到記憶體,這個時候Linux內核就會啟動OOM,內核將給系統上的所有進程進行評分,通過評分得分最高的進程就會被系統第一個幹掉,從而騰出一些記憶體空間,如果騰出的記憶體空間還是不夠該應用使用,它會繼續殺得分第二高的,直到應用有足夠的記憶體使用;一旦發生O... ...
上一篇我們聊到了docker容器的單機編排工具docker-compose的簡單使用,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13121678.html;今天我們主要來聊一聊docker容器的資源限制;通常情況下我們啟動一個docker容器,其記憶體和CPU都是同宿主機一樣大,這意味著該容器和宿主機共用相同大小的記憶體和CPU資源;這樣一來容器正常情況下沒有什麼問題,假如容器里運行的進程特別愛吃記憶體,很可能存在把宿主機上的記憶體全部吃掉,觸發內核OOM,從而導致docker daemon直接被內核殺死;為了避免這樣的尷尬局面,對啟動容器我們有必要對容器的資源進行限制;
所謂OOM就是當系統上的應用申請記憶體資源時,發現申請不到記憶體,這個時候Linux內核就會啟動OOM,內核將給系統上的所有進程進行評分,通過評分得分最高的進程就會被系統第一個幹掉,從而騰出一些記憶體空間,如果騰出的記憶體空間還是不夠該應用使用,它會繼續殺得分第二高的,直到應用有足夠的記憶體使用;一旦發生OOM,任何進程都有可能被殺死,包括docker daemon在內,為此,docker特定調整了docker daemon的oom優先順序,以免發生oom被內核殺死,但是容器的oom優先順序並未做任何調整;
那麼對於記憶體資源來講,在啟動為容器時,我們可以通過一些選項來指定容器的記憶體相關設置;如下圖
提示:-m 或 --memory 用來指定容器最大能夠使用的記憶體大小,預設情況不指定表示共用物理宿主機的記憶體大小;--memory-swap 用來指定容器的記憶體和交換記憶體的總大小;對於這個參數的取值比較詭異;待會在說吧;--memory-swappiness該選項用來指定容器使用交換記憶體的傾向性,swap啟用有個好處就是在記憶體不夠使用的情況,它可以臨時頂替一部分,但是性能會急劇下降;所以數字越大越早使用交換記憶體,數字越小越晚使用交換記憶體,取值在0-100之間;0不代表不是用交換記憶體,0表示能不用交換記憶體,則不用,但是在迫不得已的情況還是會使用的,100表示只要有一絲可以使用交換記憶體的希望,就使用交換記憶體;通常情況在運行容器的主機上不建議使用swap設備;swap交換分區如果一旦被激活,系統性能會急劇下降,建議直接禁用;--memory-reservation該選項用來指定給系統保留的記憶體空間大小;--kernel-memory用來指定給內核保留的記憶體大小;--oom-kill-disable該選項用於指定當發生oom時,是否禁用因oom而殺死該容器進程;
提示:通常情況--memory-swap這個選項必須同--memory選項一起使用,不可用單獨使用;
示例:限制容器使用最大記憶體為256M
[root@docker_registry ~]# docker run --name test --rm -m 256M lorel/docker-stress-ng --vm 2
提示:以上命令表示啟動一個名為test的容器,限制該容器最大使用記憶體大小為256M;lorel/docker-stress-ng這個進行用來壓測容器;--vm表示同時使用多少進程來做壓測;
驗證:用docker stats看看我們啟動test容器是否只能使用256M記憶體?
提示:從上面的結果可以看到,在我們啟動容器時,使用-m指定記憶體大小的容器limit的值就是我們指定的值,而對於沒有用-m指定的容器,預設就是同宿主機記憶體大小一樣;
對於CPU來講,預設情況啟動容器時,不限制CPU的資源,此時容器是共用宿主機的CPU資源,也就是說預設情況宿主機上有幾顆cpu核心,啟動的容器就有多少顆核心;對於CPU這種可壓縮資源,不會像記憶體那樣,如果CPU滿載,也不會導致某個容器崩潰,原因是因為cpu是可壓縮資源;而不同於記憶體,記憶體屬於不可壓縮資源,如果申請不到記憶體,就會出現異常,出現oom;對啟動容器來限制cpu資源,通常也是使用選項來限定;如下圖
提示:--cpus用來指定容器能夠使用的最大cpu核心數,例如--cpus=1.5,就表示該容器最大能夠使用1.5核的CPU資源,如果宿主機上有4顆CPU核心,那麼該容器最多可把1.5顆核心跑滿;這樣說吧,如果宿主機上有4顆核心,那麼該容器如果使用--cpus限定為1.5,那麼該容器就只能使用宿主機上的百分之150的核心;--cpu-period 和--cpu-quota該選項在docker1.13以後基本廢棄;--cpuset-cpus該選項用於指定容器能夠在哪些CPU上運行;如果宿主機上有4顆CPU,--cpuset-cpus=2,3就表示該容器只能使用第2號cpu和第3號cpu;--cpu-shares該選項用於指定容器使用cpu的比例;比如宿主機上只有一個容器,而該容器啟動時指定--cpu-shares=1024,則表示,如果沒有其他容器,則它可以使用宿主機上的所有cpu資源,如果有第二個容器啟動時,指定cpu-shares=512,那麼第一個容器會從原來使用整個宿主機的cpu變為使用整個宿主機的cpu的2/3;以此類推,如果有第三個,第四個,他們使用cpu資源都是按照給定的比例動態調整;
示例:第一個容器使用--cpu-shares=256;第二個容器使用--cpu-shares=512,看看當第一個容器啟動後,看看cpu使用情況,然後第二個容器啟動後再看看cpu使用情況
提示:可以看到當第一個容器啟動時,雖然設置的cpu-shares=256,但是它還是把所有核心幾乎都跑滿了;我們在跑一個容器看看,看看第二個容器啟動後,第一個容器的cpu使用情況是否有變化?
提示:從上面的結果看,t1和t2的cpu使用比例大概是1比2;總量還是400%並沒有變化;
示例:設置容器使用1.5個CPU核心
提示:從上面的結果可以看到使用--cpus來限定容器使用的CPU資源,預設它會在每顆黑核心上都要使用一部分,但是重量不會超過150%;
示例:限定容器使用CPU核心,只能在0號和3號核心上使用;
提示:從上面的結果可以看到,限定t1容器只能使用0號和3號CPU後,1號和2號就基本不會被使用,總量也不會增加;