// NewSchedulerCommand provides a CLI handler for the 'scheduler' command func NewSchedulerCommand(name, fullName string, out io.Writer) *cobra.Command { schedulerOptions := scheduleroptions.NewSchedulerServer() cmd := &cobra.Command{ Use: name, Short: "Launch Kubernetes scheduler (kube-scheduler)", Long: controllersLong, Run: func(c *cobra.Command, args []string) { startProfiler() logs.InitLogs() defer logs.FlushLogs() if err := schedulerapp.Run(schedulerOptions); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } }, } cmd.SetOutput(out) flags := cmd.Flags() flags.SetNormalizeFunc(kflag.WordSepNormalizeFunc) schedulerOptions.AddFlags(flags) return cmd }
func main() { s := options.NewSchedulerServer() s.AddFlags(pflag.CommandLine) flag.InitFlags() logs.InitLogs() defer logs.FlushLogs() verflag.PrintAndExitIfRequested() app.Run(s) }
func main() { runtime.GOMAXPROCS(runtime.NumCPU()) s := options.NewSchedulerServer() s.AddFlags(pflag.CommandLine) flag.InitFlags() util.InitLogs() defer util.FlushLogs() verflag.PrintAndExitIfRequested() app.Run(s) }
// NewScheduler creates a new hyperkube Server object that includes the // description and flags. func NewScheduler() *Server { s := options.NewSchedulerServer() hks := Server{ SimpleUsage: "scheduler", Long: "Implements a Kubernetes scheduler. This will assign pods to kubelets based on capacity and constraints.", Run: func(_ *Server, _ []string) error { return app.Run(s) }, } s.AddFlags(hks.Flags()) return &hks }
func StartSchedulerServer(lk LocalkubeServer) func() error { config := options.NewSchedulerServer() // master details config.Master = lk.GetAPIServerInsecureURL() // defaults from command config.EnableProfiling = true return func() error { return scheduler.Run(config) } }
func main() { s := options.NewSchedulerServer() s.AddFlags(pflag.CommandLine) flag.InitFlags() logs.InitLogs() defer logs.FlushLogs() verflag.PrintAndExitIfRequested() if err := app.Run(s); err != nil { glog.Fatalf("scheduler app failed to run: %v", err) } }
// NewSchedulerCommand creates a *cobra.Command object with default parameters func NewSchedulerCommand() *cobra.Command { s := options.NewSchedulerServer() s.AddFlags(pflag.CommandLine) cmd := &cobra.Command{ Use: "kube-scheduler", Long: `The Kubernetes scheduler is a policy-rich, topology-aware, workload-specific function that significantly impacts availability, performance, and capacity. The scheduler needs to take into account individual and collective resource requirements, quality of service requirements, hardware/software/policy constraints, affinity and anti-affinity specifications, data locality, inter-workload interference, deadlines, and so on. Workload-specific requirements will be exposed through the API as necessary.`, Run: func(cmd *cobra.Command, args []string) { }, } return cmd }
func NewBootkube(config Config) (*bootkube, error) { apiServer := apiserver.NewAPIServer() fs := pflag.NewFlagSet("apiserver", pflag.ExitOnError) apiServer.AddFlags(fs) fs.Parse([]string{ "--bind-address=0.0.0.0", "--secure-port=443", "--insecure-port=8081", // NOTE: temp hack for single-apiserver "--allow-privileged=true", "--tls-private-key-file=" + filepath.Join(config.AssetDir, asset.AssetPathAPIServerKey), "--tls-cert-file=" + filepath.Join(config.AssetDir, asset.AssetPathAPIServerCert), "--client-ca-file=" + filepath.Join(config.AssetDir, asset.AssetPathCACert), "--etcd-servers=" + config.EtcdServer.String(), "--service-cluster-ip-range=10.3.0.0/24", "--service-account-key-file=" + filepath.Join(config.AssetDir, asset.AssetPathServiceAccountPubKey), "--admission-control=ServiceAccount", "--runtime-config=extensions/v1beta1/deployments=true,extensions/v1beta1/daemonsets=true", }) cmServer := controller.NewCMServer() fs = pflag.NewFlagSet("controllermanager", pflag.ExitOnError) cmServer.AddFlags(fs) fs.Parse([]string{ "--master=" + insecureAPIAddr, "--service-account-private-key-file=" + filepath.Join(config.AssetDir, asset.AssetPathServiceAccountPrivKey), "--root-ca-file=" + filepath.Join(config.AssetDir, asset.AssetPathCACert), "--leader-elect=true", }) schedServer := scheduler.NewSchedulerServer() fs = pflag.NewFlagSet("scheduler", pflag.ExitOnError) schedServer.AddFlags(fs) fs.Parse([]string{ "--master=" + insecureAPIAddr, "--leader-elect=true", }) return &bootkube{ apiServer: apiServer, controller: cmServer, scheduler: schedServer, assetDir: config.AssetDir, }, nil }
func TestSchedulerServerDefaults(t *testing.T) { defaults := scheduleroptions.NewSchedulerServer() // This is a snapshot of the default config // If the default changes (new fields are added, or default values change), we want to know // Once we've reacted to the changes appropriately in BuildKubernetesMasterConfig(), update this expected default to match the new upstream defaults expectedDefaults := &scheduleroptions.SchedulerServer{ KubeSchedulerConfiguration: componentconfig.KubeSchedulerConfiguration{ Port: 10251, // disabled Address: "0.0.0.0", AlgorithmProvider: "DefaultProvider", ContentType: "application/vnd.kubernetes.protobuf", KubeAPIQPS: 50, KubeAPIBurst: 100, SchedulerName: "default-scheduler", HardPodAffinitySymmetricWeight: 1, FailureDomains: "kubernetes.io/hostname,failure-domain.beta.kubernetes.io/zone,failure-domain.beta.kubernetes.io/region", LeaderElection: componentconfig.LeaderElectionConfiguration{ LeaderElect: true, LeaseDuration: unversioned.Duration{ Duration: 15 * time.Second, }, RenewDeadline: unversioned.Duration{ Duration: 10 * time.Second, }, RetryPeriod: unversioned.Duration{ Duration: 2 * time.Second, }, }, }, } if !reflect.DeepEqual(defaults, expectedDefaults) { t.Logf("expected defaults, actual defaults: \n%s", diff.ObjectReflectDiff(expectedDefaults, defaults)) t.Errorf("Got different defaults than expected, adjust in BuildKubernetesMasterConfig and update expectedDefaults") } }
func BuildKubernetesMasterConfig(options configapi.MasterConfig, requestContextMapper kapi.RequestContextMapper, kubeClient *kclient.Client, informers shared.InformerFactory, admissionControl admission.Interface, originAuthenticator authenticator.Request) (*MasterConfig, error) { if options.KubernetesMasterConfig == nil { return nil, errors.New("insufficient information to build KubernetesMasterConfig") } kubeletClientConfig := configapi.GetKubeletClientConfig(options) kubeletClient, err := kubeletclient.NewStaticKubeletClient(kubeletClientConfig) if err != nil { return nil, fmt.Errorf("unable to configure Kubelet client: %v", err) } // in-order list of plug-ins that should intercept admission decisions // TODO: Push node environment support to upstream in future podEvictionTimeout, err := time.ParseDuration(options.KubernetesMasterConfig.PodEvictionTimeout) if err != nil { return nil, fmt.Errorf("unable to parse PodEvictionTimeout: %v", err) } // Defaults are tested in TestCMServerDefaults cmserver := cmapp.NewCMServer() // Adjust defaults cmserver.Address = "" // no healthz endpoint cmserver.Port = 0 // no healthz endpoint cmserver.EnableGarbageCollector = false // disabled until we add the controller cmserver.PodEvictionTimeout = unversioned.Duration{Duration: podEvictionTimeout} cmserver.VolumeConfiguration.EnableDynamicProvisioning = options.VolumeConfig.DynamicProvisioningEnabled // resolve extended arguments // TODO: this should be done in config validation (along with the above) so we can provide // proper errors if err := cmdflags.Resolve(options.KubernetesMasterConfig.ControllerArguments, cmserver.AddFlags); len(err) > 0 { return nil, kerrors.NewAggregate(err) } // resolve extended arguments // TODO: this should be done in config validation (along with the above) so we can provide // proper errors schedulerserver := scheduleroptions.NewSchedulerServer() schedulerserver.PolicyConfigFile = options.KubernetesMasterConfig.SchedulerConfigFile if err := cmdflags.Resolve(options.KubernetesMasterConfig.SchedulerArguments, schedulerserver.AddFlags); len(err) > 0 { return nil, kerrors.NewAggregate(err) } cloud, err := cloudprovider.InitCloudProvider(cmserver.CloudProvider, cmserver.CloudConfigFile) if err != nil { return nil, err } if cloud != nil { glog.V(2).Infof("Successfully initialized cloud provider: %q from the config file: %q\n", cmserver.CloudProvider, cmserver.CloudConfigFile) } var proxyClientCerts []tls.Certificate if len(options.KubernetesMasterConfig.ProxyClientInfo.CertFile) > 0 { clientCert, err := tls.LoadX509KeyPair( options.KubernetesMasterConfig.ProxyClientInfo.CertFile, options.KubernetesMasterConfig.ProxyClientInfo.KeyFile, ) if err != nil { return nil, err } proxyClientCerts = append(proxyClientCerts, clientCert) } server, storageFactory, err := BuildDefaultAPIServer(options) if err != nil { return nil, err } // Preserve previous behavior of using the first non-loopback address // TODO: Deprecate this behavior and just require a valid value to be passed in publicAddress := net.ParseIP(options.KubernetesMasterConfig.MasterIP) if publicAddress == nil || publicAddress.IsUnspecified() || publicAddress.IsLoopback() { hostIP, err := knet.ChooseHostInterface() if err != nil { glog.Fatalf("Unable to find suitable network address.error='%v'. Set the masterIP directly to avoid this error.", err) } publicAddress = hostIP glog.Infof("Will report %v as public IP address.", publicAddress) } m := &master.Config{ Config: &genericapiserver.Config{ PublicAddress: publicAddress, ReadWritePort: server.SecurePort, Authenticator: originAuthenticator, // this is used to fulfill the tokenreviews endpoint which is used by node authentication Authorizer: authorizer.NewAlwaysAllowAuthorizer(), AdmissionControl: admissionControl, StorageFactory: storageFactory, ServiceClusterIPRange: (*net.IPNet)(&server.ServiceClusterIPRange), ServiceNodePortRange: server.ServiceNodePortRange, RequestContextMapper: requestContextMapper, APIResourceConfigSource: getAPIResourceConfig(options), APIPrefix: server.APIPrefix, APIGroupPrefix: server.APIGroupPrefix, MasterCount: server.MasterCount, // Set the TLS options for proxying to pods and services // Proxying to nodes uses the kubeletClient TLS config (so can provide a different cert, and verify the node hostname) ProxyTLSClientConfig: &tls.Config{ // Proxying to pods and services cannot verify hostnames, since they are contacted on randomly allocated IPs InsecureSkipVerify: true, Certificates: proxyClientCerts, }, Serializer: kapi.Codecs, EnableLogsSupport: server.EnableLogsSupport, EnableProfiling: server.EnableProfiling, EnableWatchCache: server.EnableWatchCache, MasterServiceNamespace: server.MasterServiceNamespace, ExternalHost: server.ExternalHost, MinRequestTimeout: server.MinRequestTimeout, KubernetesServiceNodePort: server.KubernetesServiceNodePort, }, EventTTL: server.EventTTL, KubeletClient: kubeletClient, EnableCoreControllers: true, DeleteCollectionWorkers: server.DeleteCollectionWorkers, } if server.EnableWatchCache { cachesize.SetWatchCacheSizes(server.WatchCacheSizes) } if options.DNSConfig != nil { _, dnsPortStr, err := net.SplitHostPort(options.DNSConfig.BindAddress) if err != nil { return nil, fmt.Errorf("unable to parse DNS bind address %s: %v", options.DNSConfig.BindAddress, err) } dnsPort, err := strconv.Atoi(dnsPortStr) if err != nil { return nil, fmt.Errorf("invalid DNS port: %v", err) } m.ExtraServicePorts = append(m.ExtraServicePorts, kapi.ServicePort{Name: "dns", Port: 53, Protocol: kapi.ProtocolUDP, TargetPort: intstr.FromInt(dnsPort)}, kapi.ServicePort{Name: "dns-tcp", Port: 53, Protocol: kapi.ProtocolTCP, TargetPort: intstr.FromInt(dnsPort)}, ) m.ExtraEndpointPorts = append(m.ExtraEndpointPorts, kapi.EndpointPort{Name: "dns", Port: int32(dnsPort), Protocol: kapi.ProtocolUDP}, kapi.EndpointPort{Name: "dns-tcp", Port: int32(dnsPort), Protocol: kapi.ProtocolTCP}, ) } kmaster := &MasterConfig{ Options: *options.KubernetesMasterConfig, KubeClient: kubeClient, Master: m, ControllerManager: cmserver, CloudProvider: cloud, SchedulerServer: schedulerserver, Informers: informers, } return kmaster, nil }