Skip to content
弹性伸缩与资源管理

弹性伸缩与资源管理

HPA 自动扩缩容、ResourceQuota / LimitRange 资源配额与限制、VPA 简介。


1. 资源请求与限制(Requests & Limits)

1.1 两个关键字段

containers:
  - name: myapp
    image: myapp:latest
    resources:
      requests:           # 调度器保证的最小资源
        cpu: "250m"       # 0.25 核
        memory: "256Mi"
      limits:             # 容器能使用的最大资源
        cpu: "500m"       # 0.5 核
        memory: "512Mi"
字段 作用 超出后果
requests 调度器用它决定 Pod 放哪个节点
limits 容器资源上限 CPU 被限流(throttle),内存被 OOMKill

1.2 CPU 单位

表示 含义
11000m 1 个 CPU 核心
500m 0.5 核
250m 0.25 核
100m 0.1 核(最低合理值)

1.3 不设 requests/limits 的后果

缺失 后果
无 requests 调度器不知道需要多少资源,可能把 Pod 调度到资源紧张的节点
无 limits 容器可以使用节点上所有可用资源,可能影响同节点其他 Pod
两者都无 Pod 被分配 BestEffort QoS,内存紧张时优先被杀死

🚨 生产必须:每个容器都必须设置 resources.requestsresources.limits。这是生产环境的第一条戒律。


2. HPA(Horizontal Pod Autoscaler)

根据 CPU/内存使用率或自定义指标自动调整 Pod 副本数

2.1 工作原理

Metrics → HPA 计算 desiredReplicas = ceil(currentReplicas × currentMetricValue / desiredMetricValue)
        → 调整 Deployment/StatefulSet 的 replicas

2.2 前提条件

  • 集群已安装 metrics-server
  • 目标 Deployment 的 Pod 已设置 resources.requests(特别是 CPU)
# 检查 metrics-server 是否运行
kubectl get pod -n kube-system | grep metrics-server

# 检查是否能获取资源指标
kubectl top pod
kubectl top node

2.3 创建 HPA

# 基于 CPU 自动扩缩(最常用)
kubectl autoscale deploy nginx-deploy --min=2 --max=10 --cpu-percent=75

# 查看 HPA
kubectl get hpa

# 查看详情(含当前指标值)
kubectl describe hpa nginx-deploy

2.4 YAML 配置(推荐方式)

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deploy
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 75     # 目标 CPU 使用率 75%
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80     # 可选:再加内存指标
  behavior:                          # 可选:控制扩缩行为
    scaleDown:
      stabilizationWindowSeconds: 300  # 缩容前观察 5 分钟
      policies:
        - type: Percent
          value: 50                    # 每次最多缩 50%
          periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0    # 扩容立即生效
      policies:
        - type: Percent
          value: 100                   # 每次最多扩 100%
          periodSeconds: 15

2.5 关键参数

参数 说明 推荐值
minReplicas 最小副本数 ≥ 2(高可用)
maxReplicas 最大副本数 按预估峰值的 2 倍
stabilizationWindowSeconds 缩容冷静期 300(5 分钟)
averageUtilization 目标利用率 CPU 70-80%,内存 80%

💡 最佳实践

  • CPU 扩缩配合 stabilizationWindowSeconds=300 防止抖动
  • HPA + Cluster Autoscaler 可实现节点级别的弹性
  • 避免同时设置 CPU 和内存作为扩缩指标(内存通常不会随负载弹性释放)

2.6 测试 HPA

# 创建压力测试 Pod
kubectl run load-test --image=busybox -it --rm -- /bin/sh
# 进入后循环请求
while true; do wget -q -O- http://nginx-service; done

# 另开窗口观察 HPA 状态
kubectl get hpa -w
kubectl get pod -w

3. ResourceQuota(资源配额)

限制命名空间的资源使用总量。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-quota
  namespace: dev
spec:
  hard:
    # 计算资源限制
    requests.cpu: "10"           # 所有 Pod 的 CPU request 总和 ≤ 10 核
    requests.memory: "20Gi"      # 所有 Pod 的内存 request 总和 ≤ 20Gi
    limits.cpu: "20"
    limits.memory: "40Gi"
    # 对象数量限制
    count/pods: "20"
    count/services: "10"
    count/secrets: "20"
    count/configmaps: "20"
    count/persistentvolumeclaims: "10"
# 查看配额使用情况
kubectl describe resourcequota team-quota -n dev
kubectl get resourcequota -n dev

4. LimitRange(资源范围限制)

为命名空间中的 Pod/容器设置默认 requests 和 limits。

apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: dev
spec:
  limits:
    - type: Container
      default:                    # 默认 limits
        cpu: "500m"
        memory: "512Mi"
      defaultRequest:             # 默认 requests
        cpu: "250m"
        memory: "256Mi"
      max:                        # 最大 limits
        cpu: "2"
        memory: "2Gi"
      min:                        # 最小 requests
        cpu: "50m"
        memory: "64Mi"
      maxLimitRequestRatio:       # limits/requests 最大比例
        cpu: "4"                  # CPU limits 不能超过 requests 的 4 倍
        memory: "2"

当用户创建不带 resources 的 Pod 时,LimitRange 会自动注入默认值。


5. VPA(Vertical Pod Autoscaler)简介

与 HPA 水平扩缩不同,VPA 调整 Pod 的 CPU/内存 requests

模式 行为
Off 仅建议,不自动调整
Initial 仅在创建时设置
Recreate 修改后重建 Pod(有中断)
Auto 修改后重建 Pod(同 Recreate)

🚨 注意:VPA 的 Recreate/Auto 模式会重启 Pod。大多数场景优先使用 HPA,VPA 适用于无法水平扩展的工作负载。


6. QoS(服务质量)等级

K8s 根据 requests 和 limits 自动分配 QoS 等级,决定 OOM 时的杀死优先级。

QoS 条件 被 OOMKill 优先级
Guaranteed requests = limits(CPU 和内存都要相等) 最低,最后被杀
Burstable 设置了 requests,但 requests ≠ limits 中等
BestEffort 未设置任何 requests 和 limits 最高,最先被杀

生产建议:关键服务使用 Guaranteed QoS。


7. 资源管理命令速查

# 查看节点资源容量和已分配
kubectl describe node <node-name> | grep -A 5 "Allocated"

# 查看 Pod 的实际资源使用(需 metrics-server)
kubectl top pod --containers

# 查看资源配额
kubectl get resourcequota -A

# 查看 LimitRange
kubectl get limitrange -A

# 删除 HPA
kubectl delete hpa nginx-hpa