2. 资源模型与度量基础
自动扩缩容的每一次决策,最终都要落到“当前用了多少、目标是多少、还能加多少”这三个数字上。如果资源模型和度量口径不统一,HPA 的阈值再合理也会得出错误结论。本节先把 Kubernetes 的资源语义、QoS 分级、利用率算法和指标来源讲清楚,为后续 HPA、VPA、Cluster Autoscaler 的配置打下可计算的基础。
requests 与 limits:调度依据与运行边界
容器资源声明中,requests 和 limits 承担两种完全不同的职责。requests 是调度器(kube-scheduler)做放置决策的依据:它把 Pod 的 requests 累加到节点的已分配资源上,只有剩余可分配量足够时才会调度。因此 requests 决定“能不能被排上去”,而不是“实际会用多少”。limits 则是 kubelet 与内核 cgroup 施加的运行边界:CPU 超过 limit 会被 CFS 限流(throttling),内存超过 limit 会触发 OOM Kill。
CPU 是可压缩资源,超限表现为变慢而非被杀;内存是不可压缩资源,超限直接终止容器。这一差异决定了扩缩容策略:CPU 型服务可以适度让 requests 小于 limits 以提高装箱率,内存型服务则应尽量让 requests 接近 limits,避免节点内存超卖导致连锁 OOM。
resources:
requests:
cpu: "500m" # 0.5 核,调度依据
memory: "512Mi"
limits:
cpu: "1000m" # 1 核,CFS 限流上限
memory: "1Gi" # 超限触发 OOM Kill
QoS 分级:三种资源保障等级
Kubernetes 根据 requests 与 limits 的关系自动为 Pod 分配 QoS 等级,它直接影响节点资源紧张时的驱逐顺序:BestEffort 最先被驱逐,Burstable 次之,Guaranteed 最后。判定规则如下:
- Guaranteed:所有容器都设置了 CPU 和内存的 requests 与 limits,且两者相等。适合核心数据库、关键网关。
- Burstable:至少一个容器设置了 requests 或 limits,但不满足 Guaranteed 条件。绝大多数业务服务属于此类。
- BestEffort:所有容器都没有设置任何 requests 和 limits。仅适合可随时中断的批处理。
需要特别注意的是,只要有一个容器缺少 requests 或 limits,整个 Pod 就降级为 Burstable。因此为 sidecar、init 容器补齐资源声明,是保证 QoS 等级不被意外拉低的关键动作。
资源利用率:分子与分母的口径
HPA 的 averageUtilization 计算方式是:利用率 = 当前指标值 ÷ requests × 100%。分母是 requests,不是 limits,也不是节点容量。这一点极易被误解:如果某 Deployment 的 CPU requests 设为 200m,实际使用 150m,则利用率为 75%,而不是相对 limit 的 15%。
由此可推出两个工程结论:其一,requests 设得越小,同样的实际用量算出的利用率越高,HPA 越容易触发扩容;其二,若 requests 严重低于真实需求,HPA 会在负载并不高时频繁扩容,造成资源浪费。因此调优 HPA 的第一步往往是校准 requests,而不是调整阈值。
Metrics API 与自定义指标
HPA 读取指标依赖 Metrics API 体系,分为三条链路:
- resource metrics(
metrics.k8s.io):由 metrics-server 提供 CPU、内存的实时用量,支撑type: Resource的 HPA,是最常用的基础链路。 - custom metrics(
custom.metrics.k8s.io):由 Prometheus Adapter 等适配器暴露,指标与某个 Kubernetes 对象关联,如“每个 Pod 的 QPS”,支撑type: Pods或type: Object。 - external metrics(
external.metrics.k8s.io):来自集群外部系统,如消息队列积压数、云监控指标,支撑type: External。
自定义指标的价值在于:CPU 利用率并不总能代表真实压力。例如消费型服务在 CPU 不高时,Kafka 消费延迟可能已经飙升,此时用“待消费消息数”作为扩缩容信号更准确。配置时需在 HPA 中通过 metrics 字段声明指标名、目标类型与目标值,并确保适配器已注册对应的 APIService。
工程实践中的校准方法
把上述模型落到操作上,可按以下顺序推进。首先用 kubectl top pod 观察一段时间内的真实用量分布,取 P95 而非平均值作为 requests 参考,因为扩缩容要覆盖峰值而非均值。其次检查 QoS 等级,用 kubectl get pod -o jsonpath='{.status.qosClass}' 确认关键服务是否为 Guaranteed 或预期等级。然后核对 HPA 的分母口径,确保 averageUtilization 对应的 requests 与监控面板中的分母一致,避免“面板显示 40%、HPA 却按 80% 扩容”的口径错位。最后,当 CPU 指标与业务压力脱节时,引入自定义指标,把扩缩容信号切换到更贴近真实负载的维度。
资源模型与度量口径是自动扩缩容的地基。requests 决定调度与利用率分母,limits 决定运行边界,QoS 决定驱逐优先级,Metrics API 决定信号来源。只有这四者口径一致,后续的 HPA 阈值、VPA 推荐值和节点扩容判断才具备可比性。