diff --git a/pkg/controllers/routing/ecmp_vip.go b/pkg/controllers/routing/ecmp_vip.go index 38c66d008..2f56be338 100644 --- a/pkg/controllers/routing/ecmp_vip.go +++ b/pkg/controllers/routing/ecmp_vip.go @@ -6,6 +6,7 @@ import ( "strconv" "time" + "github.com/cloudnativelabs/kube-router/pkg/utils" "github.com/cloudnativelabs/kube-router/pkg/utils/net-tools" "github.com/golang/glog" "github.com/osrg/gobgp/table" @@ -134,6 +135,8 @@ func (nrc *NetworkRoutingController) OnServiceDelete(obj interface{}) { if len(toWithdraw) > 0 { nrc.withdrawVIPs(toWithdraw) } + + delete(nrc.advertisedExternalIPs, svc.UID) } func (nrc *NetworkRoutingController) newEndpointsEventHandler() cache.ResourceEventHandler { @@ -318,6 +321,10 @@ func (nrc *NetworkRoutingController) getVIPsForService(svc *v1core.Service, only ipList := make([]string, 0) var err error + if _, ok := nrc.advertisedExternalIPs[svc.UID]; !ok { + nrc.advertisedExternalIPs[svc.UID] = make([]string, 0) + } + nodeHasEndpoints := true if onlyActiveEndpoints { _, isLocal := svc.Annotations[svcLocalAnnotation] @@ -336,8 +343,9 @@ func (nrc *NetworkRoutingController) getVIPsForService(svc *v1core.Service, only } } + var extIPs []string if nrc.shouldAdvertiseService(svc, svcAdvertiseExternalAnnotation, nrc.advertiseExternalIP) { - ipList = append(ipList, nrc.getExternalIps(svc)...) + extIPs = nrc.getExternalIps(svc) } // Deprecated: Use service.advertise.loadbalancer=false instead of service.skiplbips. @@ -348,10 +356,23 @@ func (nrc *NetworkRoutingController) getVIPsForService(svc *v1core.Service, only } if !nodeHasEndpoints { - return nil, ipList, nil + extIPs = nrc.advertisedExternalIPs[svc.UID] + nrc.advertisedExternalIPs[svc.UID] = make([]string, 0) + return nil, append(ipList, extIPs...), nil } - return ipList, nil, nil + withdrawIPs := getDiffToWithdraw(nrc.advertisedExternalIPs[svc.UID], extIPs) + nrc.advertisedExternalIPs[svc.UID] = extIPs + return append(ipList, extIPs...), withdrawIPs, nil +} + +func getDiffToWithdraw(old, new []string) (withdrawIPs []string) { + for _, s := range old { + if !utils.CheckForElementInArray(s, new) { + withdrawIPs = append(withdrawIPs, s) + } + } + return } func isEndpointsForLeaderElection(ep *v1core.Endpoints) bool { diff --git a/pkg/controllers/routing/network_routes_controller.go b/pkg/controllers/routing/network_routes_controller.go index 678d22221..9b5bc48cd 100644 --- a/pkg/controllers/routing/network_routes_controller.go +++ b/pkg/controllers/routing/network_routes_controller.go @@ -112,6 +112,7 @@ type NetworkRoutingController struct { pathPrepend bool localAddressList []string overrideNextHop bool + advertisedExternalIPs map[types.UID][]string nodeLister cache.Indexer svcLister cache.Indexer @@ -978,6 +979,8 @@ func NewNetworkRoutingController(clientset kubernetes.Interface, "which its configured: " + err.Error()) } + nrc.advertisedExternalIPs = make(map[types.UID][]string) + bgpLocalAddressListAnnotation, ok := node.ObjectMeta.Annotations[bgpLocalAddressAnnotation] if !ok { glog.Infof("Could not find annotaion `kube-router.io/bgp-local-addresses` on node object so BGP will listen on node IP: %s address.", nrc.nodeIP.String())