为什么在 kubernetes 上禁用交换

Jer*_*obs 56 swap kubernetes

从 Kubernetes 1.8 开始,我似乎需要在我的节点上禁用交换(或设置--fail-swap-onfalse)。

我找不到 Kubernetes 坚持禁用交换的技术原因。这是出于性能原因吗?安全原因?为什么没有记录这个原因?

Mik*_*ike 48

kubernetes 的想法是将实例紧密打包以尽可能接近 100% 的利用率。所有部署都应固定 CPU/内存限制。因此,如果调度程序将 pod 发送到机器,它根本不应该使用交换。您不想交换,因为它会减慢速度。

它主要是为了性能。

  • 这对我来说没有多大意义,你当然可以通过让操作系统将一些不经常使用的内存页面放在交换中而不以明显的方式损害性能来进一步打包你的节点吗? (4认同)
  • 你的想法是,如果一个节点只有 3gig 可以免费使用......而你的新 pod 想要 4.. 它会在另一个节点上运行。 (3认同)
  • kubes 愚蠢的另一个原因 (2认同)
  • 所以他们建议当 OOM 杀手在你第一次用完 RAM 时开始收割时,整个系统崩溃停止?这怎么不是性能问题? (2认同)

小智 27

TL;DR 没有正确使用交换只是一个懒惰的黑客,它表明对内存子系统的理解很差,并且缺乏基本的系统管理技能。设计基础设施服务而不理解这些系统注定会以失败告终。

所以,我对此有一些评论,这对我来说更像是懒惰而不是功能或要求。完全有可能正确处理交换,分析内存,并确定如何正确利用内存子系统而不影响交换。有一系列围绕此构建的工具,您可以保证进程不会很容易地使用交换,因此性能点是不正确的。不放入这个工具只是懒惰的编码,总的来说,完全删除交换将损害系统性能。这里的关键是正确使用它。我同意将 pod 换出到磁盘会影响性能,但是有很多东西应该换出到磁盘。

此外,Linux 内核旨在利用交换,完全禁用它会产生负面影响。处理此问题的更好方法是将 pod 固定到主内存中,不允许它们交换到磁盘,降低 vfs 缓存压力,以便除非绝对必要,否则它不会交换,即使如此,您也可能导致固定进程在主内存耗尽的情况下使 MALLOC 失败。

根据容器中的进程,容器发生严重故障或被 OOM 杀手杀死可能会导致一些非常灾难性的结果。然而,我明白在这些容器中运行的进程在理想情况下应该是无状态和短暂的,但是在 20 年的运行系统中,我从未见过每个人都 100% 地遵循预期的设计。

此外,这还没有考虑到未来的技术,如非易失性内存,以及更新的内存系统,如 intel xpoint,这些系统可用于使用混合磁盘/内存系统显着扩展主内存。对于这些类型的系统,他们可以直接将它们用作补充主内存或利用交换文件来扩展主内存,而性能影响可忽略不计。

  • 我非常怀疑 kubernetes 项目的维护者是懒惰的。所提出的所有论点似乎都没有在 Kubernetes 中运行的容器化生态系统的背景下进行。 (8认同)
  • 他们本身并不懒惰,只是他们的优先事项似乎在 K8S 的其他方面 - 它仍然有一个很长的待办事项列表,比如更好的存储处理。 (2认同)

Ror*_*une 22

据我了解,这样做的原因是 kubelet 不是为处理交换情况而设计的,Kubernetes 团队不打算实现这一点,因为目标是 pod 应该适合主机的内存。

来自这个 GitHub 问题 #53533

对交换的支持非常重要。有保证的 pod 永远不需要交换。Burstable pod 应该在不需要交换的情况下满足他们的请求。BestEffort Pod 无法保证。kubelet 现在缺乏智能来在 pod 中提供适量的可预测行为。