kernel deadlock caused by kmem counting in k8s

錯誤現(xiàn)象

a. 終端重復報警消息:?NMI watchdog: BUG: soft lockup - CPU#xx stuck for 22s!

b. dmesg提示kernel:?SLUB: Unable to allocate memory on node -1

c. crash log顯示:

SLUB: Unable to allocate memory on node -1 (gfp=0xd0)

? cache: sock_inode_cache(158:8aff71103b350fcc15a20dcad154986160ce07496a9f70fa4aff83e7716b0936), object size: 632, buffer size: 640, default order: 3, min order: 0

? node 0: slabs: 8, objs: 363, free: 0

? node 1: slabs: 17, objs: 867, free: 0

socket: no more sockets

IPv6: Failed to initialize the ICMP6 control socket (err -23)

BUG: unable to handle kernel NULL pointer dereference at 0000000000000020

IP: [<ffffffff894dfb20>] ip6mr_sk_done+0x60/0xf0

.......

[<ffffffff894c984d>] rawv6_close+0x1d/0x40

[<ffffffff8946cf5d>] inet_release+0x7d/0x90

[<ffffffff894a67d0>] inet6_release+0x30/0x40

[<ffffffff893cba35>] sock_release+0x25/0x90

[<ffffffff893d302c>] sk_release_kernel+0x2c/0x60

[<ffffffff894cbbf5>] icmpv6_sk_init+0x125/0x140

[<ffffffff893e0794>] ops_init+0x44/0x150

[<ffffffff893e0943>] setup_net+0xa3/0x160

[<ffffffff893e10e5>] copy_net_ns+0xb5/0x180

[<ffffffff88ebfe89>] create_new_namespaces+0xf9/0x180

[<ffffffff88ec00ca>] unshare_nsproxy_namespaces+0x5a/0xc0

[<ffffffff88e90c13>] SyS_unshare+0x193/0x300

[<ffffffff8951f7d5>] system_call_fastpath+0x1c/0x21

操作系統(tǒng)版本是CentOS Linux release 7.5.1804法严, 內(nèi)核為3.10.0-862.el7.x86_64,k8s版本是v1.12.3竟痰,Docker版本Docker version 18.06.1-ce兄猩。

問題分析及解決方案

首先我們看到內(nèi)核提示的錯誤信息與內(nèi)存分配有關(guān)侠坎,我們首先考慮這可能是一個內(nèi)存泄露問題峻仇。同時弓颈,當終端不斷彈出sock lockup錯誤信息時,手動stop docker service之后消息立馬不再彈出涩维,因而我們也懷疑這是docker造成的問題。

問題先從Linux的內(nèi)存管理機制說起袁波。在Linux中瓦阐,內(nèi)存分為內(nèi)核內(nèi)存及用戶內(nèi)存,內(nèi)核內(nèi)存設(shè)計為專用于Linux內(nèi)核中系統(tǒng)服務(wù)使用篷牌,是不可swap的睡蟋,因而內(nèi)核內(nèi)存資源對Linux系統(tǒng)來說是非常寶貴的。然而枷颊,正因為這種設(shè)計戳杀,現(xiàn)實中也存在很多針對內(nèi)核內(nèi)存資源的攻擊该面,例如惡意進程可以通過不斷地fork新進程從而耗盡系統(tǒng)資源,從而造成系統(tǒng)異承趴ǎ或崩潰隔缀,這就是所謂的“fork bomb”。

為了防止出現(xiàn)“fork bomb”傍菇,社區(qū)中就有提議通過linux內(nèi)核限制cgroup中的kmem容量使用從而限制惡意進程的行為猾瘸,即kernel memory accounting機制。當我們通過memory cgroup限制應用的內(nèi)存使用時丢习,我們不但需要限制應用對用戶內(nèi)存的使用牵触,也需要限制應用對內(nèi)核內(nèi)存的使用。kernel memory accounting機制為cgroup的內(nèi)存限制增加了stack pages(例如新進程創(chuàng)建)咐低、slab pages(SLAB/SLUB分配器使用的內(nèi)存)揽思、sockets memory pressure、tcp memory pressure等见擦,內(nèi)核文檔中有詳細的描述钉汗。kernel memory accounting機制為cgroup提供了memory.kmem.usage_in_bytes配置項用于限制內(nèi)核內(nèi)存的使用,這個配置項與memory.limit_in_bytes(總內(nèi)存限額)配合使用存在下面三種情形锡宋,在lwn文章中有詳細的介紹:

????a. memory.kmem.limit_in_bytes == unlimited:這種情形不限制內(nèi)核內(nèi)存的使用儡湾。

????b. memory.kmem.limit_in_bytes < memory.limit_in_bytes:在這種情形下,我們詳細的指定了內(nèi)核內(nèi)存的上限是多少执俩。

????c. memory.kmem.limit_in_bytes >= memory.limit_in_bytes:在這種情形下徐钠,我們只關(guān)心包括內(nèi)核內(nèi)存及用戶內(nèi)存在內(nèi)的內(nèi)存的總使用情況,并不關(guān)心內(nèi)核內(nèi)存實際使用了多少役首。在實際使用中尝丐,通常是這種情形,我們將memory.kmem.limit_in_bytes設(shè)置成大于memory.limit_in_bytes衡奥,從而只限制應用的總內(nèi)存使用爹袁。

k8s從1.9版本開始runc默認Enable了kernel memory accounting,即當容器應用設(shè)置了memory limit時矮固,容器的memory cgroup中將為memory.kmem.limit_in_bytes設(shè)置整形最大值失息,從而使能內(nèi)核內(nèi)存限制機制。我們通過查看memory.kmem.slabinfo的信息即可判斷在當前cgroup中kernel memory accounting是否使能档址,如果未使能盹兢,訪問這個文件將報輸入輸出錯誤。

然而守伸,在4.0以下版本的Linux內(nèi)核對kernel memory accounting的支持并不完善绎秒,社區(qū)中逐漸爆出了slab leak causing a crash when using kmem control group問題,同時runc社區(qū)以及Kubernetes社區(qū)中也出現(xiàn)了同樣的問題尼摹,Enabling kmem accounting can break applications on CentOS7见芹、application crash due to k8s 1.9.x open the kernel memory accounting by default剂娄。對于這個問題,在內(nèi)核低于4版本的系統(tǒng)中給docker容器設(shè)置kernel-memory限制時將docker將給出以下提示:

You specified a kernel memory limit on a kernel older than 4.0. Kernel memory limits are experimental on older kernels, it won't work as expected and can cause your system to be unstable.

這個問題也是我們這次遇到問題的根本原因玄呛。kmem的泄露導致系統(tǒng)中的服務(wù)內(nèi)存申請失敗阅懦,從而造成了內(nèi)核的soft lock。這個問題的解決方法在Kernel kmem leak caused by newer versions of Docker這篇文章中有很詳細的介紹把鉴。我們解決的方案是將docker版本升級故黑,版本特性包括Disable kmem accounting in runc on RHEL/CentOS (docker/escalation#614, docker/escalation#692) docker/engine#121。



更多我的文章可以查看我的github博客

添加好友我們可以聊更多相關(guān)話題二維碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末庭砍,一起剝皮案震驚了整個濱河市场晶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怠缸,老刑警劉巖诗轻,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異揭北,居然都是意外死亡扳炬,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門搔体,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恨樟,“玉大人,你說我怎么就攤上這事疚俱∪笆酰” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵呆奕,是天一觀的道長养晋。 經(jīng)常有香客問我,道長梁钾,這世上最難降的妖魔是什么绳泉? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮姆泻,結(jié)果婚禮上零酪,老公的妹妹穿的比我還像新娘。我一直安慰自己拇勃,他們只是感情好蛾娶,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著潜秋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胎许。 梳的紋絲不亂的頭發(fā)上峻呛,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天罗售,我揣著相機與錄音,去河邊找鬼钩述。 笑死寨躁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的牙勘。 我是一名探鬼主播职恳,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼方面!你這毒婦竟也來了放钦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤恭金,失蹤者是張志新(化名)和其女友劉穎操禀,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體横腿,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡颓屑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了耿焊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揪惦。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖罗侯,靈堂內(nèi)的尸體忽然破棺而出器腋,到底是詐尸還是另有隱情,我是刑警寧澤歇父,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布蒂培,位于F島的核電站,受9級特大地震影響榜苫,放射性物質(zhì)發(fā)生泄漏护戳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一垂睬、第九天 我趴在偏房一處隱蔽的房頂上張望媳荒。 院中可真熱鬧,春花似錦驹饺、人聲如沸钳枕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鱼炒。三九已至,卻和暖如春蝌借,著一層夾襖步出監(jiān)牢的瞬間昔瞧,已是汗流浹背指蚁。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留自晰,地道東北人凝化。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像酬荞,于是被迫代替她去往敵國和親搓劫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354