文章

弹性伸缩策略

弹性伸缩策略 (HPA/VPA/KEDA)

一句话:弹性伸缩是容量规划的自动化执行——HPA 按 CPU/内存扩 Pod,VPA 调整 Pod 资源配额,KEDA 按事件队列深度扩缩,Cluster Autoscaler 加节点。

弹性伸缩全景

graph TD
    subgraph Pod 级
        HPA[HPA<br/>水平扩缩 Pod 数]
        VPA[VPA<br/>垂直调资源配额]
        KEDA[KEDA<br/>事件驱动扩缩]
    end
    
    subgraph 节点级
        CA[Cluster Autoscaler<br/>Pod Pending 加节点]
        KARPENTER[Karpenter<br/>更快的节点供给]
    end
    
    subgraph 触发源
        CPU[CPU/内存]
        CUSTOM[自定义指标<br/>QPS/队列深度]
        EVENT[事件源<br/>Kafka/Redis/PG]
    end
    
    CPU --> HPA
    CPU --> VPA
    CUSTOM --> HPA
    CUSTOM --> KEDA
    EVENT --> KEDA
    HPA -->|Pod Pending| CA
    KEDA -->|Pod Pending| CA

HPA 详解

工作原理

HPA 周期(默认 15 秒):
  1. 查询指标(CPU/内存/自定义)
  2. 计算: 期望副本数 = ceil(当前副本数 × (当前指标 / 目标指标))
  3. 对比当前副本数,决定扩缩
  4. 调用 Deployment scale

配置示例

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-gateway
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-gateway
  minReplicas: 4
  maxReplicas: 20
  metrics:
    # CPU 指标
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 65
    
    # 内存指标
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 75
    
    # 自定义指标(需 Prometheus Adapter)
    - type: Pods
      pods:
        metric:
          name: http_requests_per_second
        target:
          type: AverageValue
          averageValue: "2000"
  
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
        - type: Percent
          value: 100
          periodSeconds: 60
        - type: Pods
          value: 4
          periodSeconds: 60
      selectPolicy: Max
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 25
          periodSeconds: 120
      selectPolicy: Min

HPA 扩缩公式

期望副本数 = ceil(当前副本数 × (当前指标值 / 目标指标值))

示例:
  当前: 4 副本,CPU 平均 80%
  目标: CPU 65%
  期望 = ceil(4 × (80 / 65)) = ceil(4.92) = 5 副本

边界:
  期望 < minReplicas → 取 minReplicas
  期望 > maxReplicas → 取 maxReplicas

VPA 详解

工作原理

VPA 三种模式:
  1. Auto (默认): 自动调整 request,需要重启 Pod
  2. Recreate: 调整时重建 Pod
  3. Initial: 只在 Pod 创建时设置 request,不修改运行中的

注意: VPA 和 HPA 不能同时用 CPU/内存指标(会冲突)

配置示例

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: worker-app
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: worker-app
  updatePolicy:
    updateMode: Auto  # Auto / Off / Initial
  resourcePolicy:
    containerPolicies:
      - name: worker
        minAllowed:
          cpu: 100m
          memory: 200Mi
        maxAllowed:
          cpu: 4
          memory: 8Gi
        controlledResources: ["cpu", "memory"]

KEDA 详解

优势

KEDA vs HPA:
  HPA: 适合 CPU/内存/QPS 驱动(稳态流量)
  KEDA: 适合事件驱动(突发流量、队列积压)
  
KEDA 独特能力:
  - 缩到 0(HPA minReplicas 最少 1)
  - 支持多种事件源(Kafka/Redis/PG/AWS SQS/...)
  - 更灵活的扩缩策略

配置示例:Kafka 消费者自动扩缩

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer-scaler
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: kafka-consumer
  minReplicaCount: 0       # 无消息时缩到 0
  maxReplicaCount: 30
  pollingInterval: 15       # 每 15 秒检查一次
  cooldownPeriod: 60        # 缩容前等 60 秒
  triggers:
    - type: kafka
      metadata:
        bootstrapServers: kafka:9092
        consumerGroup: order-consumer-group
        topic: orders
        lagThreshold: "100"    # 每消费组 lag > 100 时扩容
        offsetResetPolicy: latest
        partitionLimitation: "0,1,2"  # 限定分区

KEDA 支持的事件源

事件源扩缩依据
Kafka消费者 lag(积压量)
Redis队列长度 / List 长度
PostgreSQL查询结果(如行数)
AWS SQS队列深度
RabbitMQ队列消息数
Prometheus自定义指标
Cron定时扩缩(如整点扩容)

Cluster Autoscaler

工作原理

当 Pod 处于 Pending 状态时:
  1. CA 检查 Pending 原因
  2. 如果是资源不足 → 触发新节点加入
  3. 等待节点 Ready
  4. 调度 Pod 到新节点

缩容时:
  1. 找利用率低的节点
  2. 驱逐 Pod(drain)
  3. 删除节点

云厂商集成

CA 实现特点
AWSEKS Cluster Autoscaler / Karpenter原生集成 Auto Scaling Group
阿里云ACK Cluster Autoscaler按 ESS 弹性伸缩组
腾讯云TKE CA按伸缩组
自建Cluster API + CA需自己管理节点

扩缩策略最佳实践

场景推荐方案原因
Web APIHPA (CPU + QPS) + CA流量驱动、快速扩容
消息消费者KEDA (Kafka lag)事件驱动、可缩到 0
批处理KEDA (Cron)定时扩缩
数据库不弹性(固定资源)有状态不宣频繁扩缩
GPU 推理KEDA + DRAGPU 资源驱动

扩缩参数调优表

参数推荐值说明
HPA scaleUp stabilization30s防止频繁扩容
HPA scaleDown stabilization300s防止频繁缩容
HPA maxSurge (Percent)100%扩容速度:翻倍
HPA scaleDown (Percent)25%缩容速度:温和
KEDA pollingInterval15-30s检查频率
KEDA cooldownPeriod60-120s缩容等待
CA scanInterval10s节点扩缩检查频率

常见问题 / 坑点

问题原因解决方案
HPA 不扩容指标没配好检查 Prometheus Adapter / custom metrics API
扩容太慢Pod 启动慢优化镜像大小 + readinessProbe + 预热
缩容导致抖动缩容太快增加 stabilizationWindowSeconds
VPA 和 HPA 冲突同时调 CPUVPA 只调内存,HPA 调 CPU;或只用一个
CA 加节点太慢云厂商供给慢用 Karpenter / 预留节点池
KEDA 缩到 0 后不扩事件源连不上检查 trigger 连接配置

关联知识

参考资源

状态

  • HPA 详解
  • VPA 详解
  • KEDA 详解
  • Cluster Autoscaler
  • 最佳实践
  • 参数调优