ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

报错 cannot allocate memory 或者 no space left on device ,修复K8S内存泄露问题

2021-01-21 19:32:03  阅读:1145  来源: 互联网

标签:space kmem no kubelet runc 报错 内存 cgroup memory


问题描述

一. 当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

标签:space,kmem,no,kubelet,runc,报错,内存,cgroup,memory
来源: https://www.cnblogs.com/zhangmingcheng/p/14309962.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有