GKE 的容器优化操作系统内存不足导致冻结

GKE 的容器优化操作系统内存不足导致冻结

我在 GKE 上使用 Container-Optimized OS 时遇到问题。如果我运行这个简单的命令https://pastebin.com/raw/0WPAnAzn消耗所有 RAM,主机在某个时候会冻结并且不响应任何操作。预期行为:进程应该被 OOM 终止程序终止。我在原版 Ubuntu 和 CentOS 镜像上尝试过,效果很好:进程被终止,没有冻结。

串行控制台中有三种可能的 kmsg 输出:

  1. 在某些情况下,日志不包含与冻结相关的任何内容
  2. 有时,其他进程会连续被 OOM 终止,然后冻结,没有任何相关消息
  3. 最有趣的是:OOM 终止,随后出现内核恐慌(https://pastebin.com/raw/gtdsg6vQ

冻结伴随接近 100% 的 CPU 负载。

那么这是预期的行为还是有什么问题?

答案1

经过一些实验,我发现它与 GKE 或 GCP 无关。甚至与 COS 映像也无关。

实际上,这是 Linux 内核处理 OOM 的方式。OOM 终止程序启动得太晚,并且是在内存受限的环境中运行。它使用进程的 来决定终止哪个进程oom_score

在主机上运行 Kubernetes 时,有许多高oom_score_adjust价值的进程(这些是 pod其规格中没有内存限制)。如果您的 RAM 消耗器 pod 设置了限制,其结果oom_score可能会低于许多其他进程。

在这种情况下,OOM 终止程序将首先终止那些具有最高优先级的进程,oom_score然后才有机会终止真正贪婪的进程。我不知道为什么,但是在这种情况下 Linux 完全冻结了。

我发现一个解决方法此工具将其安装为 DaemonSet 解决了这个问题。它会毫不留情地杀死贪婪的进程。

答案2

该行为是预期行为,不是由COS形象本身。相反,它与 Kubernetes 如何处理节点 OOM。在这种情况下,脚本在节点中运行,而不是在 POD 中运行。容器被终止,但主进程并未耗尽内存。

有一些提案以及帮助为节点预留资源的实现操作系统守护进程

从运行 1.7.6 版本的节点开始,Google Container Engine 将使用 Kubernetes 保留每个节点的一部分计算资源用于系统开销节点可分配功能。这将提高系统组件的可靠性,而不会增加系统开销。此更改明确保留了系统组件可能已经消耗的计算资源。

相关内容