Kubernetes OOM吊舱被杀死,因为内核内存增长了很多

时间:2018-12-12 22:13:22

标签: docker linux-kernel kubernetes out-of-memory

我正在研究一种Java服务,该服务基本上在网络文件系统中创建文件来存储数据。它在Ubuntu 18.04 LTS的k8s集群中运行。 当我们开始限制kubernetes的内存(限制:memory:3Gi)时,pod开始被kubernetes杀死。

一开始,我们认为这是Java进程中的内存泄漏,但是更深入地分析后,我们注意到问题是内核的内存。 我们验证了查看文件/sys/fs/cgroup/memory/memory.kmem.usage_in_bytes

我们将情况隔离为仅使用DD命令创建文件(不包含Java),如下所示:

for i in {1..50000}; do dd if=/dev/urandom bs=4096 count=1 of=file$i; done

使用dd命令,我们看到了相同的事情(内核内存一直增长到OOM)。 在k8s重新启动pod后,我做了一个describe pod:

  • 最后状态:终结
  • 原因:OOMKilled
  • 退出代码:143

创建文件会导致内核内存增加,删除这些文件会导致内存减少。但是我们的服务会存储数据,因此它会连续创建大量文件,直到由于OOMKilled而导致Pod被终止并重新启动。

我们使用带有--kernel-memory参数的独立docker测试了限制内核内存的功能,它可以按预期工作。内核内存已达到极限,并且不再增加。但是我们没有找到在kubernetes集群中实现此目标的任何方法。 有没有办法限制K8S环境中的内核内存? 为什么创建文件会导致内核内存增加而没有释放?

1 个答案:

答案 0 :(得分:0)

感谢所有这些信息,它非常有用!

在我的应用程序上,我通过以下命令创建了一个新的侧面容器来解决此问题,该容器每5分钟运行一次cron作业:

echo 3 > /proc/sys/vm/drop_caches

(请注意,您需要辅助容器以特权模式运行)

它运行良好,并且具有可预测的优点:每5分钟,您的内存缓存将被清除。