@@ -58,8 +58,12 @@ type controllerManager struct {
5858 // to scheme.scheme.
5959 scheme * runtime.Scheme
6060
61- // runnables is the set of Controllers that the controllerManager injects deps into and Starts.
62- runnables []Runnable
61+ // leaderElectionRunnables is the set of Controllers that the controllerManager injects deps into and Starts.
62+ // These Runnables are managed by lead election.
63+ leaderElectionRunnables []Runnable
64+ // nonLeaderElectionRunnables is the set of webhook servers that the controllerManager injects deps into and Starts.
65+ // These Runnables will not be blocked by lead election.
66+ nonLeaderElectionRunnables []Runnable
6367
6468 cache cache.Cache
6569
@@ -121,7 +125,7 @@ type controllerManager struct {
121125 retryPeriod time.Duration
122126}
123127
124- // Add sets dependencies on i, and adds it to the list of runnables to start.
128+ // Add sets dependencies on i, and adds it to the list of Runnables to start.
125129func (cm * controllerManager ) Add (r Runnable ) error {
126130 cm .mu .Lock ()
127131 defer cm .mu .Unlock ()
@@ -131,8 +135,13 @@ func (cm *controllerManager) Add(r Runnable) error {
131135 return err
132136 }
133137
134- // Add the runnable to the list
135- cm .runnables = append (cm .runnables , r )
138+ // Add the runnable to the leader election or the non-leaderelection list
139+ if leRunnable , ok := r .(LeaderElectionRunnable ); ok && ! leRunnable .NeedLeaderElection () {
140+ cm .nonLeaderElectionRunnables = append (cm .nonLeaderElectionRunnables , r )
141+ } else {
142+ cm .leaderElectionRunnables = append (cm .leaderElectionRunnables , r )
143+ }
144+
136145 if cm .started {
137146 // If already started, start the controller
138147 go func () {
@@ -254,13 +263,15 @@ func (cm *controllerManager) Start(stop <-chan struct{}) error {
254263 go cm .serveMetrics (cm .internalStop )
255264 }
256265
266+ go cm .startNonLeaderElectionRunnables ()
267+
257268 if cm .resourceLock != nil {
258269 err := cm .startLeaderElection ()
259270 if err != nil {
260271 return err
261272 }
262273 } else {
263- go cm .start ()
274+ go cm .startLeaderElectionRunnables ()
264275 }
265276
266277 select {
@@ -273,7 +284,7 @@ func (cm *controllerManager) Start(stop <-chan struct{}) error {
273284 }
274285}
275286
276- func (cm * controllerManager ) start () {
287+ func (cm * controllerManager ) startNonLeaderElectionRunnables () {
277288 cm .mu .Lock ()
278289 defer cm .mu .Unlock ()
279290
@@ -291,8 +302,26 @@ func (cm *controllerManager) start() {
291302 // TODO(community): Check the return value and write a test
292303 cm .cache .WaitForCacheSync (cm .internalStop )
293304
294- // Start the runnables after the cache has synced
295- for _ , c := range cm .runnables {
305+ // Start the non-leaderelection Runnables after the cache has synced
306+ for _ , c := range cm .nonLeaderElectionRunnables {
307+ // Controllers block, but we want to return an error if any have an error starting.
308+ // Write any Start errors to a channel so we can return them
309+ ctrl := c
310+ go func () {
311+ cm .errChan <- ctrl .Start (cm .internalStop )
312+ }()
313+ }
314+
315+ cm .started = true
316+ }
317+
318+ func (cm * controllerManager ) startLeaderElectionRunnables () {
319+ // Wait for the caches to sync.
320+ // TODO(community): Check the return value and write a test
321+ cm .cache .WaitForCacheSync (cm .internalStop )
322+
323+ // Start the leader election Runnables after the cache has synced
324+ for _ , c := range cm .leaderElectionRunnables {
296325 // Controllers block, but we want to return an error if any have an error starting.
297326 // Write any Start errors to a channel so we can return them
298327 ctrl := c
@@ -312,7 +341,7 @@ func (cm *controllerManager) startLeaderElection() (err error) {
312341 RetryPeriod : cm .retryPeriod ,
313342 Callbacks : leaderelection.LeaderCallbacks {
314343 OnStartedLeading : func (_ context.Context ) {
315- cm .start ()
344+ cm .startLeaderElectionRunnables ()
316345 },
317346 OnStoppedLeading : func () {
318347 // Most implementations of leader election log.Fatal() here.
0 commit comments