我在GKE上遇到容器优化的操作系统问题。 如果我运行这个简单的命令https://pastebin.com/raw/0WPAnAzn来消耗所有的内存,在某些时候主机会冻结,并且不会响应任何事情。 预期的行为:这个过程应该被OOM杀手所杀。 我试过这个股票的Ubuntu和CentOS的图像,他们工作完美:进程被杀死,没有冻结。
串行控制台中有三种可能的kmsg输出:
冻结伴随着接近100%的CPU负载。
所以这是预期的行为还是有什么问题呢?
经过一些实验后,我发现它不是GKE或GCP相关的。 它甚至不涉及COS图像。
其实这是Linux内核如何处理OOM。 OOM杀手启动得太晚,并在高度记忆有限的环境中行事。 它决定使用进程的oom_score来杀死哪个进程。
在主机上运行Kubernetes时,有许多进程的oom_score_adjust值很高(这些是在规范中没有内存限制的 pod)。 如果你的RAM吃豆人的豆荚已经设定了限制,那么它的结果oom_score可能会比许多其他的进程要低。
在这种情况下,OOM杀手将首先杀死那些拥有最高杀伤率的进程,然后杀死真正的贪婪进程。 我不知道为什么,但在这种情况下,Linux完全冻结。
作为解决方法,我find了这个工具 。 安装它作为守护进程解决了这个问题。 它毫不留情地杀死贪婪的进程。
行为是预期的,并不是由COS本身造成的。 相反,它与Kubernetes如何处理节点OOM有关 。 在这种情况下,脚本正在节点中运行,而不是在POD中运行。 集装箱正在被杀害,但不是扼杀记忆的主要过程。
有一些build议和实现可以帮助为节点操作系统守护进程保留资源。
从容纳版本1.7.6的节点开始,Google容器引擎将使用Kubernetes Node Allocatable function为每个节点的计算资源预留一部分系统开销。 这将增加系统组件的可靠性,而不是增加系统开销。 此更改显式地保留了系统组件可能已经消耗的计算资源。