← 中文资源

简体中文版本

用拓扑分布约束跨可用区分布副本

通过 topologySpreadConstraints 的 DoNotSchedule 约束保证单个可用区故障不会带走全部副本,并在真实 Pod 上验证分布结果。

阅读英文原文

概述

三个副本落在同一个节点上,可用性就等同于一个节点。调度器主要依据资源匹配与打分放置 Pod,因此一台资源充足的空节点可能接收某个 Deployment 的全部副本。拓扑分布约束增加了分布规则:带有相同标签的 Pod 会在 zone 或 host 等拓扑域之间平衡。硬约束(DoNotSchedule)拒绝放置会破坏偏斜上限的 Pod,软约束(ScheduleAnyway)优先平衡但在无法满足时仍然调度。

步骤

  1. 同时设置硬性的可用区约束与软性的节点偏好:
topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: payments
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        app: payments
  1. 确认所有可调度节点都带有可用区标签:
kubectl get nodes -L topology.kubernetes.io/zone
  1. 发布后检查 Pod 的实际落点:
kubectl get pods -n prod -l app=payments -o wide
kubectl get nodes -L topology.kubernetes.io/zone
  1. 缩容再扩容,验证约束仍会重新平衡:
kubectl scale deployment/payments --replicas=1 -n prod
kubectl scale deployment/payments --replicas=3 -n prod

验证

Pod 应分布在不同节点,且这些节点属于不同可用区;缩容到 1 再扩回 3 后,空出的可用区应被重新填充,而不是全部堆在第一个节点。若 Pod 处于 Pending,说明当前可用区数量或容量无法满足偏斜上限,应先确认容量,必要时设置 minDomains 或改用软约束。

注意事项

  • 硬约束在可用区满载或缺失时会导致 Pod Pending。
  • 分布只控制放置位置,不提供容量,每个可用区仍需足够 CPU 与内存。
  • 标签选择器应使用稳定的 app 标签,而不是带版本号的标签。
  • maxSkew 设为 1 适合小副本数,过大的值会容忍你本想避免的失衡。
  • 滚动更新期间放置会变化,发布后需要重新检查实际分布。