報錯 cannot allocate memory 或者 no space left on device ,修復K8S內存泄露問題


問題描述

一. 當k8s集群運行日久以后,有的node無法再新建pod,並且出現如下錯誤,當重啟服務器之后,才可以恢復正常使用。查看pod狀態的時候會出現以下報錯。

applying cgroup … caused: mkdir …no space left on device
或者在describe pod的時候出現cannot allocate memory

這時候你的 k8s 集群可能就存在內存泄露的問題了,當創建的pod越多的時候內存會泄露的越多,越快。

二. 具體查看是否存在內存泄露

cat /sys/fs/cgroup/memory/kubepods/memory.kmem.slabinfo
當出現cat: /sys/fs/cgroup/memory/kubepods/memory.kmem.slabinfo: Input/output error則說明不存在內存泄露的情況
如果存在內存泄露會出現
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>

解決方案

一. 解決方法思路:關閉 runc 和 kubelet 的 kmem,因為升級內核的方案改動較大,此處不采用。

二. kmem導致內存泄露的原因:

內核對於每個 cgroup 子系統的的條目數是有限制的,限制的大小定義在 kernel/cgroup.c #L139,當正常在 cgroup 創建一個 group 的目錄時,條目數就加1。我們遇到的情況就是因為開啟了 kmem accounting 功能,雖然 cgroup 的目錄刪除了,但是條目沒有回收。這樣后面就無法創建65535個 cgroup 了。也就是說,在當前內核版本下,開啟了 kmem accounting 功能,會導致 memory cgroup 的條目泄漏無法回收。

具體實現

一. 需要重新編譯 runc

1. 需要配置go語言環境

2. 下載runc源碼

mkdir -p /data/Documents/src/github.com/opencontainers/
cd /data/Documents/src/github.com/opencontainers/
git clone https://github.com/opencontainers/runc
cd runc/
git checkout v1.0.0-rc9  # 切到v1.0.0-rc9 tag

3. 編譯

安裝編譯組件
sudo yum install libseccomp-devel
make BUILDTAGS='seccomp nokmem'
編譯完成之后會在當前目錄下看到一個runc的可執行文件,等kubelet編譯完成之后會將其替換

二. 編譯kubelet

1.下載kubernetes源碼

cd /root/go/src/github.com/
git clone https://github.com/kubernetes/kubernetes
cd kubernetes/
git checkout v1.18.6

2. 編譯kubelet

GO111MODULE=on KUBE_GIT_TREE_STATE=clean KUBE_GIT_VERSION=v1.18.6 make kubelet GOFLAGS="-tags=nokmem"

 生成的kubelet二進制文件在生成的_output路徑下。

三. 替換原有的 runc 和 kubelet

1、將原有 runc 和 kubelet 備份

mv /usr/bin/kubelet /home/kubelet
mv /usr/bin/runc /home/runc  

2. 停止 docker 和 kubelet

systemctl stop docker
systemctl stop kubelet

3. 將編譯好的runc和kubelet進行替換

cp kubelet /usr/bin/kubelet
cp kubelet /usr/local/bin/kubelet
cp runc /usr/bin/runc

4. 檢查kmem是否關閉前需要將此節點的pod殺掉重啟或者重啟服務器,當結果為0時成功

cat /sys/fs/cgroup/memory/kubepods/burstable/memory.kmem.usage_in_bytes

5. 是否還存在內存泄露的情況

cat /sys/fs/cgroup/memory/kubepods/memory.kmem.slabinfo

6.經測試需要重啟服務器后內存泄漏問題才能解決

參考:https://zhuanlan.zhihu.com/p/343031257

參考:https://zhuanlan.zhihu.com/p/106757502

參考:https://blog.csdn.net/qq_33317586/article/details/109285758 (推薦)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM