mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/kube-vip/kube-vip.git
synced 2026-09-20 08:03:47 +08:00
* fix(endpoints): recompute and withdraw only when no longer referenced Track EndpointSlice/Endpoints deletions in provider state instead of stopping the watcher or clearing unconditionally. Recompute the aggregate endpoint set after each deletion and only withdraw local routing/BGP/DNAT state once no tracked object still references it, matching the existing behaviour for a Modified event that reduces endpoints to zero. Remove the now-unreachable per-mode delete()/deleteAction() hooks, which acted on stale pre-deletion state and could withdraw prematurely while another object still referenced the same address. Fix the WireGuard control-plane endpoint watcher to drop deleted objects from its cache instead of reloading them as still current. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> * feat(worker): support global leader election for BGP and WireGuard Wire the existing global leader-election machinery into BGP.StartServices and WireGuard.StartServices so both modes can run with a single node advertising all services, matching the option already available for ARP and RoutingTable. WireGuard has no multipath mechanism, so it must always run some form of leader election (per-service or global); remove its no-election path and the redundant services watcher previously started from OnStartedLeading, which would have run a second time alongside the global election path. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> * fix(services): drop unnecessary election guard on route teardown route.Manager.Delete is reference-counted per route and safe to call even when nothing is tracked for it, exactly like the existing BGP host teardown. Remove the leader-election guard on the RoutingTable branch of deleteService so both branches read identically and route cleanup runs consistently across all leader-election configurations. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> * fix(endpoints): treat an unknown ready condition as ready Deferring a nil Serving to Ready matched the Serving godoc but stopped half way: per the EndpointConditions.Ready godoc a nil Ready is an unknown state that consumers should interpret as ready, which is what kube-proxy does. An endpoint with both conditions unset, common in manually managed EndpointSlices for external workloads, was therefore skipped and never selected as a local endpoint. Only skip the endpoint when the resolved condition is explicitly false, and cover the condition permutations in the provider tests. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> * fix(endpoints): reconcile fully on endpoint object deletion Delete only mirrored part of AddOrModify's zero-endpoint handling, so a deleted EndpointSlice left the datapath inconsistent in three ways. In ARP global-leader mode the VIP clusters were left running with no backends, because the cluster stop that AddOrModify performs was missing. When endpoints remained, lastKnownGoodEndpoint was never revisited, so a last known endpoint that lived in the deleted slice stayed stale: egress rules were neither torn down nor moved and the active-endpoint annotations were not refreshed. The EndpointSlice controller can delete a whole slice during consolidation without touching the survivor, so no follow-up event is guaranteed to repair this. In WireGuard mode processInstance never ran, leaving DNAT rules pointing at removed addresses. Extract the shared decisions into shouldProcessInstance and handleNoEndpoints and use them from both paths, and run the same lastKnownGoodEndpoint and annotation reconciliation after a deletion. handleNoEndpoints also guards against a missing instance, which the deletion path can legitimately hit. The getEndpoints error is now wrapped with the provider label like every other error here. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> * docs(bgp): call out the services election behaviour change Enabling leader election in BGP mode now runs a global services leader. Nothing in the configuration changed for existing deployments, but a user who enabled it for the control plane previously got the no-leader path, where every node advertised the service VIP over ECMP, and now gets a single advertising node. Record this in the changelog and warn once on startup when this path is taken, pointing at the settings that restore the previous datapath. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> * refactor(endpoints): deduplicate the control plane endpoint watcher The watch.Deleted case duplicated the Added/Modified body except for the provider mutation, which meant maintaining the log message and the DNAT update in two places. Pick the mutation from the event type and share the rest. Also state the single-object invariant on the Endpoints provider's DeleteObject, so its asymmetry with the slice provider is not mistaken for an oversight. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> * fix(endpoints): only ever consider active endpoints GetLocalEndpoints skipped endpoints whose conditions said they were not serving, but GetAllEndpoints applied no filtering at all. A service using externalTrafficPolicy: Cluster therefore advertised backends that had already been marked as not ready, and the two policies disagreed about which endpoints back the same service. Extract the condition evaluation into isServing and apply it on both paths, and assert in the tests that Cluster and Local agree. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> * refactor(endpoints): reconcile every endpoint event through one path Now that a deletion recomputes the remaining endpoints, AddOrModify and Delete differed only in how the event mutated the provider. Keeping two near-identical bodies is what let their behaviour drift apart in the first place, so fold them into a single Reconcile that dispatches the mutation in applyEvent. Deletions consequently pick up the parts of the add path they were still missing: the IPv6 egress guard, the leader election start, and the endpointless opt-in branch, which now keeps an opted-in Cluster service up after its last EndpointSlice disappears instead of tearing it down. Assisted-by: GitHub-Copilot:unspecified Signed-off-by: Marcel Fest <marcel.fest@telekom.de> --------- Signed-off-by: Marcel Fest <marcel.fest@telekom.de>