跳转至

K8s HPA 自动扩缩

一句话概述:HPA(Horizontal Pod Autoscaler)根据 CPU/内存使用率或自定义指标自动增减 Pod 数量,让应用在高峰期自动扩容、低谷期自动缩容,既保证性能又节省成本。

核心知识点

概念白话解释
HPA水平 Pod 自动扩缩器 = 根据指标自动调整 Pod 数量
VPA垂直自动扩缩 = 自动调整 Pod 的 CPU/内存请求
Metrics Server指标服务器 = 收集 Pod 的 CPU/内存数据
Target Utilization目标利用率 = 你希望维持的资源使用比例
Scale-up扩容 = 增加 Pod 数量
Scale-down缩容 = 减少 Pod 数量
Stabilization Window稳定窗口 = 防止频繁伸缩的等待时间

安装配置

# 安装 Metrics Server(HPA 的数据来源)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# minikube 环境
minikube addons enable metrics-server

# 验证 Metrics Server
kubectl top nodes  # 查看节点资源使用
kubectl top pods   # 查看 Pod 资源使用

基本使用

1. 基于 CPU 的 HPA

# 先有一个 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2  # 初始2个副本
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: myapp:latest
          resources:
            requests:
              cpu: "200m"  # 必须设置 requests,HPA 才能计算利用率
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
---
# HPA 配置
apiVersion: autoscaling/v2  # 使用 v2 API
kind: HorizontalPodAutoscaler
metadata:
  name: web-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app  # 目标 Deployment
  minReplicas: 2   # 最少2个 Pod
  maxReplicas: 10  # 最多10个 Pod
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70  # CPU 平均使用率超过70%就扩容
# 命令行快速创建 HPA
kubectl autoscale deployment web-app --cpu-percent=70 --min=2 --max=10

# 查看 HPA 状态
kubectl get hpa  # 列出 HPA
kubectl describe hpa web-app-hpa  # 查看详情

2. 多指标 HPA

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: multi-metric-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70  # CPU 利用率目标70%

    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80  # 内存利用率目标80%

  behavior:  # 扩缩行为控制
    scaleUp:
      stabilizationWindowSeconds: 60  # 扩容前等60秒确认
      policies:
        - type: Percent
          value: 100  # 每次最多翻倍
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300  # 缩容前等5分钟(默认)
      policies:
        - type: Percent
          value: 10  # 每次最多缩10%
          periodSeconds: 60

3. 压力测试验证 HPA

# 给应用加压(在另一个终端)
kubectl run load-generator --rm -it --image=busybox -- /bin/sh
# 进入后执行:
while true; do wget -q -O- http://web-app-service; done

# 观察 HPA 扩容
kubectl get hpa -w  # 实时监听 HPA 状态变化
# TARGETS 列会显示当前利用率/目标利用率
# REPLICAS 列会看到 Pod 数量增加

高级用法

自定义指标 HPA

metrics:
  - type: Pods  # Pod 级别的自定义指标
    pods:
      metric:
        name: http_requests_per_second  # 自定义指标名
      target:
        type: AverageValue
        averageValue: "100"  # 每个 Pod 平均100 QPS

  - type: Object  # 外部对象指标
    object:
      describedObject:
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        name: main-ingress
      metric:
        name: requests_per_second
      target:
        type: Value
        value: "2k"  # Ingress 总 QPS 达到 2000 时扩容

StatefulSet HPA

spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: StatefulSet  # HPA 也支持 StatefulSet
    name: mysql
  minReplicas: 1
  maxReplicas: 5
  # 注意:StatefulSet 扩缩容是有序的

常见报错

报错信息原因解决方法
unable to fetch metricsMetrics Server 未安装安装 Metrics Server
missing request for cpuPod 未设置 resources.requests在 Deployment 中设置 cpu requests
<unknown>/70%指标数据还没采集到等几分钟让 Metrics Server 采集数据
频繁扩缩(抖动)stabilizationWindow 太短增加 behavior.scaleDown.stabilizationWindowSeconds
不缩容缩容窗口期内默认缩容等5分钟,耐心等

速查表

# === HPA 操作 ===
kubectl autoscale deploy <n> --cpu-percent=70 --min=2 --max=10  # 快速创建
kubectl get hpa                 # 列出 HPA
kubectl describe hpa <name>     # 查看详情
kubectl delete hpa <name>       # 删除 HPA
kubectl get hpa -w              # 实时监听

# === HPA 计算公式 ===
# 期望副本数 = ceil(当前副本数 × 当前指标值 / 目标指标值)
# 例:当前3个Pod,CPU利用率90%,目标70%
# 期望 = ceil(3 × 90/70) = ceil(3.86) = 4

# === 扩缩行为默认值 ===
# 扩容:15秒检查一次,无稳定窗口
# 缩容:15秒检查一次,5分钟稳定窗口
# 多指标时:取最大的期望副本数

# === 前提条件 ===
# 1. 安装 Metrics Server
# 2. Pod 必须设置 resources.requests
# 3. 自定义指标需要 Prometheus Adapter 等

参考:K8s HPA 文档 | 更新于 2026 年