
K8s 亲和性与反亲和性策略避免核心服务单机扎堆的容灾实践在 Kubernetes 集群运维中很多团队对多副本容灾存在一个巨大的认知盲区他们认为只要在 Deployment 的 YAML 配置中写上replicas: 10系统就天然具备了“抗单点硬件故障”的强悍容灾能力。然而在多次大促备战的突发故障演练中我们曾目睹过令人震惊的“全军覆没”惨剧某个至关重要的支付核心服务部署了 12 个 Pod 副本。当机房内某一台高配物理宿主机64 核 256GB因为电源模块损坏意外宕机时该支付服务的所有 12 个 Pod 竟然在同一秒内全部阵亡导致整个支付链路瞬间不可用长达数分钟。深入排查后发现Kubernetes 的默认调度器Kube-Scheduler在调度 Pod 时首要考量的是哪个 Node 节点的空闲资源CPU / Memory Request最充裕。当一批新 Pod 集中创建时资源最充裕的那台大规格物理宿主机被调度器连续“塞入”了该服务的所有副本。在大促备战中如果不配置严密的Pod 反亲和性Anti-Affinity与故障域拓扑隔离配置再多的副本数也只是“把所有鸡蛋放在同一个篮子里”。默认调度的致命“扎堆”陷阱在一个拥有数十台物理节点的 Kubernetes 集群中物理节点之间可能存在规格差异如部分新采购的 64 核节点资源极其空闲当 HPA 触发批量扩容或滚动更新时Kube-Scheduler 采用 LeastRequestedPriority 算法评分评分结果使得所有副本集中被调度到同一台物理宿主机、或者同一个网络交换机Top of Rack, ToR下的机架上。一旦发生宿主机内核 Kernel Panic 或硬件断电物理机万兆网卡损坏或被网络攻击宿主机上的 Docker / Containerd 守护进程死锁部署在该物理机上的所有副本将无一幸免集群外部的监控报警瞬间亮起红灯。[物理宿主机 Node-01 (64C 256G)] - 硬件突然断电! |-- Pod-1 (支付核心) [死亡] |-- Pod-2 (支付核心) [死亡] |-- ... |-- Pod-12(支付核心) [死亡] 支付服务可用率瞬间跌为 0% !工业级防扎堆Pod 反亲和性硬隔离与软隔离配置为了确保同一个核心微服务的副本绝对分散在不同的物理故障域必须在 Deployment 的podAntiAffinity中配置拓扑分布规则。Kubernetes 提供了两种反亲和性级别硬反亲和requiredDuringSchedulingIgnoredDuringExecution刚性硬限制。如果集群中找不到满足“物理机隔离”条件的空闲节点调度器宁可让 Pod 处于Pending状态也坚决不允许与同名 Pod 挤在同一台物理机上软反亲和preferredDuringSchedulingIgnoredDuringExecution柔性权重偏好。尽量分散调度若资源极度紧张时允许适度妥协。生产级核心交易服务 YAML 模板结合物理机与可用区双重隔离apiVersion: apps/v1 kind: Deployment metadata: name: pay-core-service namespace: trade spec: replicas: 10 template: metadata: labels: app: pay-core-service spec: affinity: # 1. Pod 反亲和性严禁同一物理机与同一可用区过度扎堆 podAntiAffinity: # 硬性限制单台物理宿主机上最多只允许运行 1 个 pay-core 副本 requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - pay-core-service topologyKey: kubernetes.io/hostname # 物理主机名拓扑域 # 软性偏好尽量将 Pod 均匀分散到不同的同城可用区 (AZ) preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - pay-core-service topologyKey: topology.kubernetes.io/zone # 可用区拓扑域进阶拓扑分布约束Topology Spread Constraints在 Kubernetes 1.19 中官方推荐使用更加灵活的拓扑分布约束TopologySpreadConstraints。相比传统反亲和性的“一刀切禁止”拓扑分布约束允许精细控制各物理域之间的“最大副本倾斜差值maxSkew”。例如要求 12 个副本在 3 个可用区之间严格均匀分布任何两个可用区之间的 Pod 数量差不能超过 1spec: topologySpreadConstraints: - maxSkew: 1 # 各拓扑域之间的最大副本倾斜差值不超过 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule # 强制执行均匀分布 labelSelector: matchLabels: app: pay-core-service节点亲和性nodeAffinity核心交易与边缘业务物理隔离除了 Pod 之间的互斥在大促期间还必须防范“核心交易 Pod 与耗尽 I/O 的大数据报表 Pod 挤在同一宿主机”的互相伤害。通过为物理机打上专用标签如node-role.kubernetes.io/tier: core-oltp并配合nodeAffinity与污点容忍度Taints and Tolerationsspec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/tier operator: In values: - core-oltp # 核心交易 Pod 只能调度至专属的高频 NVMe 交易节点池在大促备战的容灾体系中高可用从来不是靠运气保证的。通过严密的物理拓扑隔离、拓扑分布约束与宿主机反亲和性配置系统才能真正做到“任凭单机风吹雨打核心服务岿然不动”。