Skip to content
返回运维与 SRE

自动扩缩

配对流量变快响应的自动扩缩,带合适指标和冷却。

为什么

手动扩缩不扩 — 值班无法看 50 服务并随流量移各扩。自动扩缩(K8s HPA、KEDA、云自动扩缩器)看指标(CPU、队列深、自定义)并自动调副本,故流量尖峰 30-60 秒扩服务无人工。关键是配对:按正确指标扩(worker 队列深、web CPU、延迟敏感 RPS)、够快扩(扩上 30s 稳定、扩下 5m 避抖振)、设 sane 边界(min 副本处理基线、max 封成本)。错配自动扩缩比无更糟 — 跨 1 pod 按均 CPU 扩的 HPA 在那 pod 100% 时无(均 100%、目标 70%、扩到 2,但新 pod 60s 启且原仍 100%)。配对、负载测它、让它处理常规扩缩而人处理例外。

何时使用

对所有见变流量的服务。把自动扩缩作基线;用预测处理可预测尖峰。

如何做

1. 按服务类型选正确扩缩指标
   - Web 服务:CPU(70% 目标)或每 pod RPS(延迟敏感)
   - Worker:队列深(积压 > N 时扩)
   - 批:作业完成率或队列龄
   - 别按队列深扩 web 或按 CPU 扩 worker — 错指标

2. 设快扩上、慢扩下
   - 扩上:0-30s 稳定(快反应尖峰)
   - 扩下:5m 稳定(别对流量振荡抖振)
   - K8s:behavior.scaleUp.stabilizationWindowSeconds: 0,scaleDown: 300

3. 设 min 和 max 副本
   - Min:够处理基线流量 + 1(pod 重启无停机)
   - Max:封防失控成本(如 50 pod max);撞 max 则告警
   - Max 应够尖峰但够低不破产

4. 用负载测自动扩缩
   - 2x、5x、10x 流量 → 它扩吗?多快?延迟留 SLO 内?
   - 测扩下:降流量 → 它缩无丢在飞请求?

5. 监控并调
   - 跟踪扩缩事件:多频、多快、跟上?
   - 若总在 max → 提 max 或修瓶颈(DB 非 pod)
   - 若抖振 → 增扩下稳定

示例

# checkout 的 K8s HPA(web 服务,基于 CPU):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: checkout
spec:
  scaleTargetRef:
    kind: Deployment
    name: checkout
  minReplicas: 3          # 基线 + 1(处理重启)
  maxReplicas: 50         # 封;撞则告警
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70   # 30% 余量
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0    # 立即扩
      policies:
        - type: Percent
          value: 100                   # 每分钟可翻倍
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300  # 扩下前 5m
      policies:
        - type: Percent
          value: 10                    # 慢扩下(每分钟 10%)
          periodSeconds: 60

# order-worker 的 KEDA(基于队列):
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: order-worker
spec:
  scaleTargetRef:
    name: order-worker
  minReplicaCount: 1
  maxReplicaCount: 20
  triggers:
    - type: aws-sqs
      metadata:
        queueName: orders
        queueLength: "10"    # 队列每 10 消息 1 pod

# 在 max 时告警(无法再扩):
- alert: CheckoutAtMaxReplicas
  expr: kube_deployment_status_replicas{deployment="checkout"} == 50
  for: 5m
  labels: { severity: page }
  annotations:
    summary: "checkout 在 max 副本(50)— 流量超容量,提 max 或修瓶颈"

常见问题

  • ⚠按错指标扩 — 队列处理 worker 用 CPU(应队列深)或 web 服务用队列深(应 CPU/RPS)。
  • ⚠扩上太慢 — 5m 稳定意尖峰过 pod 才就绪;扩上用 0-30s。
  • ⚠无 max 副本 — 失控扩缩破产团队;设 max 并撞时告警(意须修瓶颈非加更多 pod)。
  • ⚠扩下抖振 — 0s 稳定意 pod 随流量振荡每 30s 缩又扩;扩下用 5m。

最佳实践

  • ✓按服务类型按正确指标扩:web 用 CPU/RPS、worker 用队列深、批用作业率。
  • ✓设快扩上(0-30s 稳定)和慢扩下(5m)以快反应尖峰无振荡抖振。
  • ✓设 min(基线 + 1)和 max 副本;撞 max 时告警 — 意流量超容量且须修瓶颈非加 pod。
  • ✓用负载测(2x、5x、10x)测自动扩缩并监控扩缩事件;按实际行为调稳定和策略。