拓扑分布约束
[toc]
引言
你部署了一个 3 副本的 Deployment,调度器"贴心"地把三个副本全部放到了同一个节点上——然后这个节点宕机,服务整体不可用。这不是 bug,而是调度器的默认行为:调度器只保证"放得下",不保证"放得散"。Pod 拓扑分布约束(Pod Topology Spread Constraints)就是官方给出的答案:告诉调度器"把同类 Pod 尽量均匀地铺开到各个可用区/节点/机架上"。
本文面向已了解基础调度概念(见 将Pod调度到指定节点 和 污点和容忍度)的读者,逐字段讲透 maxSkew、whenUnsatisfiable、topologyKey 三大核心参数,并给出可直接运行的完整示例。
官方文档参考
以上链接均为 Kubernetes 中文官网地址,已逐一验证有效。
1. 为什么需要拓扑分布约束
先看反面教材。一个普通的 3 副本 Deployment,没有分布约束时可能被调度成:
节点 node1 节点 node2 节点 node3
[pod] [pod] [pod] (空) (空)
三个副本同宿一节点,至少有三类问题:
- 可用性问题:node1 宕机 = 服务全灭,多副本的容灾意义归零;
- 资源争抢问题:三个副本挤在 node1 上互相抢 CPU/内存,node2、node3 却闲置;
- 滚动更新风险:滚动更新时新旧副本全部落在同一节点,一次重启波动放大三倍。
有了拓扑分布约束后,调度器会尽量铺开:
节点 node1 节点 node2 节点 node3
[pod] [pod] [pod]
拓扑域是什么
"拓扑域"由节点标签定义。常见的域划分方式:
kubernetes.io/hostname——每个节点一个域(按节点打散)topology.kubernetes.io/zone——按云厂商可用区打散(如北京一区/二区)topology.kubernetes.io/region——按地域打散- 自定义标签——按机架、电源域、机房等物理结构打散
这些标签由 kubelet 或云厂商自动打在节点上,可用 kubectl get nodes --show-labels 查看。