Pod 服务质量类别

本页介绍了 Kubernetes 中的服务质量 (QoS) 类,并解释了 Kubernetes 如何根据您为 Pod 中容器指定的资源约束为每个 Pod 分配 QoS 类。Kubernetes 依靠这种分类来决定当节点上可用资源不足时应该驱逐哪些 Pod。

服务质量 (QoS) 类

Kubernetes 会对您运行的 Pod 进行分类,并将每个 Pod 分配到特定的服务质量 (QoS) 类中。Kubernetes 使用该分类来影响不同 Pod 的处理方式。Kubernetes 根据 Pod 中 容器资源请求(Requests) 以及这些请求与资源限制(Limits)的关系来进行此分类。这被称为 服务质量 (QoS) 类。Kubernetes 根据 Pod 内各个容器的资源请求和限制为每个 Pod 分配 QoS 类。Kubernetes 使用 QoS 类来决定在节点遭遇 节点压力 时应驱逐哪些 Pod。可能的 QoS 类有 GuaranteedBurstableBestEffort。当节点资源耗尽时,Kubernetes 会首先驱逐该节点上运行的 BestEffort Pod,其次是 Burstable Pod,最后是 Guaranteed Pod。当这种驱逐是由资源压力引起时,只有超过资源请求的 Pod 才会成为驱逐对象。

Guaranteed

Guaranteed 级别的 Pod 具有最严格的资源限制,最不容易被驱逐。它们保证在超过其限制或没有可从节点抢占的较低优先级 Pod 之前不会被终止。它们不能获取超过其指定限制的资源。这些 Pod 还可以使用 static CPU 管理策略来利用独占 CPU。

标准

要使 Pod 被赋予 Guaranteed QoS 类:

  • Pod 中的每个容器都必须有内存限制和内存请求,且两者均大于零。
  • 对于 Pod 中的每个容器,内存限制必须等于内存请求。
  • Pod 中的每个容器都必须有 CPU 限制和 CPU 请求,且两者均大于零。
  • 对于 Pod 中的每个容器,CPU 限制必须等于 CPU 请求。

如果 Pod 使用的是 Pod 级资源

特性状态: Kubernetes v1.34 [beta](默认启用)
  • Pod 必须具有 Pod 级的内存限制和内存请求,并且它们的值必须相等。
  • Pod 必须具有 Pod 级的 CPU 限制和 CPU 请求,并且它们的值必须相等。

Burstable

Burstable 级别的 Pod 根据请求具有一定的资源下限保证,但不需要特定的限制。如果未指定限制,它默认为等同于节点容量的限制,这允许 Pod 在有资源可用时灵活地增加其资源使用量。在因节点资源压力导致的 Pod 驱逐事件中,这些 Pod 仅在所有 BestEffort Pod 被驱逐后才会被驱逐。由于 Burstable Pod 可能包含没有资源限制或请求的容器,因此 Burstable Pod 可能会尝试使用任意数量的节点资源。

标准

如果满足以下条件,Pod 将被赋予 Burstable QoS 类:

  • 该 Pod 不符合 Guaranteed QoS 类的标准。
  • Pod 中至少有一个容器有内存或 CPU 请求或限制,或者该 Pod 有 Pod 级的内存或 CPU 请求或限制。

BestEffort

BestEffort QoS 类中的 Pod 可以使用未专门分配给其他 QoS 类 Pod 的节点资源。例如,如果您有一个具有 16 个 CPU 核心供 kubelet 使用的节点,并且您将 4 个 CPU 核心分配给了 Guaranteed Pod,那么 BestEffort QoS 类中的 Pod 就可以尝试使用剩余 12 个 CPU 核心中的任意数量。

如果节点面临资源压力,kubelet 会优先驱逐 BestEffort Pod。

标准

如果一个 Pod 不符合 GuaranteedBurstable 的标准,则其 QoS 类为 BestEffort。换句话说,只有当 Pod 中的容器都没有内存限制或内存请求,且都没有 CPU 限制或 CPU 请求,并且该 Pod 没有任何 Pod 级内存或 CPU 限制或请求时,Pod 才是 BestEffort。Pod 中的容器可以请求其他资源(非 CPU 或内存),并仍然被归类为 BestEffort

使用 cgroup v2 的内存 QoS

特性状态: Kubernetes v1.22 [alpha](默认禁用)

内存 QoS 使用 cgroup v2 的内存控制器来管理 Kubernetes 中的内存限制和保护。它利用 Pod 的 QoS 类来决定应用哪些 cgroup 设置,但这是一个可选的独立特性。禁用内存 QoS 不会改变 Pod 的分类方式。

内存限制(Throttling)

对于 Burstable Pod,kubelet 会设置 memory.high 以在工作负载达到其硬限制 (memory.max) 之前对其内存分配进行限制。限制阈值的计算方式如下:

memory.high = requests + memoryThrottlingFactor * (limits - requests)

其中 memoryThrottlingFactor 默认值为 0.9。例如,一个内存请求为 256 MiB 且限制为 1 GiB 的容器,其 memory.high 将被设置为约 947 MiB。如果 Burstable 容器没有内存限制,则使用节点的可分配内存来代替限制。

Guaranteed Pod 不会获得 memory.high,因为它们的请求等于其限制。BestEffort Pod 也不会获得 memory.high,因为它们没有请求或限制。

配置内存预留

内存预留通过 kubelet 配置字段 memoryReservationPolicy 进行控制:

  • None(默认):kubelet 不会为容器和 Pod 设置 memory.minmemory.low。没有任何内存被内核硬锁定。
  • TieredReservation:kubelet 根据 Pod 的 QoS 类设置分层内存保护:
    • Guaranteed Pod:memory.min 设置为内存请求量。在任何情况下,内核都不会回收此内存。
    • Burstable Pod:memory.low 设置为内存请求量。内核会优先保留此内存,但在极端压力下可能会回收它。
    • BestEffort Pod:不设置内存保护。

系统要求

内存 QoS 需要使用 cgroup v2 的 Linux 内核。建议使用内核 5.9 或更高版本,因为在旧版本内核上进行 memory.high 限制可能会触发已知的 livelock(活锁)错误。如果 MemoryQoS 特性开关在较旧的内核上启用,kubelet 会在启动时记录警告信息。

某些行为与 QoS 类无关

某些行为与 Kubernetes 分配的 QoS 类无关。例如:

  • 任何超过资源限制的容器都将被 kubelet 杀死并重启,且不会影响该 Pod 中的其他容器。

  • 如果一个容器超过了其资源请求,且其运行的节点面临资源压力,则该容器所属的 Pod 将成为 驱逐 对象。如果发生这种情况,Pod 中的所有容器都将被终止。Kubernetes 可能会创建一个替换 Pod,通常是在另一个节点上。

  • Pod 的资源请求等于其各组件容器资源请求之和,Pod 的资源限制等于其各组件容器资源限制之和。

  • kube-scheduler 在选择 抢占 哪些 Pod 时不考虑 QoS 类。当集群没有足够的资源来运行您定义的所有 Pod 时,可能会发生抢占。

  • QoS 类是在 Pod 创建时确定的,并在 Pod 的生命周期内保持不变。如果您稍后尝试进行会导致不同 QoS 类的 原地调整大小 (in-place resize),该调整请求将被准入控制拒绝。

接下来


最后修改于 2026 年 4 月 5 日凌晨 1:01 (PST): KEP-2570: 更新 v1.36 的内存 QoS 文档 (d4c6c9d44e)