本文已发布一年以上。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes v1.22 中的新功能:alpha 版支持使用交换内存

1.22 版本引入了 alpha 支持,用于在每个节点的基础上为 Kubernetes 工作负载配置交换内存使用。

在之前的版本中,Kubernetes 不支持在 Linux 上使用交换内存,因为当涉及到交换时,很难保证和核算 pod 的内存利用率。作为 Kubernetes 早期设计的一部分,交换支持被认为超出范围,如果在节点上检测到交换,则 kubelet 默认会启动失败。

但是,有许多用例将受益于 Kubernetes 节点支持交换,包括改进的节点稳定性、更好地支持具有高内存开销但工作集较小的应用程序、使用内存受限的设备以及内存灵活性。

因此,在过去的两个版本中,SIG Node 一直在努力收集适当的用例和反馈,并提出一种设计,以便以受控的、可预测的方式向节点添加交换支持,以便 Kubernetes 用户可以执行测试并提供数据,以继续在交换之上构建集群功能。节点交换内存支持的 alpha 毕业是我们实现这一目标的第一个里程碑!

它是如何工作的?

有许多可能的方式可以设想在节点上使用交换。为了使这个初始实现的范围可管理,当交换已经配置并在节点上可用时,我们已提议 kubelet 应该可以配置为

  • 它可以启动并启用交换。
  • 默认情况下,它将指示容器运行时接口为 Kubernetes 工作负载分配零交换内存。
  • 你可以配置 kubelet 来指定整个节点的交换利用率。

节点上的交换配置通过 KubeletConfiguration 中的 memorySwap 向集群管理员公开。作为集群管理员,你可以通过设置 memorySwap.swapBehavior 来指定节点在存在交换内存时的行为。

这是通过在容器运行时接口 (CRI) 中添加 memory_swap_limit_in_bytes 字段来实现的。kubelet 的配置将控制 kubelet 通过 CRI 指示容器运行时为每个容器分配多少交换内存。然后,容器运行时会将交换设置写入容器级别的 cgroup。

我如何使用它?

在已经配置了交换内存的节点上,可以通过启用 kubelet 上的 NodeSwap 功能门,并禁用 failSwapOn 配置设置--fail-swap-on 命令行标志来启用节点上 Kubernetes 对交换的使用。

你还可以选择配置 memorySwap.swapBehavior,以便指定节点将如何使用交换内存。例如,

memorySwap:
  swapBehavior: LimitedSwap

swapBehavior 的可用配置选项为

  • LimitedSwap(默认):Kubernetes 工作负载可以使用的交换量受到限制。节点上不受 Kubernetes 管理的工作负载仍然可以进行交换。
  • UnlimitedSwap:Kubernetes 工作负载可以使用它们请求的尽可能多的交换内存,直到系统限制。

如果未指定 memorySwap 的配置且启用了功能门,则默认情况下 kubelet 将应用与 LimitedSwap 设置相同的行为。

LimitedSwap 设置的行为取决于节点是否运行的是控制组 (也称为“cgroup”) 的 v1 或 v2 版本

  • cgroups v1:如果设置了 pod 的内存限制,Kubernetes 工作负载可以使用内存和交换的任意组合,直到 pod 的内存限制。
  • cgroups v2:Kubernetes 工作负载不能使用交换内存。

注意事项

在系统上启用交换会降低可预测性。交换的性能比常规内存差,有时差几个数量级,这可能会导致意外的性能下降。此外,交换会改变系统在内存压力下的行为,并且应用程序无法直接控制将其内存使用量的哪些部分交换出去。由于启用交换允许 Kubernetes 中的工作负载使用更大的内存,而这些内存无法被预测地核算,因此它还会增加吵闹的邻居和意外打包配置的风险,因为调度程序无法核算交换内存的使用。

启用交换内存的节点的性能取决于底层物理存储。当使用交换内存时,在每秒 I/O 操作数 (IOPS) 受限的环境中,例如具有 I/O 限制的云虚拟机,与固态驱动器或 NVMe 等更快的存储介质相比,性能会显著降低。

因此,我们不建议在某些性能受限的工作负载或环境中使用交换。集群管理员和开发人员应在生产场景中使用交换之前对他们的节点和应用程序进行基准测试,并且我们需要你的帮助

展望未来

Kubernetes 1.22 版本引入了对节点交换内存的 alpha 支持,我们将继续努力在 1.23 版本中实现 beta 毕业。这将包括

  • 添加通过 cgroup 控制 Pod 级别交换消耗的支持。
    • 这将包括设置从 kubelet 在主机上检测到的系统保留交换量的能力。
  • 确定一组用于节点 QoS 的指标,以便评估启用和未启用交换的节点的性能和稳定性。
  • 收集来自测试用户案例的反馈。
    • 我们将考虑为交换引入新的配置模式,例如工作负载的节点范围交换限制。

我如何了解更多?

你可以查看 Kubernetes 网站上的当前文档

有关更多信息,以及帮助进行测试并提供反馈,请参阅KEP-2400 及其设计提案

我如何参与?

我们始终欢迎你的反馈!SIG Node 定期举行会议,可以通过 Slack(频道 #sig-node)或 SIG 的邮件列表 联系到。如果你想提供帮助,请随时与我 Elana Hashman(Slack 和 GitHub 上的 @ehashman)联系。