Kubernetes HPA与VPA弹性伸缩实战:从指标驱动到预测式扩缩容

Kubernetes弹性伸缩为什么需要HPA和VPA双引擎

Kubernetes容器编排中,弹性伸缩是保障服务稳定性和资源利用率的核心机制。HPA(Horizontal Pod Autoscaler)通过增减Pod副本数应对流量变化,VPA(Vertical Pod Autoscaler)通过调整Pod资源请求优化单Pod资源配置。两者解决的是不同层面的问题:HPA扩容解决”排不下的请求”,VPA调优解决”浪费资源的Pod”。

生产环境常见错误:只配HPA不配VPA,导致大量Pod资源配置偏高(内存申请4Gi实际只用800Mi),集群资源利用率低;或者只配VPA不配HPA,单Pod资源再大也扛不住流量洪峰。正确做法是两者配合使用,VPA保障合理基线,HPA应对弹性峰值。

HPA v2核心配置与指标类型

HPA v2支持三种指标源:Resource(CPU/内存)、Pods(自定义Pod指标)、Object/External(外部指标)。从Kubernetes 1.27起,HPA v2成为稳定API(autoscaling/v2)。

基础CPU伸缩配置:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  minReplicas: 3
  maxReplicas: 50
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

关键参数说明:
minReplicas: 3:最小副本数,保障基础可用性
maxReplicas: 50:最大副本数,防止无限扩容消耗集群资源
averageUtilization: 70:CPU使用率目标70%,超过此值触发扩容

HPA计算公式:desiredReplicas = ceil[currentReplicas × (currentMetric / desiredMetric)]。例如3副本CPU使用率140%,目标70%,则 ceil[3 × (140/70)] = 6

自定义指标HPA:QPS驱动扩容

CPU/内存是间接指标,对Web服务而言QPS(每秒请求数)是更直接的扩容信号。需要配合Prometheus Adapter将Prometheus指标暴露给HPA:

# Prometheus Adapter配置(ConfigMap)
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-adapter-config
data:
  config.yml: |
    rules:
    - seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
      resources:
        overrides:
          namespace: {resource: namespace}
          pod: {resource: pod}
      name:
        matches: "http_requests_total"
        as: "http_requests_per_second"
      metricsQuery: 'sum(rate(http_requests_total{namespace="<<.Namespace>>",pod=~"<<.PodName>>.*"}[2m])) by (pod)'

HPA使用自定义QPS指标:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-api-qps-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  minReplicas: 3
  maxReplicas: 100
  metrics:
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: 1000

每个Pod平均QPS超过1000时触发扩容,比CPU指标响应更快——QPS上升时CPU还没来得及飙升,HPA已经提前扩容。

HPA扩缩容行为控制与冷却

Kubernetes 1.18+支持behavior字段,精细控制扩缩容速率,防止流量毛刺导致的频繁抖动:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  minReplicas: 3
  maxReplicas: 50
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 100
        periodSeconds: 60
      - type: Pods
        value: 5
        periodSeconds: 60
      selectPolicy: Max
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 10
        periodSeconds: 60
      selectPolicy: Min

扩容策略解读:
selectPolicy: Max:取Percent和Pods两个策略中扩容幅度更大的那个
Percent: 100:每分钟最多翻倍扩容(3→6→12→24)
Pods: 5:每分钟最多新增5个Pod
– 当副本数少于5时Pods策略生效,多于5时Percent策略生效

缩容策略解读:
stabilizationWindowSeconds: 300:缩容前观察5分钟,防止流量短暂下降后回升导致的抖动
Percent: 10:每分钟最多缩容10%的副本
selectPolicy: Min:保守缩容,避免过快缩减

VPA资源推荐与自动调整

VPA有三个运行模式:
Off:仅推荐,不自动调整(推荐用于初始部署阶段)
Recommend:仅更新推荐,不重启Pod
Auto:自动调整Pod资源请求并重启Pod

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: web-api-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  updatePolicy:
    updateMode: "Auto"
  resourcePolicy:
    containerPolicies:
    - containerName: '*'
      minAllowed:
        cpu: 100m
        memory: 128Mi
      maxAllowed:
        cpu: "4"
        memory: 8Gi
      controlledResources: ["cpu", "memory"]

VPA推荐结果查看:

kubectl describe vpa web-api-vpa

# 输出中的Recommendation段
# Target:  cpu=500m, memory=512Mi  (推荐值)
# Lower Bound: cpu=200m, memory=256Mi (下限)
# Upper Bound: cpu=2, memory=4Gi     (上限)
# Uncapped Target: cpu=450m, memory=480Mi (原始推荐值)

VPA的重要限制:Auto模式下调整资源会重建Pod(删除旧Pod创建新Pod),对有状态服务不友好。因此VPA更适合无状态服务,有状态服务建议使用Recommend模式人工审核后再调整。

HPA与VPA共存配置

HPA和VPA不能同时基于同一指标(CPU/内存)进行伸缩,否则会产生冲突。正确的共存方式:

– VPA负责CPU/内存资源的right-sizing(自动调整为合理值)
– HPA基于自定义指标(QPS、延迟、队列深度等)做水平伸缩

# VPA配置:只管CPU/内存right-sizing
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: web-api-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  updatePolicy:
    updateMode: "Auto"
---
# HPA配置:基于QPS水平扩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  minReplicas: 3
  maxReplicas: 50
  metrics:
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: 1000

这种配置下,VPA持续优化每个Pod的资源请求(避免过度分配),HPA在流量增长时水平扩容(增加Pod数),两者互不干扰。

预测式扩容:KEDA与CronTrigger

HPA是响应式扩容——指标超过阈值才开始扩容,Pod启动需要时间(Java应用可能30-60秒),导致流量洪峰期间短暂过载。对于可预测的周期性流量(如每天早晚高峰),可以用KEDA的CronTrigger提前扩容:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: web-api-cron-scaler
spec:
  scaleTargetRef:
    name: web-api
  minReplicaCount: 3
  maxReplicaCount: 50
  triggers:
  - type: cron
    metadata:
      timezone: Asia/Shanghai
      start: 0 8 * * 1-5    # 工作日8点开始
      end: 0 20 * * 1-5     # 工作日20点结束
      desiredReplicas: "20"  # 高峰期预扩到20副本

KEDA CronTrigger在指定时间段将副本数调整到目标值,配合HPA的maxReplicas上限,高峰期由HPA在20基础上继续扩容,非高峰期回退到3副本。这样就实现了”预扩容+弹性伸缩”的两级策略。

弹性伸缩监控与告警

弹性伸缩本身的健康状态也需要监控——HPA可能因为指标缺失而无法工作,或者因为Cluster Autoscaler资源不足导致Pod一直Pending:

# 查看HPA状态
kubectl get hpa web-api-hpa

# 关键字段
# TARGETS:  70%/70% (当前/目标)  - 正常
# TARGETS:  <unknown>/70%       - 指标源故障
# REPLICAS: 3/3                 - 未触发扩容
# REPLICAS: 3/20               - 已扩容到20

# 检查HPA事件
kubectl describe hpa web-api-hpa | grep -A5 Events

# 常见异常
# "the HPA was unable to compute the replica count" - 指标获取失败
# "failed to get memory utilization" - metrics-server未部署
# "insufficient cpu, memory" - 集群资源不足,Pod Pending

Prometheus告警规则:

groups:
  - name: hpa_alerts
    rules:
      - alert: HPAUnableScale
        expr: kube_hpa_status_condition{condition="ScalingLimited",status="true"} == 1
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "HPA {{ $labels.hpa }} 扩容受限"

      - alert: HPAReplicasAtMax
        expr: kube_hpa_status_current_replicas == kube_hpa_spec_max_replicas
        for: 15m
        labels:
          severity: critical
        annotations:
          summary: "HPA {{ $labels.hpa }} 已达最大副本数"

HPA达到最大副本数意味着当前配置可能无法承载更大流量,需要检查是否需要增加maxReplicas或优化应用性能。VPA达到最大资源限制同理,需要评估是否需要水平拆分服务。

以上方案从HPA基础配置、自定义指标驱动、扩缩容行为控制、VPA资源调优、双引擎共存到预测式扩容,覆盖了Kubernetes弹性伸缩在生产环境中的完整落地路径。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kuberneteshpa-yu-vpa-tan-xing-shen-suo-shi-zhan-cong-zhi/

(0)
小编小编
上一篇 19小时前
下一篇 19小时前

相关推荐

发表回复

登录后才能评论