概念定位
topologySpreadConstraints 用 maxSkew、topologyKey、whenUnsatisfiable 三个要素表达「副本在各拓扑域之间尽量均匀」,比 podAntiAffinity 更可控:它允许指定偏差上限,也可以设置参与均衡的域数量下限。适用平台是 Kubernetes(1.19 起功能稳定)。硬模式保证偏差不超标,软模式只影响打分,跨可用区容灾与节点级打散都可以用它统一表达。
基本信息
| 适用平台 | Kubernetes,Pod 级 spec.topologySpreadConstraints |
|---|---|
| 关键字段 | maxSkew、topologyKey、whenUnsatisfiable、labelSelector、minDomains |
| 两种模式 | DoNotSchedule(硬)、ScheduleAnyway(软) |
| 默认行为 | minDomains 未设置时按实际存在的域计算均衡 |
典型使用场景
- 跨可用区均衡:让副本均匀分布在多个 zone,单区故障影响面可控
- 节点级打散:以 hostname 为域,避免多个副本挤在同一台机器
- 替换硬反亲和:反亲和无法表达「偏差不超过 1」,分布约束可以
- 多约束组合:同时按可用区与机型标签做两层分布
- 灰度观察:先用软模式上量,确认调度结果符合预期后再转硬约束
跨可用区均衡
跨可用区均衡
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
minDomains: 2
labelSelector:
matchLabels:
app: web核对与排查
核对与排查
kubectl get pods -l app=web -o custom-columns='NAME:.metadata.name,NODE:.spec.nodeName'
kubectl get nodes -L topology.kubernetes.io/zone # 域的数量
kubectl describe pod web-x | grep -A8 'Topology Spread' # 解析后的约束
kubectl get events --field-selector reason=FailedScheduling --sort-by=.lastTimestamp | tail -5字段作用
| 字段 | 作用 | 写错后果 |
|---|---|---|
| maxSkew | 各域副本数允许的偏差上限 | 设 1 且域数不整除副本数时会有额外约束 |
| whenUnsatisfiable | 硬约束或软偏好 | 硬约束下节点不足会造成 Pending |
| topologyKey | 用什么标签划分域 | 域标签缺失时整批无法调度 |
| minDomains | 参与均衡的域数量下限 | 设置过高时域不足会直接拒绝调度 |
硬模式配合 maxSkew=1 时需要预留足够的拓扑域容量,扩副本前先算出每域能放几个,否则多余副本会长时间 Pending。
同一 Pod 可以声明多条分布约束(如同时按可用区与节点),调度器需全部满足;约束越多,可用节点组合越少。
选择硬软模式的依据
- 合规或多活架构要求副本必须跨域时用 DoNotSchedule,接受偶发 Pending
- 只希望尽量分散、不能影响扩容的用 ScheduleAnyway,容量不足时自动退让
- 域数量固定且容量充足时用 minDomains 明确下限,域不足会直接拒绝调度
- 先用软模式上线观察实际分布,确认符合预期再切硬约束,避免一次性锁死调度空间