required 和 preferred 差在哪?反亲和写错了会怎样?调度之后条件变了,Pod 会被赶走吗?这篇用一个带 zone 与 cores 标签的集群,把 nodeAffinity、podAffinity、podAntiAffinity 的硬软两种写法逐个真跑了一遍。
required zone In [b](4 个副本):节点 worker3=4 required cores Gt 6 且 zone NotIn [c](同一个 matchExpressions 里的条件是 AND):节点 worker3=4(只有 cores=8 的 worker3 满足) 两个 nodeSelectorTerms(之间是 OR):zone In [b] 或 zone In [c]:节点 worker3=3 worker4=3 preferred zone=c(weight 100,8 个副本):节点 worker4=8
required…IgnoredDuringExecution 是硬条件:zone In [b] 的 4 个副本全部在 worker3;matchExpressions 里的多个条件是 AND(cores Gt 6 且 zone NotIn [c] 只剩 worker3),而多个 nodeSelectorTerms 之间是 OR(zone b 或 zone c,得到 worker3=3、worker4=3)。preferred 只是加分:zone=c(weight 100)的 8 个副本全部去了 worker4,但如果 worker4 放不下,它们仍会去别处。
5 个副本、4 个可用的 worker(控制面有污点):节点 worker=1 worker2=1 worker3=1 worker4=1;Pending 1 个
Pending Pod 的原因:0/5 nodes are available: 1 node(s) had untolerated taint(s), 4 node(s) didn't match pod anti-affinity rules. preemption: 0/5 nodes are available: 1 Preemption is not helpful for scheduling, 4 No preem
缩到 4 个副本:节点 worker=1 worker2=1 worker3=1 worker4=1podAntiAffinity required、topologyKey: kubernetes.io/hostname、同一个标签:每个节点最多 1 个。5 个副本、4 个可用的 worker(控制面有污点)只放下 4 个,第 5 个 Pending:1 node(s) had untolerated taint(s), 4 node(s) didn't match pod anti-affinity rules。副本数大于节点数时,用 required 就等于故意留 Pod 在 Pending。
5 个副本:节点 worker=1 worker2=1 worker3=1 worker4=2(全部都调度了) 扩到 9 个:节点 worker=2 worker2=2 worker3=2 worker4=3
改成 preferred(weight 100)之后 5 个副本全部调度,分布 1/1/1/2;扩到 9 个也都能调度(2/2/2/3)。它只影响打分:尽量分开,放不下就挤在一起,永远不会让 Pod 无法调度。想要“尽量均匀”应该用它,或者上一篇的 topologySpreadConstraints。
web 要求和 app=cache 的 Pod 在同一个节点(podAffinity required,hostname):节点 worker3=3(cache 在 worker3) 删掉 cache 之后:已经运行的 web Pod 节点 worker3=3(没有被驱逐) 把 web 扩到 5 个:节点 worker3=3;Pending 2 个;Pending 原因:0/5 nodes are available: 1 node(s) had untolerated taint(s), 4 node(s) didn't match pod affinity rules. preemption: 0/5 nodes are available: 5 Preemption is not helpful for scheduling. nodeAffinity required zone In [b] 的 2 个 Pod 调度后,把 worker3 的 zone 标签删掉:节点 worker3=2(没有被驱逐);再加 1 个副本:节点 worker3=2;Pending 1 个;原因:0/5 nodes are available: 1 node(s) had untolerated taint(s), 4 node(s) didn't match Pod's node affinity/selector. preemption: 0/5 nodes are available: 5 Preemption is not helpful for scheduling.
名字里的这个词意思是:只在调度那一刻检查。web 要求和 cache 同节点,3 个都在 worker3;把 cache 删掉,web 的 3 个 Pod 不会被驱逐,但扩容出来的新副本 Pending(didn't match pod affinity rules)。节点亲和也一样:调度后把 worker3 的 zone 标签删掉,已经在运行的 Pod 不动,新副本 Pending(didn't match Pod's node affinity/selector)。结果是新旧副本分布可能不一致。