// StartAPI starts the components of the master that are considered part of the API - the Kubernetes // API and core controllers, the Origin API, the group, policy, project, and authorization caches, // etcd, the asset server (for the UI), the OAuth server endpoints, and the DNS server. // TODO: allow to be more granularly targeted func StartAPI(oc *origin.MasterConfig, kc *kubernetes.MasterConfig) error { // start etcd if oc.Options.EtcdConfig != nil { etcdserver.RunEtcd(oc.Options.EtcdConfig) } // verify we can connect to etcd with the provided config if _, err := etcd.GetAndTestEtcdClient(oc.Options.EtcdClientInfo); err != nil { return err } // Must start policy caching immediately oc.Informers.StartCore(utilwait.NeverStop) oc.RunClusterQuotaMappingController() oc.RunGroupCache() oc.RunProjectCache() unprotectedInstallers := []origin.APIInstaller{} if oc.Options.OAuthConfig != nil { authConfig, err := origin.BuildAuthConfig(oc) if err != nil { return err } unprotectedInstallers = append(unprotectedInstallers, authConfig) } var standaloneAssetConfig *origin.AssetConfig if oc.WebConsoleEnabled() { overrideConfig, err := getResourceOverrideConfig(oc) if err != nil { return err } config, err := origin.NewAssetConfig(*oc.Options.AssetConfig, overrideConfig) if err != nil { return err } if oc.Options.AssetConfig.ServingInfo.BindAddress == oc.Options.ServingInfo.BindAddress { unprotectedInstallers = append(unprotectedInstallers, config) } else { standaloneAssetConfig = config } } if kc != nil { oc.Run([]origin.APIInstaller{kc}, unprotectedInstallers) } else { _, kubeClientConfig, err := configapi.GetKubeClient(oc.Options.MasterClients.ExternalKubernetesKubeConfig, oc.Options.MasterClients.ExternalKubernetesClientConnectionOverrides) if err != nil { return err } proxy := &kubernetes.ProxyConfig{ ClientConfig: kubeClientConfig, } oc.Run([]origin.APIInstaller{proxy}, unprotectedInstallers) } // start up the informers that we're trying to use in the API server oc.Informers.Start(utilwait.NeverStop) oc.InitializeObjects() if standaloneAssetConfig != nil { standaloneAssetConfig.Run() } if oc.Options.DNSConfig != nil { oc.RunDNSServer() } oc.RunProjectAuthorizationCache() return nil }
// 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 }
// StartAPI starts the components of the master that are considered part of the API - the Kubernetes // API and core controllers, the Origin API, the group, policy, project, and authorization caches, // etcd, the asset server (for the UI), the OAuth server endpoints, and the DNS server. // TODO: allow to be more granularly targeted func StartAPI(oc *origin.MasterConfig, kc *kubernetes.MasterConfig) error { // start etcd if oc.Options.EtcdConfig != nil { etcdserver.RunEtcd(oc.Options.EtcdConfig) } // verify we can connect to etcd with the provided config if etcdClient, err := etcd.GetAndTestEtcdClient(oc.Options.EtcdClientInfo); err != nil { return err } else { etcdClient.Close() } // Must start policy caching immediately oc.Informers.StartCore(utilwait.NeverStop) oc.RunClusterQuotaMappingController() oc.RunGroupCache() oc.RunProjectCache() unprotectedInstallers := []origin.APIInstaller{} if oc.Options.OAuthConfig != nil { authConfig, err := origin.BuildAuthConfig(oc) if err != nil { return err } unprotectedInstallers = append(unprotectedInstallers, authConfig) } var standaloneAssetConfig *origin.AssetConfig if oc.WebConsoleEnabled() { var overrideConfig *overrideapi.ClusterResourceOverrideConfig = nil if oc.Options.KubernetesMasterConfig != nil { // external kube gets you a nil pointer here if overridePluginConfigFile, err := pluginconfig.GetPluginConfigFile(oc.Options.KubernetesMasterConfig.AdmissionConfig.PluginConfig, overrideapi.PluginName, ""); err != nil { return err } else if overridePluginConfigFile != "" { configFile, err := os.Open(overridePluginConfigFile) if err != nil { return err } if overrideConfig, err = override.ReadConfig(configFile); err != nil { return err } } } config, err := origin.NewAssetConfig(*oc.Options.AssetConfig, overrideConfig) if err != nil { return err } if oc.Options.AssetConfig.ServingInfo.BindAddress == oc.Options.ServingInfo.BindAddress { unprotectedInstallers = append(unprotectedInstallers, config) } else { standaloneAssetConfig = config } } if kc != nil { oc.Run([]origin.APIInstaller{kc}, unprotectedInstallers) } else { _, kubeClientConfig, err := configapi.GetKubeClient(oc.Options.MasterClients.ExternalKubernetesKubeConfig) if err != nil { return err } proxy := &kubernetes.ProxyConfig{ ClientConfig: kubeClientConfig, } oc.Run([]origin.APIInstaller{proxy}, unprotectedInstallers) } oc.InitializeObjects() if standaloneAssetConfig != nil { standaloneAssetConfig.Run() } if oc.Options.DNSConfig != nil { oc.RunDNSServer() } oc.RunProjectAuthorizationCache() return nil }