1. 自动扩缩容工程全景
Kubernetes 的自动扩缩容并不是一个单一功能,而是一套跨越多个抽象层次的协同机制。理解它的第一步,是分清"扩什么"和"谁来扩"。从最贴近业务的维度看,扩缩容可以划分为四个层次:Pod 副本层(一个工作负载跑多少个副本)、节点资源层(集群里有多少台可调度机器)、资源规格层(单个 Pod 申请多少 CPU/内存)、以及集群容量层(底层云资源池或物理机池的供给能力)。这四个层次各自有独立的控制器,又通过调度器和指标系统相互耦合,任何一层配置失当,都会让其他层的动作失效。
四个层次与核心组件
最上层是 Horizontal Pod Autoscaler(HPA),它根据 CPU、内存或自定义指标调整 Deployment、StatefulSet 等对象的副本数。HPA 本身不采集指标,而是从 Metrics Server 或 Prometheus Adapter 读取,再通过 scale 子资源下发副本数。与之并列的是 Vertical Pod Autoscaler(VPA),它不改变副本数量,而是调整 Pod 的 requests 与 limits,通常需要重建 Pod 才能生效,因此更适合"单副本但资源需求波动"的场景。
当 HPA 把副本数调高、而现有节点没有足够可分配资源时,Pod 会进入 Pending。此时 Cluster Autoscaler(CA) 或云厂商的 Karpenter 介入:它们监听不可调度的 Pod,判断其资源需求能否被某个节点池满足,然后调用云 API 扩容节点。缩容方向则相反——当节点长期利用率低于阈值且其上 Pod 可被迁移时,CA 会驱逐 Pod 并释放节点。最底层是云资源配额与实例类型选择,它决定了"最多能扩到多大"和"扩出来的机器是否划算"。
设计原则:让每一层各司其职
工程上最容易犯的错误,是让多层同时"抢着扩"。合理的分工是:HPA 负责应对分钟级的流量波动,CA/Karpenter 负责应对小时级的容量缺口,VPA 负责长期资源画像的修正。三者时间尺度不同,不应互相替代。第二条原则是指标必须真实反映瓶颈:如果应用是 IO 密集型,用 CPU 触发 HPA 往往反应迟钝,应改用 QPS、队列长度等自定义指标。第三条是为缩容留出缓冲,通过 stabilizationWindowSeconds 和 scaleDownDelayAfterAdd 避免副本数剧烈震荡。
工程挑战与典型参数
实际落地时,以下问题几乎必然遇到:指标延迟导致扩容滞后于流量峰值;Pending Pod 无法被满足,因为请求的实例类型配额已满;缩容抖动,节点刚释放又立刻被重新申请;以及成本失控,扩容策略过于激进。下面是一份可直接参考的 HPA 配置示例,参数为教学假设值:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 2
periodSeconds: 120
这份配置的含义是:副本数在 3 到 30 之间,CPU 平均利用率超过 65% 时扩容;扩容窗口仅 30 秒,允许每分钟翻倍;缩容窗口长达 300 秒,且每 120 秒最多减少 2 个副本。这种"快扩慢缩"的非对称策略,是应对流量突增、避免误缩容的常见做法。
currentReplicas 是否跟随 desiredReplicas 收敛;集群中 Pending Pod 的持续时间是否长期大于 1 分钟;以及节点数量变化是否与业务负载曲线同向。若 Pending 持续存在而节点数不变,问题通常出在 CA 的节点池上限或云配额,而非 HPA。