upstream contribution ยท merged โœ“

one bad node killed every egressip in the cluster

github.com/ovn-kubernetes/ovn-kubernetes ยท PR #6773

๐Ÿฃ first โ€” what is "EgressIP"?

Pods normally share a node's IP for outbound traffic.
EgressIP gives pods a stable, dedicated source IP instead.
Firewalls and partners allowlist this IP โ†’ pods can reach external services.
The cluster manager assigns EgressIPs to eligible nodes using
each node's k8s.ovn.org/host-cidrs annotation.

๐Ÿ› two problems found

1. ๐Ÿ”ด conflict check aborts on one bad node
isEgressIPAddrConflict() reads every node's host-cidrs annotation.
If any node's annotation is missing or malformed โ†’ returns error.
assignEgressIPs() sees the error โ†’ aborts the entire pass.
every EgressIP in the cluster goes unassigned โ†’ cluster-wide egress outage

2. bad nodes stay in the assignment pool
A node with the egress-assignable label but broken host-cidrs
was still considered a valid target for new EgressIP assignments.
IPs assigned to unvalidatable nodes โ†’ inconsistent state.
existing assignments on the bad node were never released

๐Ÿ’ญ what changed?

before fix

node-3 loses host-cidrs
โ†“
conflict check โ†’ error
โ†“
assignEgressIPs aborts
โ†“
ALL egressips: status = []
โ†“
entire cluster: no egress ๐Ÿ’€

after fix

node-3 loses host-cidrs
โ†“
conflict check โ†’ skip + warn
โ†“
node-3 removed from pool
โ†“
existing IPs released โ†’ move
โ†“
other nodes: assigned โœ“

๐Ÿ’ก the rule

contain the blast radius.
When one component is broken, punish that component โ€” not everyone.
A bad node is a bad node. It should not take the whole fleet down.

Skip, isolate, log, and let the healthy ones keep working.
Fail closed for the individual. Fail open for the system.

merged: Aug 24 2026  |  repo: ovn-kubernetes/ovn-kubernetes pr: #6773
small fix ยท big lesson contributed by Parikshit Khedekar