作者:Itamar Holder(红帽)
1.22 版本引入了 Alpha 支持,可以为 Linux 上运行的 Kubernetes 工作负载按节点配置交换内存使用情况。现在,在 1.28 版本中,对 Linux 节点上的交换的支持已升级为 Beta,并有许多新的改进。
在 1.22 版本之前,Kubernetes 不提供对 Linux 系统上交换内存的支持。这是由于在涉及交换内存时保证和计算 Pod 内存利用率的固有困难。因此,交换支持被认为超出了 Kubernetes 的初始设计范围,并且如果在节点上检测到交换内存,kubelet 的默认行为将无法启动。
在 1.22 版本中,Linux 的交换功能最初是在其 Alpha 阶段引入的。这代表着一项重大进步,为 Linux 用户提供了首次尝试交换功能的机会。然而,作为 Alpha 版本,它尚未完全开发并存在一些问题,包括对 cgroup v2 的支持不足、指标和摘要 API 统计数据不足、测试不足等等。
Kubernetes 中的交换为广泛的用户提供了大量的用例。因此,Kubernetes 项目内的节点特别兴趣小组投入了大量精力来支持 beta 版 Linux 节点上的交换。与 alpha 版本相比,kubelet 对启用交换运行的支持更加稳定和健壮,更加用户友好,并且解决了许多已知的缺点。这次升级到 Beta 版代表着朝着实现完全支持 Kubernetes 交换的目标迈出了关键一步。
如何使用
通过激活 kubelet 上的 NodeSwap 功能门,可以促进已配置交换内存的节点上的利用。此外,您必须禁用 failSwapOn 配置设置,或者必须停用已弃用的--fail-swap-on
命令行标志。
可以配置 memorySwap.swapBehavior 选项来定义节点使用交换内存的方式。例如,
# this fragment goes into the kubelet's configuration file
memorySwap:
swapBehavior: UnlimitedSwap
swapBehavior 的可用配置选项有:
- UnlimitedSwap (默认):Kubernetes 工作负载可以使用其请求的尽可能多的交换内存,最多可达系统限制。
- LimitedSwap :Kubernetes 工作负载对交换内存的利用受到限制。只有 Burstable QoS 的 Pod 才允许使用交换。
如果未指定 memorySwap 的配置并且启用了功能门,则默认情况下 kubelet 将应用与 UnlimitedSwap 设置相同的行为。
使用 kubeadm 安装启用swap
此演示需要按照 kubeadm 安装指南中概述的步骤安装 kubeadm 工具。如果节点上已启用交换,则可以继续创建集群。如果未启用交换,请参阅提供的启用交换说明。
创建交换文件并打开
我将演示创建 4GiB 的未加密swap
dd if=/dev/zero of=/swapfile bs=128M count=32
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
swapon -s # enable the swap file only until this node is rebooted
要在启动时启动交换文件,请将/swapfile swap swap defaults 0 0
等行添加到/etc/fstab
文件中。
设置启用交换的节点
---
apiVersion: "kubeadm.k8s.io/v1beta3"
kind: InitConfiguration
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
failSwapOn: false
featureGates:
NodeSwap: true
memorySwap:
swapBehavior: LimitedSwap
然后使用kubeadm init --config kubeadm-config.yaml
创建单节点集群。在 init 过程中,如果 kubelet failSwapOn 设置为 true,则会出现警告,表明节点上已启用交换。我们计划在未来的版本中删除此警告。
LimitedSwap限额是如何确定的?
交换内存的配置(包括其局限性)提出了重大挑战。它不仅容易出现配置错误,而且作为系统级属性,任何错误配置都可能危及整个节点而不仅仅是特定的工作负载。为了减轻这种风险并确保节点的健康,我们在 Beta 版中实现了 Swap,并自动配置限制。
对于 LimitedSwap ,不属于 Burstable QoS 分类的 Pod(即 BestEffort / Guaranteed QoS Pod)被禁止使用交换内存。 BestEffort QoS Pod 表现出不可预测的内存消耗模式,并且缺乏有关其内存使用情况的信息,因此很难确定交换内存的安全分配。相反, Guaranteed QoS Pod 通常用于依赖于工作负载指定的资源精确分配且内存立即可用的应用程序。为了维持上述安全性和节点健康保证,当 LimitedSwap 生效时,这些 Pod 不允许使用交换内存。
-
nodeTotalMemory :节点上可用的物理内存总量。
-
totalPodsSwapAvailable :节点上可供 Pod 使用的交换内存总量(某些交换内存可能会保留供系统使用)。
-
containerMemoryRequest :容器的内存请求。
交换限额配置为: (containerMemoryRequest / nodeTotalMemory) × totalPodsSwapAvailable
换句话说,容器能够使用的交换内存量与其内存请求、节点的总物理内存以及节点上可供 Pod 使用的交换内存总量成正比。
值得注意的是,对于Burstable QoS Pod
中的容器,可以通过指定等于内存限制的内存请求来选择退出交换使用。以这种方式配置的容器将无法访问交换内存。
它是如何工作的?
人们可以通过多种可能的方式设想在节点上使用交换。当交换已在节点上配置并可用时,SIG Node 提议应该能够配置 kubelet,以便:
- 它可以从交换开始。
- 默认情况下,它将指示容器运行时接口向 Kubernetes 工作负载分配零交换内存。
节点上的交换配置通过 KubeletConfiguration 中的 memorySwap 公开给集群管理员。作为集群管理员,您可以通过设置 memorySwap.swapBehavior 来指定存在交换内存时节点的行为。
kubelet使用CRI(容器运行时接口)API来指示CRI配置特定的cgroup v2参数(例如 memory.swap.max
),从而为容器启用所需的交换配置。然后,CRI 负责将这些设置写入容器级cgroup。
如何监控交换?
Alpha 版本的一个显着缺陷是无法监控和内省交换使用情况。这个问题已在 Kubernetes 1.28 引入的 Beta 版本中得到解决,该版本现在提供了通过多种不同方法监控交换使用情况的功能。
kubelet 的 beta 版本现在收集节点级指标统计信息,可以在/metrics/resource
和/stats/summary
kubelet HTTP 端点访问这些统计信息。这允许客户端在使用 LimitedSwap 时直接询问 kubelet 来监控交换使用情况和剩余交换内存。此外,cadvisor 中还添加了一个 machine_swap_bytes 指标,以显示计算机的总物理交换容量。
注意事项
在系统上提供可用交换会降低可预测性。 Swap 的性能比常规内存差,有时差很多数量级,这可能会导致意外的性能下降。此外,交换会改变系统在内存压力下的行为。由于启用交换允许 Kubernetes 中的工作负载使用更大的内存使用量,而这是无法预测的,因此它也会增加嘈杂邻居和意外打包配置的风险,因为调度程序无法考虑交换内存使用情况。
启用交换内存的节点的性能取决于底层物理存储。当使用交换内存时,与固态硬盘或 NVMe 等更快的存储介质相比,在每秒 I/O 操作数 (IOPS) 受限的环境(例如具有 I/O 限制的云虚拟机)中,性能会明显变差。
因此,我们不提倡在受性能限制的工作负载或环境中使用交换内存。此外,建议使用 LimitedSwap ,因为这可以显着减轻对节点造成的风险。
集群管理员和开发人员应在生产场景中使用交换之前对其节点和应用程序进行测试