一、背景
起因:
自監(jiān)控應(yīng)用凌晨告警:Pod 內(nèi)存使用率大于80%(規(guī)格為1c1G)。內(nèi)存緩慢增長,持續(xù)到早上內(nèi)存使用率停止在81%左右。
疑點:
此模塊是一個輕任務(wù)模塊(基于go開發(fā)),請求量很低并且數(shù)據(jù)量非常少,平常內(nèi)存占用一直以來都在100MB左右,出現(xiàn)內(nèi)存不足的概率極小,而且運行了幾個月無故障。
初步定位:
登錄平常查看指標(biāo),確實有一個節(jié)點內(nèi)存異常,但另一個節(jié)點正常(這模塊有個特性是主備模式,同一時間只有一個節(jié)點工作,通過日志確定異常的節(jié)點正是工作節(jié)點)。
二、初步分析過程
登錄k8s查看內(nèi)存情況,通過 kubectl top pod 查看內(nèi)存占用果然已經(jīng)有800MB+,但理論上這模塊不應(yīng)該占用這么多內(nèi)存(截圖時間點不一樣,有部分回收)。
?繼續(xù)登錄pod內(nèi),通過 cat /sys/fs/cgroup/memory/ 查看內(nèi)存統(tǒng)計 (注意,在pod中使用 free -m 等類似的命令只能統(tǒng)計到宿主機(jī)的內(nèi)存信息,固無用)
# cd /sys/fs/cgroup/memory/
# cat memory.usage_in_bytes
顯示輸出 962097152(即約917MB,即將超過1GB限額,超過則會激活OOM Kill)
# cat memory.stat 后輸出如下圖
?其中的?rss?標(biāo)識當(dāng)前應(yīng)用進(jìn)程實際使用內(nèi)存量,55017472 = 約52MB,此數(shù)據(jù)證實了一般的設(shè)定:這個應(yīng)用一般占用都在100MB以內(nèi)。
三、懷疑監(jiān)控指標(biāo)不準(zhǔn)確?
通過了解到,激活自監(jiān)控告警的指標(biāo)是通過k8s的?container_memory_working_set_bytes?指標(biāo)超過80%告警。
通過查閱k8s源碼 promethus.go 的?Memory.WorkingSet 相關(guān)引用發(fā)現(xiàn),此參數(shù)是通過計算?Memory.Usage -?total_inactive_file?得出(即本案例是?962097152 - 111620096 = 811MB)
?(其中的?Memory.Usage 即為memory.usage_in_bytes文件中的值:962097152?)
按照此情況看,數(shù)據(jù)取值確實沒問題,同時,關(guān)注到一個指標(biāo)??total_active_file?(795275264 = 75.8MB),此參數(shù)加上rss剛好與已用內(nèi)存接近,源碼中未找到此指標(biāo)的相關(guān)信息,通過查閱官方資料發(fā)現(xiàn),此參數(shù)認(rèn)為是一個不能被計算為可用內(nèi)存的值。
也就是說 k8s 作者們認(rèn)為?此active_file內(nèi)存不認(rèn)定為可用內(nèi)存(官方地址為:https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/#active-file-memory-is-not-considered-as-available-memory )
此參數(shù)作為文件緩存是否要被計算進(jìn)已用內(nèi)存中,github上的討論已經(jīng)有了6年之久仍然是Open狀態(tài) (地址為: ?https://github.com/kubernetes/kubernetes/issues/43916)。
四、應(yīng)用分析
此應(yīng)用只有日志才用到寫文件的操作,是否是日志文件導(dǎo)致的file cache呢? 進(jìn)入到日志文件目錄 ,通過 > xxx.log 清理文件后,再次?cat memory.stat
其中的 total_active_file 立即縮小,在通過之前的命令查看內(nèi)存占用,立即恢復(fù)正常,也就是?日志文件導(dǎo)致的?total_active_file 增長從而導(dǎo)致Pod內(nèi)存使用量增大。
五、回溯代碼 & 修復(fù)措施
此應(yīng)用使用了 zap日志框架,通過配置?MaxSize 設(shè)定日志輪轉(zhuǎn)文件大小為1G,在故障時日志文件大小已經(jīng)達(dá)到了?889M。
日志一直要達(dá)到1G才會激活輪轉(zhuǎn),此前系統(tǒng)將此cache住,但是k8s認(rèn)為此內(nèi)存無法被利用,就導(dǎo)致了內(nèi)存一直在增長,直到產(chǎn)生告警。
解決方案:
為保證Pod 不被 OOM Kill,通過修改MaxSize 修改文件大小進(jìn)行輪轉(zhuǎn)(比如改為200-300M),file cache即可在日志輪轉(zhuǎn)后釋放。
文章轉(zhuǎn)載自:mikevictor
原文鏈接:https://www.cnblogs.com/mikevictor07/p/17968696文章來源:http://www.zghlxwxcb.cn/news/detail-800427.html
體驗地址:引邁 - JNPF快速開發(fā)平臺_低代碼開發(fā)平臺_零代碼開發(fā)平臺_流程設(shè)計器_表單引擎_工作流引擎_軟件架構(gòu)文章來源地址http://www.zghlxwxcb.cn/news/detail-800427.html
到了這里,關(guān)于記一次go應(yīng)用在k8s pod已用內(nèi)存告警不準(zhǔn)確分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!