这篇文章已经超过一年了。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes 1.14 中用于提高稳定性的进程 ID 限制
你有没有见过有人拿走超过自己应得的饼干?那个人伸出手,抓起半打新鲜出炉的巧克力块,像饼干怪兽一样飞奔而去,大声喊着“Om nom nom nom”。
在某些罕见的工作负载中,类似的事件发生在 Kubernetes 集群内部。对于每个 Pod 和节点,所有应用程序共享的进程 ID (PID) 数量都是有限的。虽然任何一个进程或 Pod 抓住所有 PID 的情况很少发生,但一些用户正因这种行为而面临资源匮乏。因此,在 Kubernetes 1.14 中,我们引入了一项增强功能,以减轻单个 Pod 垄断所有可用 PID 的风险。
你能匀出一些 PID 吗?
在这里,我们谈论的是某些容器的贪婪。在理想情况之外,不时会发生失控的进程,尤其是在进行测试的集群中。因此,正在发生一些非常不适合生产的活动。
在这种情况下,节点内部可能会发生类似于 fork 炸弹的事情。随着资源慢慢流失,被某个像僵尸一样的进程接管,该进程不断产生子进程,其他合法的负载开始被挤掉,取而代之的是这个不断膨胀的浪费处理能力的“气球”。这可能导致同一 Pod 上的其他进程无法获得所需的 PID。这也可能导致有趣的副作用,例如节点可能会出现故障,并且该 Pod 的副本被调度到一台新机器上,在该机器上,该过程会在整个集群中重复进行。
解决问题
因此,在 Kubernetes 1.14 中,我们添加了一项功能,允许配置 kubelet 来限制给定 Pod 可以消耗的 PID 数量。如果该机器支持 32,768 个 PID 和 100 个 Pod,则可以为每个 Pod 分配 300 个 PID 的预算,以防止 PID 完全耗尽。如果管理员希望像 CPU 或内存一样过度分配 PID,他们也可以这样做,但会带来一些额外的风险。无论哪种方式,都没有一个 Pod 可以使整台机器崩溃。这将普遍防止简单的 fork 炸弹接管你的集群。
此更改允许管理员保护一个 Pod 免受另一个 Pod 的影响,但不能确保机器上的所有 Pod 可以保护节点以及节点代理本身免于崩溃。因此,我们在此版本中以 Alpha 形式引入了一项功能,该功能提供了将 Pod 上的最终用户工作负载的 PID 与节点代理(kubelet、运行时等)隔离的功能。管理员可以保留特定数量的 PID(类似于今天保留 CPU 或内存的方式),并确保它们永远不会被该机器上的 Pod 消耗。一旦该功能从 Alpha 升级到 Beta,然后在未来的 Kubernetes 版本中达到稳定状态,我们将可以防止一种容易被耗尽的 Linux 资源。
开始使用 Kubernetes 1.14。
参与其中
如果您对此功能有反馈,或者有兴趣参与设计和开发,请加入 节点特别兴趣小组。
关于作者
Derek Carr 是 Red Hat 的高级首席软件工程师。他是 Kubernetes 的贡献者,也是 Kubernetes 社区指导委员会的成员。