Skip to content

Commit 44cac26

Browse files
committed
move start controller pre- and post- checks/actions out of StartControllers
into StartController function the function is reused by ServiceAccountTokenController
1 parent b768967 commit 44cac26

File tree

1 file changed

+71
-62
lines changed

1 file changed

+71
-62
lines changed

cmd/kube-controller-manager/app/controllermanager.go

Lines changed: 71 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -623,20 +623,18 @@ func CreateControllerContext(logger klog.Logger, s *config.CompletedConfig, root
623623
// StartControllers starts a set of controllers with a specified ControllerContext
624624
func StartControllers(ctx context.Context, controllerCtx ControllerContext, controllerDescriptors map[string]*ControllerDescriptor,
625625
unsecuredMux *mux.PathRecorderMux, healthzHandler *controllerhealthz.MutableHealthzHandler) error {
626-
logger := klog.FromContext(ctx)
626+
var controllerChecks []healthz.HealthChecker
627627

628628
// Always start the SA token controller first using a full-power client, since it needs to mint tokens for the rest
629629
// If this fails, just return here and fail since other controllers won't be able to get credentials.
630630
if serviceAccountTokenControllerDescriptor, ok := controllerDescriptors[names.ServiceAccountTokenController]; ok {
631-
controllerName := serviceAccountTokenControllerDescriptor.Name()
632-
if !controllerCtx.IsControllerEnabled(serviceAccountTokenControllerDescriptor) {
633-
logger.Info("Warning: controller is disabled", "controller", controllerName)
634-
} else {
635-
logger.V(1).Info("Starting controller", "controller", controllerName)
636-
initFunc := serviceAccountTokenControllerDescriptor.GetInitFunc()
637-
if _, _, err := initFunc(klog.NewContext(ctx, klog.LoggerWithName(logger, controllerName)), controllerCtx, controllerName); err != nil {
638-
return err
639-
}
631+
check, err := StartController(ctx, controllerCtx, serviceAccountTokenControllerDescriptor, unsecuredMux)
632+
if err != nil {
633+
return err
634+
}
635+
if check != nil {
636+
// HealthChecker should be present when controller has started
637+
controllerChecks = append(controllerChecks, check)
640638
}
641639
}
642640

@@ -646,83 +644,94 @@ func StartControllers(ctx context.Context, controllerCtx ControllerContext, cont
646644
controllerCtx.Cloud.Initialize(controllerCtx.ClientBuilder, ctx.Done())
647645
}
648646

649-
var controllerChecks []healthz.HealthChecker
650-
651647
// Each controller is passed a context where the logger has the name of
652648
// the controller set through WithName. That name then becomes the prefix of
653649
// of all log messages emitted by that controller.
654650
//
655-
// In this loop, an explicit "controller" key is used instead, for two reasons:
651+
// In StartController, an explicit "controller" key is used instead, for two reasons:
656652
// - while contextual logging is alpha, klog.LoggerWithName is still a no-op,
657653
// so we cannot rely on it yet to add the name
658654
// - it allows distinguishing between log entries emitted by the controller
659655
// and those emitted for it - this is a bit debatable and could be revised.
660-
for controllerName, controllerDesc := range controllerDescriptors {
656+
for _, controllerDesc := range controllerDescriptors {
661657
if controllerDesc.RequiresSpecialHandling() {
662658
continue
663659
}
664660

665-
disabledByFeatureGate := false
666-
for _, featureGate := range controllerDesc.GetRequiredFeatureGates() {
667-
if !utilfeature.DefaultFeatureGate.Enabled(featureGate) {
668-
disabledByFeatureGate = true
669-
break
670-
}
661+
check, err := StartController(ctx, controllerCtx, controllerDesc, unsecuredMux)
662+
if err != nil {
663+
return err
671664
}
672-
if disabledByFeatureGate {
673-
logger.Info("Controller is disabled by a feature gate", "controller", controllerName, "requiredFeatureGates", controllerDesc.GetRequiredFeatureGates())
674-
continue
665+
if check != nil {
666+
// HealthChecker should be present when controller has started
667+
controllerChecks = append(controllerChecks, check)
675668
}
669+
}
676670

677-
if controllerDesc.IsCloudProviderController() && controllerCtx.LoopMode != IncludeCloudLoops {
678-
logger.Info("Skipping a cloud provider controller", "controller", controllerName, "loopMode", controllerCtx.LoopMode)
679-
continue
680-
}
671+
healthzHandler.AddHealthChecker(controllerChecks...)
681672

682-
if !controllerCtx.IsControllerEnabled(controllerDesc) {
683-
logger.Info("Warning: controller is disabled", "controller", controllerName)
684-
continue
673+
return nil
674+
}
675+
676+
// StartController starts a controller with a specified ControllerContext
677+
// and performs required pre- and post- checks/actions
678+
func StartController(ctx context.Context, controllerCtx ControllerContext, controllerDescriptor *ControllerDescriptor,
679+
unsecuredMux *mux.PathRecorderMux) (healthz.HealthChecker, error) {
680+
logger := klog.FromContext(ctx)
681+
controllerName := controllerDescriptor.Name()
682+
683+
for _, featureGate := range controllerDescriptor.GetRequiredFeatureGates() {
684+
if !utilfeature.DefaultFeatureGate.Enabled(featureGate) {
685+
logger.Info("Controller is disabled by a feature gate", "controller", controllerName, "requiredFeatureGates", controllerDescriptor.GetRequiredFeatureGates())
686+
return nil, nil
685687
}
688+
}
686689

687-
time.Sleep(wait.Jitter(controllerCtx.ComponentConfig.Generic.ControllerStartInterval.Duration, ControllerStartJitter))
690+
if controllerDescriptor.IsCloudProviderController() && controllerCtx.LoopMode != IncludeCloudLoops {
691+
logger.Info("Skipping a cloud provider controller", "controller", controllerName, "loopMode", controllerCtx.LoopMode)
692+
return nil, nil
693+
}
688694

689-
logger.V(1).Info("Starting controller", "controller", controllerName)
695+
if !controllerCtx.IsControllerEnabled(controllerDescriptor) {
696+
logger.Info("Warning: controller is disabled", "controller", controllerName)
697+
return nil, nil
698+
}
690699

691-
initFunc := controllerDesc.GetInitFunc()
692-
ctrl, started, err := initFunc(klog.NewContext(ctx, klog.LoggerWithName(logger, controllerName)), controllerCtx, controllerName)
693-
if err != nil {
694-
logger.Error(err, "Error starting controller", "controller", controllerName)
695-
return err
696-
}
697-
if !started {
698-
logger.Info("Warning: skipping controller", "controller", controllerName)
699-
continue
700-
}
701-
check := controllerhealthz.NamedPingChecker(controllerName)
702-
if ctrl != nil {
703-
// check if the controller supports and requests a debugHandler
704-
// and it needs the unsecuredMux to mount the handler onto.
705-
if debuggable, ok := ctrl.(controller.Debuggable); ok && unsecuredMux != nil {
706-
if debugHandler := debuggable.DebuggingHandler(); debugHandler != nil {
707-
basePath := "/debug/controllers/" + controllerName
708-
unsecuredMux.UnlistedHandle(basePath, http.StripPrefix(basePath, debugHandler))
709-
unsecuredMux.UnlistedHandlePrefix(basePath+"/", http.StripPrefix(basePath, debugHandler))
710-
}
700+
time.Sleep(wait.Jitter(controllerCtx.ComponentConfig.Generic.ControllerStartInterval.Duration, ControllerStartJitter))
701+
702+
logger.V(1).Info("Starting controller", "controller", controllerName)
703+
704+
initFunc := controllerDescriptor.GetInitFunc()
705+
ctrl, started, err := initFunc(klog.NewContext(ctx, klog.LoggerWithName(logger, controllerName)), controllerCtx, controllerName)
706+
if err != nil {
707+
logger.Error(err, "Error starting controller", "controller", controllerName)
708+
return nil, err
709+
}
710+
if !started {
711+
logger.Info("Warning: skipping controller", "controller", controllerName)
712+
return nil, nil
713+
}
714+
715+
check := controllerhealthz.NamedPingChecker(controllerName)
716+
if ctrl != nil {
717+
// check if the controller supports and requests a debugHandler
718+
// and it needs the unsecuredMux to mount the handler onto.
719+
if debuggable, ok := ctrl.(controller.Debuggable); ok && unsecuredMux != nil {
720+
if debugHandler := debuggable.DebuggingHandler(); debugHandler != nil {
721+
basePath := "/debug/controllers/" + controllerName
722+
unsecuredMux.UnlistedHandle(basePath, http.StripPrefix(basePath, debugHandler))
723+
unsecuredMux.UnlistedHandlePrefix(basePath+"/", http.StripPrefix(basePath, debugHandler))
711724
}
712-
if healthCheckable, ok := ctrl.(controller.HealthCheckable); ok {
713-
if realCheck := healthCheckable.HealthChecker(); realCheck != nil {
714-
check = controllerhealthz.NamedHealthChecker(controllerName, realCheck)
715-
}
725+
}
726+
if healthCheckable, ok := ctrl.(controller.HealthCheckable); ok {
727+
if realCheck := healthCheckable.HealthChecker(); realCheck != nil {
728+
check = controllerhealthz.NamedHealthChecker(controllerName, realCheck)
716729
}
717730
}
718-
controllerChecks = append(controllerChecks, check)
719-
720-
logger.Info("Started controller", "controller", controllerName)
721731
}
722732

723-
healthzHandler.AddHealthChecker(controllerChecks...)
724-
725-
return nil
733+
logger.Info("Started controller", "controller", controllerName)
734+
return check, nil
726735
}
727736

728737
// serviceAccountTokenControllerStarter is special because it must run first to set up permissions for other controllers.

0 commit comments

Comments
 (0)