想让副本均匀分布在不同可用区,应该怎么写?maxSkew 到底是怎么算的?已经失衡了会不会自己纠正?遇到不可用的 zone 为什么会卡住?这篇建一个有三个 zone 的集群,把这些情形都真跑了一遍。
topologySpreadConstraints(maxSkew 1,topologyKey zone,DoNotSchedule):zone a=2 b=2 c=2;节点 worker=1 worker2=1 worker3=2 worker4=2 对照:同样 6 个副本,没有任何约束:zone a=4 b=1 c=1;节点 worker=2 worker2=2 worker3=1 worker4=1
给 4 个 worker 打 zone 标签:worker、worker2 在 a,worker3 在 b,worker4 在 c。6 个副本写上 maxSkew: 1、topologyKey: zone、whenUnsatisfiable: DoNotSchedule,结果每个 zone 2 个(2/2/2)。没有约束时默认调度是按节点打散的,zone a 有两个节点,于是 4/1/1。maxSkew 是任意两个域之间 Pod 数的最大差值。
先用 nodeName 把 4 个 app=s2 的 Pod 强行放在 zone a 的两个节点上:zone a=4 b=0 c=0;节点 worker=2 worker2=2
再加 3 个带 maxSkew=1 约束的 Pod:zone a=4 b=1 c=2;节点 worker=2 worker2=2 worker3=1 worker4=2(zone a 从 4 个没有再增加)
新 Pod gpj59 → worker4(zone c)
新 Pod h4xwp → worker4(zone c)
新 Pod l5xqr → worker3(zone b)先用 nodeName 把 4 个 Pod 强行放进 zone a(4/0/0),再加 3 个带约束的 Pod:它们都避开了 zone a,去了 zone c(2 个)和 zone b(1 个),总数 4/1/2。zone a 没有再增加,但已有的 4 个也不会被挪走——约束只在调度新 Pod 时生效。要纠正得靠 descheduler 或重建 Pod。
默认(nodeTaintsPolicy 缺省 = Ignore:统计 zone 时还把带污点的 worker4 算进去):zone a=1 b=1 c=0;节点 worker2=1 worker3=1;Pending 4 个
Pending Pod 的原因:0/5 nodes are available: 2 node(s) had untolerated taint(s), 3 node(s) didn't match pod topology spread constraints. preemption: 0/5 nodes are available: 2 Preemption is not helpfu
加 nodeTaintsPolicy: Honor(统计 zone 时排除掉 Pod 容忍不了污点的节点):zone a=3 b=3 c=0;节点 worker=2 worker2=1 worker3=3
whenUnsatisfiable: ScheduleAnyway(只是“尽量”):zone a=3 b=3 c=0;节点 worker=1 worker2=2 worker3=3给 zone c 唯一的节点打上污点。默认情况下统计各 zone 的 Pod 数时仍把 worker4 算进去:c 永远是 0 个,而 a、b 各放 1 个之后再放就会让差值超过 1,6 个副本只调度了 2 个,其余 Pending:2 node(s) had untolerated taint(s), 3 node(s) didn't match pod topology spread constraints。加 nodeTaintsPolicy: Honor(排除掉 Pod 去不了的节点)或改成 ScheduleAnyway(软约束)都能让它们全部调度,得到 3/3。
zone 与 hostname 两个约束(都是 maxSkew 1):zone a=2 b=2 c=2;节点 worker=1 worker2=1 worker3=2 worker4=2 扩到 9 个:zone a=3 b=2 c=2;节点 worker=1 worker2=2 worker3=2 worker4=2;Pending 2 个
zone 和 hostname 同时 maxSkew: 1:6 个副本 2/2/2,节点 1/1/2/2;扩到 9 个只放下 7 个(zone 3/2/2,节点 1/2/2/2),另外 2 个 Pending——两个约束要同时满足,条件冲突时宁可不放。常见的写法是 zone 用 DoNotSchedule、hostname 用 ScheduleAnyway。