// startControllers launches the controllers func startControllers(oc *origin.MasterConfig, kc *kubernetes.MasterConfig) error { if oc.Options.Controllers == configapi.ControllersDisabled { return nil } go func() { oc.ControllerPlugStart() // when a manual shutdown (DELETE /controllers) or lease lost occurs, the process should exit // this ensures no code is still running as a controller, and allows a process manager to reset // the controller to come back into a candidate state and compete for the lease if err := oc.ControllerPlug.WaitForStop(); err != nil { glog.Fatalf("Controller shutdown due to lease being lost: %v", err) } glog.Fatalf("Controller graceful shutdown requested") }() oc.ControllerPlug.WaitForStart() glog.Infof("Controllers starting (%s)", oc.Options.Controllers) // Get configured options (or defaults) for k8s controllers controllerManagerOptions := cmapp.NewCMServer() if kc != nil && kc.ControllerManager != nil { controllerManagerOptions = kc.ControllerManager } // Start these first, because they provide credentials for other controllers' clients oc.RunServiceAccountsController() oc.RunServiceAccountTokensController(controllerManagerOptions) // used by admission controllers oc.RunServiceAccountPullSecretsControllers() oc.RunSecurityAllocationController() if kc != nil { _, _, rcClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraReplicationControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for replication controller: %v", err) } _, _, rsClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraReplicaSetControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for replication controller: %v", err) } _, _, deploymentClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraDeploymentControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for deployment controller: %v", err) } jobConfig, _, jobClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraJobControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for job controller: %v", err) } _, hpaOClient, hpaKClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraHPAControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for HPA controller: %v", err) } _, _, binderClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraPersistentVolumeBinderControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for persistent volume binder controller: %v", err) } _, _, attachDetachControllerClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraPersistentVolumeAttachDetachControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for attach detach controller: %v", err) } _, _, daemonSetClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraDaemonSetControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for daemonset controller: %v", err) } _, _, disruptionClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraDisruptionControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for disruption budget controller: %v", err) } _, _, gcClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraGCControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for pod gc controller: %v", err) } _, _, serviceLoadBalancerClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraServiceLoadBalancerControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for pod gc controller: %v", err) } _, _, petSetClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraPetSetControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for pet set controller: %v", err) } namespaceControllerClientConfig, _, namespaceControllerKubeClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraNamespaceControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for namespace controller: %v", err) } namespaceControllerClientSet := clientadapter.FromUnversionedClient(namespaceControllerKubeClient) namespaceControllerClientPool := dynamic.NewClientPool(namespaceControllerClientConfig, dynamic.LegacyAPIPathResolverFunc) _, _, endpointControllerClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraEndpointControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client for endpoint controller: %v", err) } // no special order kc.RunNodeController() kc.RunScheduler() kc.RunReplicationController(rcClient) kc.RunReplicaSetController(rsClient) kc.RunDeploymentController(deploymentClient) extensionsEnabled := len(configapi.GetEnabledAPIVersionsForGroup(kc.Options, extensions.GroupName)) > 0 batchEnabled := len(configapi.GetEnabledAPIVersionsForGroup(kc.Options, batch.GroupName)) > 0 if extensionsEnabled || batchEnabled { kc.RunJobController(jobClient) } if batchEnabled { kc.RunScheduledJobController(jobConfig) } // TODO: enable this check once the HPA controller can use the autoscaling API if the extensions API is disabled autoscalingEnabled := len(configapi.GetEnabledAPIVersionsForGroup(kc.Options, autoscaling.GroupName)) > 0 if extensionsEnabled || autoscalingEnabled { kc.RunHPAController(hpaOClient, hpaKClient, oc.Options.PolicyConfig.OpenShiftInfrastructureNamespace) } if extensionsEnabled { kc.RunDaemonSetsController(daemonSetClient) } policyEnabled := len(configapi.GetEnabledAPIVersionsForGroup(kc.Options, policy.GroupName)) > 0 if policyEnabled { kc.RunDisruptionBudgetController(disruptionClient) } kc.RunEndpointController(endpointControllerClient) kc.RunNamespaceController(namespaceControllerClientSet, namespaceControllerClientPool) kc.RunPersistentVolumeController(binderClient, oc.Options.PolicyConfig.OpenShiftInfrastructureNamespace, oc.ImageFor("recycler"), bootstrappolicy.InfraPersistentVolumeRecyclerControllerServiceAccountName) kc.RunPersistentVolumeAttachDetachController(attachDetachControllerClient) kc.RunGCController(gcClient) kc.RunServiceLoadBalancerController(serviceLoadBalancerClient) appsEnabled := len(configapi.GetEnabledAPIVersionsForGroup(kc.Options, apps.GroupName)) > 0 if appsEnabled { kc.RunPetSetController(petSetClient) } glog.Infof("Started Kubernetes Controllers") } // no special order if configapi.IsBuildEnabled(&oc.Options) { err := oc.RunBuildController(oc.Informers) if err != nil { glog.Fatalf("Could not start build controller: %v", err) return err } oc.RunBuildPodController() oc.RunBuildConfigChangeController() oc.RunBuildImageChangeTriggerController() } oc.RunDeploymentController() oc.RunDeploymentConfigController() oc.RunDeploymentTriggerController() oc.RunImageImportController() oc.RunOriginNamespaceController() oc.RunSDNController() // initializes quota docs used by admission oc.RunResourceQuotaManager(nil) oc.RunClusterQuotaReconciliationController() oc.RunClusterQuotaMappingController() _, _, serviceServingCertClient, err := oc.GetServiceAccountClients(bootstrappolicy.ServiceServingCertServiceAccountName) if err != nil { glog.Fatalf("Could not get client: %v", err) } oc.RunServiceServingCertController(serviceServingCertClient) oc.RunUnidlingController() _, _, ingressIPClient, err := oc.GetServiceAccountClients(bootstrappolicy.InfraServiceIngressIPControllerServiceAccountName) if err != nil { glog.Fatalf("Could not get client: %v", err) } oc.RunIngressIPController(ingressIPClient) glog.Infof("Started Origin Controllers") return nil }