diff --git a/pkg/controller/service/controller.go b/pkg/controller/service/controller.go index ccfce3e72d8..1348596c178 100644 --- a/pkg/controller/service/controller.go +++ b/pkg/controller/service/controller.go @@ -19,11 +19,10 @@ package service import ( "context" "fmt" + "reflect" "sync" "time" - "reflect" - v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" @@ -96,6 +95,7 @@ type serviceCache struct { type Controller struct { cloud cloudprovider.Interface knownHosts []*v1.Node + knownHostsLock sync.Mutex servicesToUpdate []*v1.Service kubeClient clientset.Interface clusterName string @@ -170,6 +170,21 @@ func New( s.serviceLister = serviceInformer.Lister() s.serviceListerSynced = serviceInformer.Informer().HasSynced + nodeInformer.Informer().AddEventHandlerWithResyncPeriod( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(cur interface{}) { + s.nodeSyncLoop() + }, + UpdateFunc: func(old, cur interface{}) { + s.nodeSyncLoop() + }, + DeleteFunc: func(old interface{}) { + s.nodeSyncLoop() + }, + }, + time.Duration(0), + ) + if err := s.init(); err != nil { return nil, err } @@ -637,6 +652,8 @@ func getNodeConditionPredicate() NodeConditionPredicate { // nodeSyncLoop handles updating the hosts pointed to by all load // balancers whenever the set of nodes in the cluster changes. func (s *Controller) nodeSyncLoop() { + s.knownHostsLock.Lock() + defer s.knownHostsLock.Unlock() newHosts, err := listWithPredicate(s.nodeLister, getNodeConditionPredicate()) if err != nil { runtime.HandleError(fmt.Errorf("Failed to retrieve current set of nodes from node lister: %v", err))