kubernetes排错-cgroup 内存泄漏导致 pod 无法创建
创建 pod 时提示 cannot allocate memory: unknown 错误.
起因
kubernetes 无法创建 pod ,describe pod 事件提示如下:
Error: failed to create containerd task: OCI runtime create failed: container_linux.go:370: starting container process caused: process_linux.go:326: applying cgroup configuration for process caused: mkdir /sys/fs/cgroup/memory/kubepods/besteffort/podc8bfb77f-ac98-4c15-9161-f5c3eb4501dc/bill-daily: cannot allocate memory: unknown
到对应的节点,查看 kubelet 日志,也发现类似的日志:
E0307 02:07:02.444577 51168 pod_workers.go:191] Error syncing pod 18dcebc5-6c0d-4d7a-9a92-33186cd52baf ("order-auto-renew-1709748420-vkwtf_volc(18dcebc5-6c0d-4d7a-9a92-33186cd52baf)"), skipping: failed to ensure that the pod: 18dcebc5-6c0d-4d7a-9a92-33186cd52baf cgroups exist and are correctly applied: failed to create container for [kubepods besteffort pod18dcebc5-6c0d-4d7a-9a92-33186cd52baf] : mkdir /sys/fs/cgroup/memory/kubepods/besteffort/pod18dcebc5-6c0d-4d7a-9a92-33186cd52baf: cannot allocate memory
查阅网上相关资料,得知是 cgroup 内存泄露所致。
查看 cgroup 数量:
|
|
cgroup 的默认限制是 65536 , 通过这一系列检查可以发现, 当前占用的 cgroups 数量(第一个命令结果)大于65536, 新建容器会需要创建一个新的 cgroup 资源组, 系统认为已经没有 cgroup 资源可以分配了, 所以容器无法启动。
解决这个问题的办法:
-
重启机器(几乎所有资料都是重启节点解决)
-
升级内核版本(几乎所有资料都是升级到 4.x 以上,实际上 4.x 版本内核在特定的某些场景也会触发),之前我用 centos7 用的 5.12 以上版本没遇到过这个问题
-
使用脚本(重点介绍脚本,不用重启节点即可解决问题,需要做成 crontab 任务)
脚本
保存脚本名为 clean_slab_leak.sh (请自行命名),免责声明:生产环境慎用,我们的环境可以生效,不代表你们的环境可以,出了任何问题,概不负责。
|
|
执行脚本:
|
|
再次查看 cgroup 数量:
|
|
pod 也可以 run 起来了。然后再把上面的脚本做成 crontab 定时任务,定时执行即可。
总结
网上大部分教程都是提到重启节点,没有其他的处理办法,这里我们也是找了熟悉内核的同事,他们给的脚本,才无需重启节点解决问题。