4. QoS 服务质量等级:Guaranteed、Burstable、BestEffort 三类 Pod 的调度与驱逐行为
Kubernetes 的 QoS(Quality of Service)等级是集群在资源争抢时决定 Pod 驱逐顺序的核心依据。当节点内存或 CPU 资源不足时,kubelet 会根据 Pod 的 QoS 等级执行分级驱逐,等级越低的 Pod 越先被终止。QoS 等级由 Pod 中所有容器的 requests 和 limits 配置共同决定,共分为三类:Guaranteed、Burstable、BestEffort。
4.1 三类 QoS 等级的定义与配置规则
| QoS 等级 | 配置条件 | 资源保障 | 典型场景 |
|---|---|---|---|
| Guaranteed | 每个容器都设置了 requests 和 limits,且两者相等(CPU 和内存均需满足) |
最高保障,资源完全预留,不会被超卖 | 数据库、关键中间件、有状态服务 |
| Burstable | 至少一个容器设置了 requests,且 limits > requests 或未设置 limits |
部分保障,可突发使用空闲资源 | Web 服务、API 网关、批处理任务 |
| BestEffort | 所有容器均未设置 requests 和 limits |
无保障,完全依赖空闲资源 | 开发测试、临时 Job、低优先级任务 |
关键判断点:QoS 等级是Pod 级别的属性,由 Pod 内所有容器的资源声明共同决定。只要有一个容器未设置
requests,整个 Pod 就降级为 BestEffort。
4.2 三类 Pod 的调度行为差异
调度器(kube-scheduler)在调度 Pod 时,主要依据 requests 值进行资源计算,但 QoS 等级会影响调度优先级和节点选择倾向:
- Guaranteed Pod:调度器严格按
requests预留资源,节点剩余资源必须满足所有容器的requests总和。调度优先级最高,优先分配到资源充足的节点。 - Burstable Pod:调度器按
requests计算资源占用,但允许 Pod 在运行时突发使用超出requests的资源(不超过limits)。调度优先级中等,可能被调度到资源利用率较高的节点。 - BestEffort Pod:调度器不为其预留任何资源,仅检查节点是否有空闲资源即可调度。调度优先级最低,通常被调度到负载较轻的节点,或作为“填充”任务使用。
调度优先级排序:Guaranteed > Burstable > BestEffort。在节点资源紧张时,调度器会优先保证高 QoS 等级的 Pod 被调度。
4.3 资源争抢时的驱逐行为(Eviction)
当节点内存或磁盘资源低于阈值(如 memory.available < 100Mi)时,kubelet 启动驱逐流程。驱逐顺序严格按照 QoS 等级从低到高执行:
- 第一阶段:驱逐 BestEffort Pod — 所有 BestEffort Pod 被标记为
Evicted,按内存使用量从大到小排序驱逐。 - 第二阶段:驱逐 Burstable Pod — 如果资源仍未恢复,驱逐 Burstable Pod,按内存使用量超出
requests的比例从高到低排序。 - 第三阶段:驱逐 Guaranteed Pod — 仅在极端情况下(如系统 OOM)才会驱逐 Guaranteed Pod,且按内存使用量超出
requests的比例排序。
注意:Guaranteed Pod 并非永远不会被驱逐。当节点发生内核 OOM(Out-Of-Memory)时,OOM Killer 会杀死占用内存最多的进程,此时 Guaranteed Pod 也可能被杀死,但概率远低于其他等级。
4.4 QoS 驱逐优先级与内存使用关系
下图展示了三类 Pod 在节点资源紧张时的驱逐优先级与内存使用量的关系:
4.5 实际驱逐测试示例
以下 YAML 定义了三类 QoS 等级的 Pod,可用于在测试环境中验证驱逐行为:
# guaranteed-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: guaranteed-pod
spec:
containers:
- name: stress
image: polinux/stress
resources:
requests:
memory: "200Mi"
cpu: "500m"
limits:
memory: "200Mi"
cpu: "500m"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "180M", "--vm-hang", "1"]
---
# burstable-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: burstable-pod
spec:
containers:
- name: stress
image: polinux/stress
resources:
requests:
memory: "100Mi"
cpu: "200m"
limits:
memory: "400Mi"
cpu: "800m"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "300M", "--vm-hang", "1"]
---
# besteffort-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: besteffort-pod
spec:
containers:
- name: stress
image: polinux/stress
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "500M", "--vm-hang", "1"]
测试建议:在节点上同时部署上述三个 Pod,然后通过
kubectl describe node <node-name> 观察节点资源状态。当内存压力达到驱逐阈值时,使用 kubectl get pods -o wide 查看驱逐顺序,验证 BestEffort Pod 是否最先被驱逐。
4.6 多租户场景下的 QoS 策略建议
| 租户类型 | 推荐 QoS 等级 | 原因 |
|---|---|---|
| 生产级关键租户 | Guaranteed | 资源完全预留,避免被其他租户争抢,保障 SLA |
| 普通业务租户 | Burstable | 允许突发流量,同时保证基础资源,成本与性能平衡 |
| 开发测试租户 | BestEffort | 利用空闲资源运行,成本最低,可接受被驱逐 |
| 批处理/离线租户 | BestEffort 或 Burstable(低 requests) | 优先使用空闲资源,不影响在线服务 |
多租户风险提示:如果所有租户都使用 BestEffort,一旦节点资源紧张,所有 Pod 都可能被同时驱逐,导致大面积服务中断。建议至少为关键租户设置
requests,使其进入 Burstable 或 Guaranteed 等级。