linux容器內(nèi)存占用居高不下怎么解決

本篇內(nèi)容主要講解“l(fā)inux容器內(nèi)存占用居高不下怎么解決”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“l(fā)inux容器內(nèi)存占用居高不下怎么解決”吧!

成都創(chuàng)新互聯(lián)專(zhuān)業(yè)為企業(yè)提供民勤網(wǎng)站建設(shè)、民勤做網(wǎng)站、民勤網(wǎng)站設(shè)計(jì)、民勤網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、民勤企業(yè)網(wǎng)站模板建站服務(wù),10余年民勤做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

疑問(wèn)

在出現(xiàn)系統(tǒng)內(nèi)存過(guò)高的情況下,我們可以通過(guò) free -m 來(lái)查看當(dāng)前系統(tǒng)的內(nèi)存使用情況:

linux容器內(nèi)存占用居高不下怎么解決    

在發(fā)現(xiàn)是系統(tǒng)內(nèi)存占用高后,就有讀者提到,為什么不 “手動(dòng)清理 Cache”,因?yàn)?Cache 高的話,可以通過(guò) drop_caches 的方式來(lái)清理:

  1. 清理 page cache:
$ echo 1 > /proc/sys/vm/drop_caches
  1. 清理 dentries 和 inodes:
$ echo 2 > /proc/sys/vm/drop_caches
  1. 清理 page cache、dentries 和 inodes:
$ echo 3 > /proc/sys/vm/drop_caches

但新問(wèn)題又出現(xiàn)了,因?yàn)槲覀兊拿}是在容器中,在 Kubernetes 中,若執(zhí)行 drop_caches 相關(guān)命令,將會(huì)對(duì) Node 節(jié)點(diǎn)上的所有其他應(yīng)用程序產(chǎn)生影響,尤其是那些占用大量 IO 并由于緩沖區(qū)高速緩存而獲得更好性能的應(yīng)用程序,可能會(huì)產(chǎn)生 “負(fù)面” 后果。 

表象

回歸原始,那就是為什么要排查這個(gè)問(wèn)題,本質(zhì)原因就是容器設(shè)置了 Memory Limits,而容器在運(yùn)行中達(dá)到了 Limits 上限,被 OOM 掉了,所以我們想知道為什么會(huì)出現(xiàn)這個(gè)情況。

在前文中我們針對(duì)了五大類(lèi)情況進(jìn)行了猜想:

  • 頻繁申請(qǐng)重復(fù)對(duì)象。
  • 不知名內(nèi)存泄露。
  • madvise 策略變更。
  • 監(jiān)控/判別條件有問(wèn)題。
  • 容器環(huán)境的機(jī)制。

在逐一排除后,后續(xù)發(fā)現(xiàn)容器的 Memory OOM 判定標(biāo)準(zhǔn)是 container_memory_working_set_bytes 指標(biāo),其實(shí)際組成為 RSS + Cache(最近訪問(wèn)的內(nèi)存、臟內(nèi)存和內(nèi)核內(nèi)存)。

在排除進(jìn)程內(nèi)存泄露的情況下,我們肯定是希望知道 Cache 中有什么,為什么占用了那么大的空間,此時(shí)我們可以通過(guò) Linux pmap 來(lái)查看該容器進(jìn)程的內(nèi)存映射情況:

linux容器內(nèi)存占用居高不下怎么解決    

在上圖中,我們發(fā)現(xiàn)了大量的 mapping 為 anon 的內(nèi)存映射,最終 totals 確實(shí)達(dá)到了容器 Memory 相當(dāng)?shù)牧浚敲?anon 又是什么呢。實(shí)質(zhì)上 anon 行表示在磁盤(pán)上沒(méi)有對(duì)應(yīng)的文件,也就是沒(méi)有實(shí)際存在的載體,是 anonymous。 

思考

既然存在如此多的 anon,結(jié)合先前的考慮,我們知道出現(xiàn)這種情況的服務(wù)都是文件處理型服務(wù),包含大量的批量生成圖片、生成 PDF 等資源消耗型的任務(wù),也就是會(huì)瞬間申請(qǐng)大量的內(nèi)存,使得系統(tǒng)的空閑內(nèi)存觸及全局最低水位線(global wmark_min),而在觸及全局最低水位線后,會(huì)嘗試進(jìn)行回收,實(shí)在不行才會(huì)觸發(fā) cgroup OOM 的行為。

那么更進(jìn)一步思考的是兩個(gè)問(wèn)題,一個(gè)是 cgroup 達(dá)到 Limits 前的嘗試釋放仍然不足以支撐所需申請(qǐng)的連續(xù)內(nèi)存段,而另外一個(gè)問(wèn)題就是為什么 Cache 并沒(méi)有釋放:

linux容器內(nèi)存占用居高不下怎么解決    

通過(guò)上圖,可以肯定該服務(wù)在凌晨 00:00-06:00 是沒(méi)有什么流量的,但是 container_memory_working_set_bytes 指標(biāo)依舊穩(wěn)定不變,排除 RSS 的原因,那配合指標(biāo)的查看基本確定是該 cgroup 的 Cache 沒(méi)有釋放。

而 Cache 的占用高,主要考慮是由于其頻繁操作文件導(dǎo)致,因?yàn)樵?Linux 中,在第一次讀取文件時(shí)會(huì)將一份放到系統(tǒng) Cache,另外一份則放入進(jìn)程內(nèi)存中使用。關(guān)鍵點(diǎn)在于當(dāng)進(jìn)程運(yùn)行完畢關(guān)閉后,系統(tǒng) Cache 是不會(huì)馬上回收的,需要經(jīng)過(guò)系統(tǒng)的內(nèi)存管理后再適時(shí)釋放。

但我們發(fā)現(xiàn) Cache 的持續(xù)不釋放,進(jìn)程也沒(méi)外部流量,RSS 也低的可憐,Cache 不像被進(jìn)程占用住了的樣子(這一步的排除很重要),最終就考慮到是否 Linux 內(nèi)核在這塊內(nèi)存管理上存在 BUG 呢? 

根因

問(wèn)題版本

該服務(wù)所使用的 Kubernetes 是 1.11.5 版本,Linux 內(nèi)核版本為 3.10.x,時(shí)間為 2017 年 9 月:

$ uname -aLinux xxxxx-xxx-99bd5776f-k9t8z 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 Linux

都算是有一定年代的老版本了。 

原因分析

memcg 是 Linux 內(nèi)核中管理 cgroup 內(nèi)存的模塊,但實(shí)際上在 Linux 3.10.x 的低內(nèi)核版本中存在不少實(shí)現(xiàn)上的 BUG,其中最具代表性的是 memory cgroup 中 kmem accounting 相關(guān)的問(wèn)題(在低版本中屬于 alpha 特性):

  • slab 泄露:具體可詳見(jiàn)該文章 SLUB: Unable to allocate memory on node -1 中的介紹和說(shuō)明。

  • memory cgroup 泄露:在刪除容器后沒(méi)有回收完全,而 Linux 內(nèi)核對(duì) memory cgroup 的總數(shù)限制是 65535 個(gè),若頻繁創(chuàng)建刪除開(kāi)啟了 kmem 的 cgroup,就會(huì)導(dǎo)致無(wú)法再創(chuàng)建新的 memory cgroup。

當(dāng)然,為什么出現(xiàn)問(wèn)題后絕大多數(shù)是由 Kubernetes、Docker 的相關(guān)使用者發(fā)現(xiàn)的呢(從 issues 時(shí)間上來(lái)看),這與云原生的興起,這類(lèi)問(wèn)題與內(nèi)部容器化的機(jī)制相互影響,最終開(kāi)發(fā)者 “發(fā)現(xiàn)” 了這類(lèi)應(yīng)用頻繁出現(xiàn) OOM,于是開(kāi)始進(jìn)行排查。 

解決方案 

調(diào)整內(nèi)核參數(shù)

關(guān)閉 kmem accounting:

cgroup.memory=nokmem

也可以通過(guò) kubelet 的 nokmem Build Tags 來(lái)編譯解決:

$ kubelet GOFLAGS="-tags=nokmem"

但需要注意,kubelet 版本需要在 v1.14 及以上。

升級(jí)內(nèi)核版本

升級(jí) Linux 內(nèi)核至 kernel-3.10.0-1075.el7 及以上就可以修復(fù)這個(gè)問(wèn)題,詳細(xì)可見(jiàn) slab leak causing a crash when using kmem control group,其在發(fā)行版中 CentOS 7.8 已經(jīng)發(fā)布。

到此,相信大家對(duì)“l(fā)inux容器內(nèi)存占用居高不下怎么解決”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!

新聞名稱(chēng):linux容器內(nèi)存占用居高不下怎么解決
當(dāng)前路徑:http://bm7419.com/article32/igeisc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、、用戶(hù)體驗(yàn)外貿(mào)建站、小程序開(kāi)發(fā)、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

微信小程序開(kāi)發(fā)