diff --git a/pkg/controlplane/controller/defaultservicecidr/default_servicecidr_controller.go b/pkg/controlplane/controller/defaultservicecidr/default_servicecidr_controller.go index 686bf6e061d..831290d5de9 100644 --- a/pkg/controlplane/controller/defaultservicecidr/default_servicecidr_controller.go +++ b/pkg/controlplane/controller/defaultservicecidr/default_servicecidr_controller.go @@ -82,8 +82,6 @@ func NewController( c.eventBroadcaster = broadcaster c.eventRecorder = recorder - c.readyCh = make(chan struct{}) - return c } @@ -99,8 +97,6 @@ type Controller struct { serviceCIDRLister networkingv1alpha1listers.ServiceCIDRLister serviceCIDRsSynced cache.InformerSynced - readyCh chan struct{} // channel to block until the default ServiceCIDR exists - interval time.Duration } @@ -120,28 +116,40 @@ func (c *Controller) Start(stopCh <-chan struct{}) { return } - go wait.Until(c.sync, c.interval, stopCh) + // derive a context from the stopCh so we can cancel the poll loop + ctx := wait.ContextForChannel(stopCh) + // wait until first successfully sync + // this blocks apiserver startup so poll with a short interval + err := wait.PollUntilContextCancel(ctx, 100*time.Millisecond, true, func(ctx context.Context) (bool, error) { + syncErr := c.sync() + return syncErr == nil, nil + }) + if err != nil { + klog.Infof("error initializing the default ServiceCIDR: %v", err) - select { - case <-stopCh: - case <-c.readyCh: } + + // run the sync loop in the background with the defined interval + go wait.Until(func() { + err := c.sync() + if err != nil { + klog.Infof("error trying to sync the default ServiceCIDR: %v", err) + } + }, c.interval, stopCh) } -func (c *Controller) sync() { +func (c *Controller) sync() error { // check if the default ServiceCIDR already exist serviceCIDR, err := c.serviceCIDRLister.Get(DefaultServiceCIDRName) // if exists if err == nil { - c.setReady() c.syncStatus(serviceCIDR) - return + return nil } // unknown error if !apierrors.IsNotFound(err) { - klog.Infof("error trying to obtain the default ServiceCIDR: %v", err) - return + return err } // default ServiceCIDR does not exist @@ -156,21 +164,11 @@ func (c *Controller) sync() { } serviceCIDR, err = c.client.NetworkingV1alpha1().ServiceCIDRs().Create(context.Background(), serviceCIDR, metav1.CreateOptions{}) if err != nil && !apierrors.IsAlreadyExists(err) { - klog.Infof("error creating default ServiceCIDR: %v", err) c.eventRecorder.Eventf(serviceCIDR, v1.EventTypeWarning, "KubernetesDefaultServiceCIDRError", "The default ServiceCIDR can not be created") - return + return err } - - c.setReady() c.syncStatus(serviceCIDR) -} - -func (c *Controller) setReady() { - select { - case <-c.readyCh: - default: - close(c.readyCh) - } + return nil } func (c *Controller) syncStatus(serviceCIDR *networkingapiv1alpha1.ServiceCIDR) { diff --git a/pkg/controlplane/controller/defaultservicecidr/default_servicecidr_controller_test.go b/pkg/controlplane/controller/defaultservicecidr/default_servicecidr_controller_test.go index b0173b0e3f3..cf94a594703 100644 --- a/pkg/controlplane/controller/defaultservicecidr/default_servicecidr_controller_test.go +++ b/pkg/controlplane/controller/defaultservicecidr/default_servicecidr_controller_test.go @@ -56,7 +56,6 @@ func newController(t *testing.T, objects []*networkingapiv1alpha1.ServiceCIDR) ( eventRecorder: record.NewFakeRecorder(100), serviceCIDRLister: serviceCIDRInformer.Lister(), serviceCIDRsSynced: func() bool { return true }, - readyCh: make(chan struct{}), } return client, c