Kubernetes HPA与VPA自动伸缩策略配置与实战调优

Kubernetes HPAVPA自动伸缩策略是集群资源管理的核心机制,前者根据负载动态调整Pod副本数,后者根据历史用量优化资源请求和限制。HPA与VPA协同配置的难点在于避免伸缩抖动、控制资源浪费率,同时保障服务在流量突增时的弹性扩容能力。

HPA自动伸缩机制与指标选择策略

HPA(Horizontal Pod Autoscaler)通过周期性查询指标并计算期望副本数来驱动水平伸缩。期望副本数的计算公式为:desiredReplicas = ceil(currentReplicas * currentMetricValue / targetMetricValue)。当当前指标值超过目标值时触发扩容,低于目标值时触发缩容。

HPA支持三种指标源:Resource指标(CPU/内存)、Pod自定义指标和外部指标。CPU指标适用于计算密集型服务,但存在滞后性——CPU饱和时请求已经在排队。对于Web服务,基于QPS或并发数的自定义指标能更早捕获负载变化。以下是同时基于CPU和内存的HPA配置:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-server-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  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
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "1000"

多指标配置下,HPA分别计算每个指标的期望副本数,取最大值作为最终目标。这种策略确保任何一个维度达到瓶颈都能触发扩容,但也可能导致副本数过度增长,需要结合behavior配置进行约束。

HPA behavior配置与伸缩抖动抑制

HPA默认的伸缩策略会因指标短期波动导致频繁扩缩容,给集群调度器带来压力并影响服务稳定性。Kubernetes 1.18引入的behavior字段允许精细控制扩缩容速率和冷却时间,是生产环境必须配置的参数。

扩容策略通常允许快速响应,缩容策略需要保守谨慎。以下配置实现秒级扩容、分钟级缩容的平滑策略:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-server-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 3
  maxReplicas: 50
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0  # 扩容立即响应
      policies:
      - type: Percent
        value: 100  # 每次最多扩容100%
        periodSeconds: 15
      - type: Pods
        value: 4    # 或最多扩容4个Pod
        periodSeconds: 15
      selectPolicy: Max
    scaleDown:
      stabilizationWindowSeconds: 300  # 缩容观察5分钟
      policies:
      - type: Percent
        value: 10  # 每次最多缩容10%
        periodSeconds: 60
      selectPolicy: Min

stabilizationWindowSeconds是抖动抑制的核心参数。扩容窗口设为0秒表示指标一超阈值立即扩容;缩容窗口设为300秒表示指标必须连续5分钟低于目标值才触发缩容,避免因瞬时流量回落而过早释放资源。selectPolicy设为Max时取所有策略中扩容幅度最大的,设为Min时取缩容幅度最小的。

Metrics Server部署与资源指标采集

HPA依赖Metrics Server提供CPU和内存指标,Metrics Server通过每个节点的Kubelet Summary API采集容器资源使用数据。部署前需确认集群启用了聚合层(API Aggregation),并配置正确的请求超时参数。

# 部署Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 生产环境建议调整参数以适配大规模集群
# 修改metrics-server Deployment添加启动参数
kubectl edit deployment metrics-server -n kube-system

# 关键启动参数:
# --kubelet-preferred-address-types=InternalIP  # 避免DNS解析延迟
# --metric-resolution=60s  # 采集间隔
# --requestheader-client-ca-file  # 证书配置
# --max-requests=0  # 取消并发限制

# 验证Metrics Server工作状态
kubectl top nodes
kubectl top pods -n production

# 输出示例:
# NAME           CPU(cores)   MEMORY(bytes)
# node-worker-1  2450m        8234Mi
# node-worker-2  1890m        6532Mi

# 排查Metrics Server采集异常
kubectl logs -n kube-system -l k8s-app=metrics-server --tail=50
# 常见错误:x509 certificate signed by unknown authority
# 解决方案:添加 --kubelet-insecure-tls 参数(仅测试环境)

Metrics Server的数据存在1-60秒的采集延迟,HPA默认每15秒轮询一次指标,实际响应延迟约30-75秒。对于需要更快响应的场景,可缩短metric-resolution为15秒,但会增加API Server和etcd的负载。

自定义指标与Prometheus Adapter集成

Resource指标仅覆盖CPU和内存,无法满足基于业务指标的精细化伸缩需求。Prometheus Adapter将Prometheus中的自定义指标注册为Kubernetes API资源,HPA即可基于QPS、消息队列深度、连接数等业务指标进行伸缩决策。

# Prometheus Adapter配置文件
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-adapter-config
  namespace: monitoring
data:
  config.yaml: |
    rules:
    - seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
      seriesFilters:
      - is: .*_total
      resources:
        overrides:
          namespace: {resource: "namespace"}
          pod: {resource: "pod"}
      name:
        matches: "^(.*)_total"
        as: "${1}_per_second"
      metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'

    - seriesQuery: 'redis_queue_length{namespace!=""}'
      resources:
        overrides:
          namespace: {resource: "namespace"}
      name:
        matches: "^(.*)"
        as: "redis_queue_length"
      metricsQuery: 'max(<<.Series>>{<<.LabelMatchers>>})'

    resourceRules:
      cpu:
        containerQuery: 'sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>}[3m])) by (<<.GroupBy>>)'
        nodeQuery: 'sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>, id="/"}[3m])) by (<<.GroupBy>>)'
        resources:
          overrides:
            namespace: {resource: "namespace"}
            node: {resource: "node"}
      memory:
        containerQuery: 'sum(container_memory_working_set_bytes{<<.LabelMatchers>>}) by (<<.GroupBy>>)'
        nodeQuery: 'sum(container_memory_working_set_bytes{<<.LabelMatchers>>,id="/"}) by (<<.GroupBy>>)'
        resources:
          overrides:
            namespace: {resource: "namespace"}
            node: {resource: "node"}

rules部分定义了如何将Prometheus指标转换为Kubernetes自定义指标。seriesQuery匹配Prometheus中的时间序列,metricsQuery定义聚合查询语句,name定义转换后的指标名称。配置完成后,HPA即可引用这些自定义指标:

# 基于redis队列长度伸缩的HPA(外部指标)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: worker-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: queue-worker
  minReplicas: 2
  maxReplicas: 30
  metrics:
  - type: External
    external:
      metric:
        name: redis_queue_length
        selector:
          matchLabels:
            queue: "task_queue"
      target:
        type: AverageValue
        averageValue: "500"  # 每500条消息扩容一个Pod

VPA资源推荐模式与配置详解

VPA(Vertical Pod Autoscaler)分析容器的历史资源使用数据,自动推荐和调整资源请求值。VPA有三种运行模式:Auto模式自动应用推荐值,在Pod重建时生效;Recreate模式立即重建Pod以应用推荐值;Off模式仅生成推荐值不自动应用,适合观察阶段。

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

minAllowed和maxAllowed约束VPA的推荐范围,防止推荐值过低导致OOM或过高导致资源浪费。controlledValues设为RequestsOnly时仅调整请求值,Limits保持不变,适合需要严格限制资源上限的场景。

Off模式是VPA上线初期的推荐配置,通过kubectl describe vpa查看推荐值而不自动应用,人工评估后逐步切换为Auto模式:

# 查看VPA推荐值
$ kubectl describe vpa api-server-vpa -n production

  Recommendation:
    Container Recommendation:
      Container Name:  api-server
      Lower Bound:
        Cpu:     250m
        Memory:  512Mi
      Target:
        Cpu:     500m
        Memory:  1Gi
      Uncapped Target:
        Cpu:     480m
        Memory:  980Mi
      Upper Bound:
        Cpu:     800m
        Memory:  2Gi

# Target是推荐值,Lower Bound和Upper Bound是95%置信区间
# Uncapped Target是忽略minAllowed/maxAllowed约束的原始推荐值

HPA与VPA冲突规避与协同配置方案

HPA和VPA同时管理同一Deployment时存在冲突风险。如果HPA基于CPU利用率伸缩,VPA同时调整CPU请求值,两者会形成反馈循环——VPA提高CPU请求导致CPU利用率下降,HPA触发缩容,实际负载未变但副本数减少,可能导致过载。Kubernetes官方明确建议:HPA和VPA不应同时管理同一资源维度的指标。

正确的协同方案是职责分离。HPA管理水平伸缩(基于QPS等业务指标),VPA管理垂直伸缩(基于CPU/内存资源指标但HPA不使用CPU指标),或者VPA仅运行在Off模式提供推荐值。以下是生产环境的推荐配置模板:

# 方案一:HPA基于CPU,VPA仅Off模式推荐
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: api-server-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: api-server
  updatePolicy:
    updateMode: "Off"  # 仅推荐不自动应用
---
# 方案二:HPA基于自定义指标,VPA自动调整CPU/内存
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-server-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 3
  maxReplicas: 50
  metrics:
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second  # 仅用业务指标,不用CPU
      target:
        type: AverageValue
        averageValue: "500"

方案一中VPA的推荐值可用于人工调整Deployment的resources字段,配合定期Review优化资源配置。方案二中HPA完全脱离CPU指标,VPA可安全地自动调整资源请求值和限制值。两种方案都规避了HPA与VPA的冲突循环,同时实现水平和垂直两个维度的弹性伸缩。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kuberneteshpa-yu-vpa-zi-dong-shen-suo-ce-lyue-pei-zhi-yu/

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

相关推荐