Kubernetes v1.37:Memory QoS 进阶到 Beta
Memory QoS 已在 Kubernetes v1.37 中进阶到 Beta,并默认启用。 在运行 cgroup v2 的 Linux 节点上,该特性使用内存控制器, 为内核提供更好的指引来处理容器内存。 它最早在 v1.22 中以 Alpha 形式引入,并在 v1.36 中扩展了分层内存预留。
本文介绍 v1.37 中的变更、进阶到 Beta 对集群运维人员的意义,以及如何配置该特性。
v1.37 的变更
Memory QoS 为 Beta 且默认启用
MemoryQoS 特性门控在 v1.37 中已是 Beta。
这意味着在每个 v1.37 版本的 kubelet 中,该特性都会默认启用,无需更改配置。
默认开启该特性是安全的,因为默认的 kubelet 配置并不会启用内存节流或内存预留。
除非你显式配置,否则不会向 cgroup 写入 memory.high、memory.min 或 memory.low 值。
你可以通过 kubelet 配置字段选择性启用特定行为:
- 设置
memoryThrottlingFactor(例如0.9), 以对 Burstable 和 BestEffort 容器启用memory.high节流。 默认值为null,表示不进行节流。 - 将
memoryReservationPolicy设置为TieredReservation, 以通过memory.min和memory.low启用分层内存保护。 默认值为None,表示不进行内存预留。
默认的 memoryThrottlingFactor 变更为 null
在更早的 Alpha 版本中,memoryThrottlingFactor 的默认值为 0.9,
这意味着启用特性门控后,kubelet 会为容器设置 memory.high。
在 v1.37 中,默认值为 null,
因此除非你配置了具体数值,否则 kubelet 不会设置 memory.high。
作出这一变更是因为特性门控现已默认开启,
如果自动设置 memory.high,可能会节流那些此前在无节流情况下运行的工作负载。
将其设为 null 可确保升级到 v1.37 时不会改变现有集群的运行时行为。
如果你的 kubelet 配置文件中已经显式包含 memoryThrottlingFactor 值,
该值会在升级时被保留,节流行为会继续按原样工作。
如果你的配置文件不包含 memoryThrottlingFactor,
kubelet 会使用新的 null 默认值,并停止设置 memory.high。
若要在这种情况下继续启用节流,请显式添加 memoryThrottlingFactor:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
memoryThrottlingFactor: 0.9
如何在 v1.37 中配置 MemoryQoS
有关配置 Memory QoS 的完整说明,请参阅 使用 cgroup v2 的内存 QoS、 配置内存预留 以及系统要求。
仅启用内存节流
将 memoryThrottlingFactor 设置为 0 到 1 之间的值。
kubelet 使用该因子为 Burstable 和 BestEffort 容器计算 memory.high。
有关各 QoS 类如何计算 memory.high,请参阅
内存抑制。
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
memoryThrottlingFactor: 0.9
同时启用内存节流与分层内存预留
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
memoryThrottlingFactor: 0.9
memoryReservationPolicy: TieredReservation
启用分层内存预留但不启用节流
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
memoryReservationPolicy: TieredReservation
完全禁用 Memory QoS
升级后若要禁用该特性,请将特性门控设置为 false,并确保 kubelet 配置兼容。
如果 memoryThrottlingFactor 被设置为除此前默认值 0.9 以外的任何值,
或者 memoryReservationPolicy 为 TieredReservation,
kubelet 会拒绝该配置,因此若你设置过这些字段,请删除或调整它们。
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
featureGates:
MemoryQoS: false
当特性门控关闭,或 memoryReservationPolicy 不是 TieredReservation 时,
kubelet 会在 cgroup v2 节点启动时重置残留的保护设置:
将根 kubepods cgroup 的 memory.min 和 memory.low 重置为 0,
并将 Burstable QoS cgroup 的 memory.low 重置为 0。
对于容器,残留的 memory.high 值会在重启或原地调整资源等协调路径上被重置为 max。
已知限制:内存预留是节点范围的
memoryReservationPolicy 作用于节点上的每一个 Pod。
在 TieredReservation 下,每个 Guaranteed Pod 都会获得 memory.min,
每个 Burstable Pod 都会获得 memory.low;无法让单个 Pod 单独加入或退出。
若节点上同时混合了需要硬预留的工作负载和其内存应保持可回收的工作负载,
则必须为它们统一选择一种策略。
硬预留还会覆盖计入容器 cgroup 的所有内容,包括页缓存, 因此读取大文件的 Pod 可能会占住内核本可回收并提供给相邻工作负载的内存。
SIG Node 正在 kubernetes/kubernetes#140246 中跟踪以上两点。如果你受到影响,最适合在该 Issue 中说明你的工作负载情况。
后续展望
Memory QoS 的下一个里程碑是进阶到 GA。 Beta 用户的反馈将决定 GA 之前还需要做哪些调整。 如果你遇到问题,请在 kubernetes/kubernetes 提交缺陷报告。
如何进一步了解?
- KEP-2570: Memory QoS
- Pod Quality of Service Classes
- Memory QoS with cgroup v2
- Managing Resources for Containers
- Kubernetes cgroups v2 support
- Linux kernel cgroups v2 documentation
参与其中
此特性由 SIG Node 推动。 如果你有兴趣参与贡献或提供反馈,可以通过以下渠道联系我们:
- Slack:#sig-node
- 邮件列表
- SIG Node 会议