中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

linux容器內存占用居高不下怎么解決

發布時間:2022-05-27 16:22:40 來源:億速云 閱讀:1472 作者:iii 欄目:大數據

本篇內容主要講解“linux容器內存占用居高不下怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“linux容器內存占用居高不下怎么解決”吧!

疑問

在出現系統內存過高的情況下,我們可以通過 free -m 來查看當前系統的內存使用情況:

linux容器內存占用居高不下怎么解決    

在發現是系統內存占用高后,就有讀者提到,為什么不 “手動清理 Cache”,因為 Cache 高的話,可以通過 drop_caches 的方式來清理:

  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

但新問題又出現了,因為我們的命題是在容器中,在 Kubernetes 中,若執行 drop_caches 相關命令,將會對 Node 節點上的所有其他應用程序產生影響,尤其是那些占用大量 IO 并由于緩沖區高速緩存而獲得更好性能的應用程序,可能會產生 “負面” 后果。 

表象

回歸原始,那就是為什么要排查這個問題,本質原因就是容器設置了 Memory Limits,而容器在運行中達到了 Limits 上限,被 OOM 掉了,所以我們想知道為什么會出現這個情況。

在前文中我們針對了五大類情況進行了猜想:

  • 頻繁申請重復對象。
  • 不知名內存泄露。
  • madvise 策略變更。
  • 監控/判別條件有問題。
  • 容器環境的機制。

在逐一排除后,后續發現容器的 Memory OOM 判定標準是 container_memory_working_set_bytes 指標,其實際組成為 RSS + Cache(最近訪問的內存、臟內存和內核內存)。

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

linux容器內存占用居高不下怎么解決    

在上圖中,我們發現了大量的 mapping 為 anon 的內存映射,最終 totals 確實達到了容器 Memory 相當的量,那么 anon 又是什么呢。實質上 anon 行表示在磁盤上沒有對應的文件,也就是沒有實際存在的載體,是 anonymous。 

思考

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

那么更進一步思考的是兩個問題,一個是 cgroup 達到 Limits 前的嘗試釋放仍然不足以支撐所需申請的連續內存段,而另外一個問題就是為什么 Cache 并沒有釋放:

linux容器內存占用居高不下怎么解決    

通過上圖,可以肯定該服務在凌晨 00:00-06:00 是沒有什么流量的,但是 container_memory_working_set_bytes 指標依舊穩定不變,排除 RSS 的原因,那配合指標的查看基本確定是該 cgroup 的 Cache 沒有釋放。

而 Cache 的占用高,主要考慮是由于其頻繁操作文件導致,因為在 Linux 中,在第一次讀取文件時會將一份放到系統 Cache,另外一份則放入進程內存中使用。關鍵點在于當進程運行完畢關閉后,系統 Cache 是不會馬上回收的,需要經過系統的內存管理后再適時釋放。

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

根因

問題版本

該服務所使用的 Kubernetes 是 1.11.5 版本,Linux 內核版本為 3.10.x,時間為 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 內核中管理 cgroup 內存的模塊,但實際上在 Linux 3.10.x 的低內核版本中存在不少實現上的 BUG,其中最具代表性的是 memory cgroup 中 kmem accounting 相關的問題(在低版本中屬于 alpha 特性):

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

  • memory cgroup 泄露:在刪除容器后沒有回收完全,而 Linux 內核對 memory cgroup 的總數限制是 65535 個,若頻繁創建刪除開啟了 kmem 的 cgroup,就會導致無法再創建新的 memory cgroup。

當然,為什么出現問題后絕大多數是由 Kubernetes、Docker 的相關使用者發現的呢(從 issues 時間上來看),這與云原生的興起,這類問題與內部容器化的機制相互影響,最終開發者 “發現” 了這類應用頻繁出現 OOM,于是開始進行排查。 

解決方案 

調整內核參數

關閉 kmem accounting:

cgroup.memory=nokmem

也可以通過 kubelet 的 nokmem Build Tags 來編譯解決:

$ kubelet GOFLAGS="-tags=nokmem"

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

升級內核版本

升級 Linux 內核至 kernel-3.10.0-1075.el7 及以上就可以修復這個問題,詳細可見 slab leak causing a crash when using kmem control group,其在發行版中 CentOS 7.8 已經發布。

到此,相信大家對“linux容器內存占用居高不下怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

五大连池市| 大同市| 靖州| 榆树市| 海门市| 凤台县| 故城县| 巴马| 许昌市| 嘉善县| 黄大仙区| 滕州市| 库车县| 中方县| 循化| 榕江县| 罗定市| 达孜县| 武强县| 行唐县| 土默特右旗| 崇仁县| 光山县| 江门市| 监利县| 威海市| 泰宁县| 闵行区| 景洪市| 天门市| 曲阜市| 青田县| 景泰县| 铜川市| 栖霞市| 班玛县| 阜南县| 资中县| 游戏| 明光市| 天等县|