cgroup内存泄露问题

2020-03-17  本文已影响0人  一舍

软硬件环境

version
kernel 4.4.58-20171215.kylin.server.YUN+-generic
docker 17.03.2-ce-rc1
runc version 1.0.0-rc10+dev
kubernetes 1.14.1

问题现象

问题首先出现是操作系统出现了只读,经过排查系统日志,发现了以下关键词:

SLUB: Unable to allocate memory on node -1
No space left on device

以上现象,据查是由于cgroup内存泄露引起的。

问题分析

什么是cgroup内存泄露呢,这要从内核的kernel memory accounting机制说起。

为了防止出现“fork bomb”,社区中就有人提议通过linux内核限制cgroup中的kmem容量使用,从而限制恶意进程的行为。于是就有了kernel memory accounting机制。

kernel memory accounting机制为cgroup的内存限制增加了stack pages(例如新进程创建)、 slab pages(SLAB/SLUB分配器使用的内存)、sockets memory pressure、tcp memory pressure等。

有人会说,既然kernel memory accounting机制是为了限制cgroup中的kmem容量使用,那为什么还会出现内存无法分配的问题呢,一句话总结,就是当前的内核版本对kernel memory accounting机制的支持存在BUG。

解决方案

  1. 重新编译runc,关闭kmem,替换原先的runc。编译方法如下(可参照https://github.com/opencontainers/runc#build-tags):
go get github.com/opencontainers/runc
cd $GOPATH/src/github.com/opencontainers/runc
make BUILDTAGS='nokmem'
  1. 重新编译kubelet,关闭kmem,替换原先的kubelet。编译方法如下:
git clone https://github.com/kubernetes/kubernetes
cd kubernetes
git checkout v1.14.1
make kubelet GOFLAGS="-tags=nokmem"
  1. 重启机器
  2. 验证禁用是否生效,方法和正确结果如下:
cat /sys/fs/cgroup/memory/kubepods/burstable/pod<pod-id>/<containerID>/memory.kmem.slabinfo
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
cat /sys/fs/cgroup/memory/kubepods/burstable/pod<podid>/<containerID>/memory.kmem.usage_in_bytes
0

参考资料:

  1. https://github.com/kubernetes/kubernetes/issues/61937
  2. https://tencentcloudcontainerteam.github.io/2018/12/29/cgroup-leaking/
  3. https://github.com/opencontainers/runc
  4. http://www.iceyao.com.cn/2020/01/04/%E8%AE%B0%E4%B8%80%E6%AC%A1k8s-cgroup%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3/
上一篇下一篇

猜你喜欢

热点阅读