跳到内容

11.3 Kubernetes 容量治理:调度、扩缩容与中断

Kubernetes 可以把 Pod 放到节点,也可以调整副本数,但它不知道哪种延迟、成本和故障风险对业务可接受。生产容量治理要把 requests、limits、调度约束、HPA、PDB 和租户边界看成一套相互作用的控制系统。

Requests 决定调度,Limits 约束运行

yaml
resources:
  requests:
    cpu: 500m
    memory: 768Mi
  limits:
    cpu: "2"
    memory: 1Gi

调度器按 requests 判断节点是否容纳 Pod,而不是按瞬时实际用量。request 长期高估会让节点看似已满;低估则会在峰值时过度装箱。

CPU limit 通常通过节流执行,可能在节点还有空闲 CPU 时也增加尾延迟;内存 limit 超出后进程可能被 OOM kill。是否设置 CPU limit 应由多租户风险和延迟测试决定,不能把同一模板套给所有服务。内存 request 与 limit 则应结合工作集、峰值和 OOM 恢复成本设置。

副本要跨故障域分布

三个副本若都在同一节点或可用区,数量并没有转化为可用性。可用 topology spread constraints 表达分布目标:

yaml
topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: atlas-api
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        app: atlas-api

硬约束提高隔离,却可能在容量不足时让 Pod Pending;软约束提高可调度性,却可能牺牲分布。选择必须与各故障域的预留容量匹配。

Taint/toleration 允许特定 Pod 进入节点,不会保证它一定被调度到那里;需要定向时还要结合 node affinity。不要用用户可随意添加的 label 承载安全隔离,受信任的节点标签必须由受控身份维护。

HPA 的分母来自 Request

CPU utilization 目标大致基于:

text
当前用量 / CPU request

如果容器没有相应 request,HPA 无法正确计算该资源利用率。request 改变也会在真实负载不变时改变 HPA 观察到的百分比。

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: atlas-api
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: atlas-api
  minReplicas: 3
  maxReplicas: 30
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
        - type: Percent
          value: 100
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 25
          periodSeconds: 60
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60

对队列消费者,积压量或最老消息年龄通常比 CPU 更接近需求;对延迟敏感服务,可组合并发数和业务 SLI。指标管线失效、冷启动时间和节点扩容延迟必须进入容量预算,否则 HPA 只会生成一批 Pending Pod。

不要让 HPA 和 VPA 同时争夺同一资源信号而不分析反馈回路:VPA 改 request 会改变 HPA 的 utilization 分母。

PDB 只约束自愿中断

yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: atlas-api
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: atlas-api

PDB 限制通过 Eviction API 发起的自愿中断,例如尊重 PDB 的节点 drain。它不能阻止节点宕机,也不会限制 Deployment 自己的滚动升级,更不能替代足够副本和跨域分布。

过严 PDB 会让节点永远无法维护。设置前要同时检查副本数、maxUnavailable、readiness、终止时间和集群升级策略。

Namespace 不是完整安全边界

共享集群中常组合:

  • RBAC:谁能操作哪些 API 对象;
  • ResourceQuota:限制 namespace 的总 requests、limits 和对象数量;
  • LimitRange:为单个容器设置默认值和上下界;
  • NetworkPolicy:限制通信;
  • Pod Security Admission:限制高风险 Pod 配置;
  • 独立节点池、RuntimeClass 或独立集群:处理更强隔离需求。

ResourceQuota 独立于真实集群容量;所有 namespace 的 quota 总和可以超过节点资源,因此它不能替代容量规划。Namespace 也共享控制面和部分节点内核,对不互信租户或严格合规工作负载,应评估更强边界。

生产就绪检查表

text
发布:滚动策略、readiness、优雅终止、回滚与迁移兼容
容量:requests/limits、峰值余量、HPA 指标、节点扩容时延
故障:跨节点/区域分布、PDB、依赖超时、恢复演练
安全:工作负载身份、RBAC、PSA、NetworkPolicy、镜像签名
存储:PVC 生命周期、快照一致性、RPO/RTO、异地恢复
运维:事件信号、变更审计、controller 状态、证书与密钥轮换

清单的价值不是勾完一次,而是把条件变成 admission policy、CI 检查、持续监控和定期演练。

参考资料

Built with VitePress | Software Systems Atlas