From bd5ee4f7082512b89a5dc220a3b5e7c2e88afa0c Mon Sep 17 00:00:00 2001 From: "Alexander \"Ananace\" Olofsson" Date: Thu, 22 Apr 2021 00:25:16 +0200 Subject: [PATCH] fix(nsc): Overly eager IPVS updating * fix(nsc): Overly eager IPVS updating Switches the endpoint map comparison in OnEndpointsUpdate from being a DeepEqual, to instead checking that all services exist, and that their associated endpoints are similar. Ordering is no longer considered important in regards to the IPVS update check. Fixes #1026 --- .../proxy/network_services_controller.go | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/pkg/controllers/proxy/network_services_controller.go b/pkg/controllers/proxy/network_services_controller.go index 6b9aa596..3157446e 100644 --- a/pkg/controllers/proxy/network_services_controller.go +++ b/pkg/controllers/proxy/network_services_controller.go @@ -813,6 +813,48 @@ func (nsc *NetworkServicesController) publishMetrics(serviceInfoMap serviceInfoM return nil } +// TODO Move to utils +func unsortedListsEquivalent(a, b []endpointsInfo) bool { + if len(a) != len(b) { + return false + } + + values := make(map[interface{}]int) + for _, val := range a { + values[val] = 1 + } + for _, val := range b { + values[val] = values[val] + 1 + } + + for _, val := range values { + if val == 1 { + return false + } + } + + return true +} + +func endpointsMapsEquivalent(a, b endpointsInfoMap) bool { + if len(a) != len(b) { + return false + } + + for key, valA := range a { + valB, ok := b[key] + if !ok { + return false + } + + if !unsortedListsEquivalent(valA, valB) { + return false + } + } + + return true +} + // OnEndpointsUpdate handle change in endpoints update from the API server func (nsc *NetworkServicesController) OnEndpointsUpdate(ep *api.Endpoints) { @@ -850,7 +892,7 @@ func (nsc *NetworkServicesController) OnEndpointsUpdate(ep *api.Endpoints) { newServiceMap := nsc.buildServicesInfo() newEndpointsMap := nsc.buildEndpointsInfo() - if len(newEndpointsMap) != len(nsc.endpointsMap) || !reflect.DeepEqual(newEndpointsMap, nsc.endpointsMap) { + if !endpointsMapsEquivalent(newEndpointsMap, nsc.endpointsMap) { nsc.endpointsMap = newEndpointsMap nsc.serviceMap = newServiceMap klog.V(1).Infof("Syncing IPVS services sync for update to endpoint: %s/%s", ep.Namespace, ep.Name)