报错 cannot allocate memory 或者 no space left on device ,修复K8S内存泄露问题
问题描述
一. 当k8s集群运行日久以后,有的node无法再新建pod,并且出现如下错误,当重启服务器之后,才可以恢复正常使用。查看pod状态的时候会出现以下报错。
1 2 | applying cgroup … caused: mkdir …no space left on device 或者在describe pod的时候出现cannot allocate memory |
这时候你的 k8s 集群可能就存在内存泄露的问题了,当创建的pod越多的时候内存会泄露的越多,越快。
二. 具体查看是否存在内存泄露
1 2 3 4 5 | 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源码
1 2 3 4 5 | 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. 编译
1 2 3 4 | 安装编译组件 sudo yum install libseccomp-devel make BUILDTAGS= 'seccomp nokmem' 编译完成之后会在当前目录下看到一个runc的可执行文件,等kubelet编译完成之后会将其替换 |
二. 编译kubelet
1.下载kubernetes源码
1 2 3 4 | cd /root/go/src/github.com/ git clone https: //github.com/kubernetes/kubernetes cd kubernetes/ git checkout v1.18.6 |
2. 编译kubelet
1 | 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 备份
1 2 | mv /usr/bin/kubelet /home/kubelet mv /usr/bin/runc /home/runc |
2. 停止 docker 和 kubelet
1 2 | systemctl stop docker systemctl stop kubelet |
3. 将编译好的runc和kubelet进行替换
1 2 3 | cp kubelet /usr/bin/kubelet cp kubelet /usr/local/bin/kubelet cp runc /usr/bin/runc |
4. 检查kmem是否关闭前需要将此节点的pod杀掉重启或者重启服务器,当结果为0时成功
1 | cat /sys/fs/cgroup/memory/kubepods/burstable/memory.kmem.usage_in_bytes |
5. 是否还存在内存泄露的情况
1 | 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 (推荐)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2019-01-21 git中设置http代理和取消http代理
2015-01-21 整数(质因子)分解(Pollard rho大整数分解)
2015-01-21 应用中国剩余定理解线性同余方程组(不懂)
2015-01-21 HDU3579:Hello Kiki(解一元线性同余方程组)
2015-01-21 HDU1573:X问题(解一元线性同余方程组)