Skip to content

Commit 5f41e97

Browse files
committed
wait for kube controllers to be ready before starting informers
1 parent c103229 commit 5f41e97

File tree

4 files changed

+22
-6
lines changed

4 files changed

+22
-6
lines changed

pkg/cmd/server/origin/controller/interfaces.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ type ControllerContext struct {
4343

4444
// Stop is the stop channel
4545
Stop <-chan struct{}
46+
47+
// InformersStarted is closed after all of the controllers have been initialized and are running. After this point it is safe,
48+
// for an individual controller to start the shared informers. Before it is closed, they should not.
49+
InformersStarted chan struct{}
4650
}
4751

4852
// OpenshiftControllerOptions contain the options used to run the controllers. Eventually we need to construct a way to properly

pkg/cmd/server/start/controllers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func newControllerContext(
2828
kubeExternal kclientsetexternal.Interface,
2929
informers *informers,
3030
stopCh <-chan struct{},
31+
informersStarted chan struct{},
3132
) origincontrollers.ControllerContext {
3233

3334
// divide up the QPS since it re-used separately for every client
@@ -60,6 +61,7 @@ func newControllerContext(
6061
SecurityInformers: informers.securityInformers,
6162
TemplateInformers: informers.templateInformers,
6263
Stop: stopCh,
64+
InformersStarted: informersStarted,
6365
}
6466

6567
return openshiftControllerContext

pkg/cmd/server/start/start_kube_controller_manager.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
)
2828

2929
// newKubeControllerContext provides a function which overrides the default and plugs a different set of informers in
30-
func newKubeControllerContext(informers *informers) func(s *controlleroptions.CMServer, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}) (controllerapp.ControllerContext, error) {
30+
func newKubeControllerContext(informers *informers, informersStarted chan struct{}) func(s *controlleroptions.CMServer, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}) (controllerapp.ControllerContext, error) {
3131
oldContextFunc := controllerapp.CreateControllerContext
3232
return func(s *controlleroptions.CMServer, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}) (controllerapp.ControllerContext, error) {
3333
ret, err := oldContextFunc(s, rootClientBuilder, clientBuilder, stop)
@@ -38,6 +38,7 @@ func newKubeControllerContext(informers *informers) func(s *controlleroptions.CM
3838
// Overwrite the informers. Since nothing accessed the existing informers that we're overwriting, they are inert.
3939
// TODO Remove this. It keeps in-process memory utilization down, but we shouldn't do it.
4040
ret.InformerFactory = newGenericInformers(informers)
41+
ret.InformersStarted = informersStarted
4142

4243
return ret, nil
4344
}
@@ -219,10 +220,11 @@ func createRecylerTemplate(recyclerImage string) (string, error) {
219220
}
220221

221222
func runEmbeddedKubeControllerManager(kubeconfigFile, saPrivateKeyFile, saRootCAFile, podEvictionTimeout string, dynamicProvisioningEnabled bool, cmdLineArgs map[string][]string,
222-
recyclerImage string, informers *informers) {
223-
controllerapp.CreateControllerContext = newKubeControllerContext(informers)
223+
recyclerImage string, informers *informers, informersStarted chan struct{}, kubeControllersStarted chan struct{}) {
224+
controllerapp.CreateControllerContext = newKubeControllerContext(informers, informersStarted)
224225
controllerapp.StartInformers = func(stop <-chan struct{}) {
225-
informers.Start(stop)
226+
// We'll start everything out of band, BUT we don't want to start until kube has called this
227+
close(kubeControllersStarted)
226228
}
227229

228230
// TODO we need a real identity for this. Right now it's just using the loopback connection like it used to.

pkg/cmd/server/start/start_master.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,9 @@ func (m *Master) Start() error {
475475
// continuously run the scheduler while we have the primary lease
476476
go runEmbeddedScheduler(m.config.MasterClients.OpenShiftLoopbackKubeConfig, m.config.KubernetesMasterConfig.SchedulerConfigFile, m.config.KubernetesMasterConfig.SchedulerArguments)
477477

478+
informersStarted := make(chan struct{})
479+
kubeControllersStarted := make(chan struct{})
480+
478481
go runEmbeddedKubeControllerManager(
479482
m.config.MasterClients.OpenShiftLoopbackKubeConfig,
480483
m.config.ServiceAccountConfig.PrivateKeyFile,
@@ -483,18 +486,23 @@ func (m *Master) Start() error {
483486
m.config.VolumeConfig.DynamicProvisioningEnabled,
484487
m.config.KubernetesMasterConfig.ControllerArguments,
485488
recyclerImage,
486-
informers)
489+
informers,
490+
informersStarted,
491+
kubeControllersStarted)
487492

488493
openshiftControllerOptions, err := getOpenshiftControllerOptions(m.config.KubernetesMasterConfig.ControllerArguments)
489494
if err != nil {
490495
glog.Fatal(err)
491496
}
492-
controllerContext := newControllerContext(openshiftControllerOptions, privilegedLoopbackConfig, kubeExternal, informers, utilwait.NeverStop)
497+
controllerContext := newControllerContext(openshiftControllerOptions, privilegedLoopbackConfig, kubeExternal, informers, utilwait.NeverStop, informersStarted)
493498
if err := startControllers(*m.config, allocationController, controllerContext); err != nil {
494499
glog.Fatal(err)
495500
}
496501

502+
// don't start any controllers until kube is ready
503+
<-kubeControllersStarted
497504
informers.Start(utilwait.NeverStop)
505+
close(informersStarted)
498506
}()
499507
}
500508

0 commit comments

Comments
 (0)