mirror of https://github.com/k3s-io/k3s
161 lines
5.8 KiB
Go
161 lines
5.8 KiB
Go
/*
|
|
Copyright 2014 Google Inc. All rights reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// Package app implements a Server object for running the scheduler.
|
|
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"net/http"
|
|
"net/http/pprof"
|
|
"os"
|
|
"strconv"
|
|
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
|
|
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/record"
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
|
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
|
|
_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/algorithmprovider"
|
|
schedulerapi "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api"
|
|
latestschedulerapi "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api/latest"
|
|
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
|
|
|
|
"github.com/golang/glog"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/spf13/pflag"
|
|
)
|
|
|
|
// SchedulerServer has all the context and params needed to run a Scheduler
|
|
type SchedulerServer struct {
|
|
Port int
|
|
Address util.IP
|
|
AlgorithmProvider string
|
|
PolicyConfigFile string
|
|
EnableProfiling bool
|
|
Master string
|
|
Kubeconfig string
|
|
}
|
|
|
|
// NewSchedulerServer creates a new SchedulerServer with default parameters
|
|
func NewSchedulerServer() *SchedulerServer {
|
|
s := SchedulerServer{
|
|
Port: ports.SchedulerPort,
|
|
Address: util.IP(net.ParseIP("127.0.0.1")),
|
|
AlgorithmProvider: factory.DefaultProvider,
|
|
}
|
|
return &s
|
|
}
|
|
|
|
// AddFlags adds flags for a specific SchedulerServer to the specified FlagSet
|
|
func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) {
|
|
fs.IntVar(&s.Port, "port", s.Port, "The port that the scheduler's http service runs on")
|
|
fs.Var(&s.Address, "address", "The IP address to serve on (set to 0.0.0.0 for all interfaces)")
|
|
fs.StringVar(&s.AlgorithmProvider, "algorithm-provider", s.AlgorithmProvider, "The scheduling algorithm provider to use, one of: "+factory.ListAlgorithmProviders())
|
|
fs.StringVar(&s.PolicyConfigFile, "policy-config-file", s.PolicyConfigFile, "File with scheduler policy configuration")
|
|
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
|
|
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")
|
|
fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.")
|
|
}
|
|
|
|
// Run runs the specified SchedulerServer. This should never exit.
|
|
func (s *SchedulerServer) Run(_ []string) error {
|
|
if s.Kubeconfig == "" && s.Master == "" {
|
|
glog.Warningf("Neither --kubeconfig nor --master was specified. Using default API client. This might not work.")
|
|
}
|
|
|
|
// This creates a client, first loading any specified kubeconfig
|
|
// file, and then overriding the Master flag, if non-empty.
|
|
kubeconfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
|
&clientcmd.ClientConfigLoadingRules{ExplicitPath: s.Kubeconfig},
|
|
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: s.Master}}).ClientConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
kubeconfig.QPS = 20.0
|
|
kubeconfig.Burst = 100
|
|
|
|
kubeClient, err := client.New(kubeconfig)
|
|
if err != nil {
|
|
glog.Fatalf("Invalid API configuration: %v", err)
|
|
}
|
|
|
|
go func() {
|
|
mux := http.NewServeMux()
|
|
healthz.InstallHandler(mux)
|
|
if s.EnableProfiling {
|
|
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
|
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
|
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
|
}
|
|
mux.Handle("/metrics", prometheus.Handler())
|
|
|
|
server := &http.Server{
|
|
Addr: net.JoinHostPort(s.Address.String(), strconv.Itoa(s.Port)),
|
|
Handler: mux,
|
|
}
|
|
glog.Fatal(server.ListenAndServe())
|
|
}()
|
|
|
|
configFactory := factory.NewConfigFactory(kubeClient)
|
|
config, err := s.createConfig(configFactory)
|
|
if err != nil {
|
|
glog.Fatalf("Failed to create scheduler configuration: %v", err)
|
|
}
|
|
|
|
eventBroadcaster := record.NewBroadcaster()
|
|
config.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: "scheduler"})
|
|
eventBroadcaster.StartRecordingToSink(kubeClient.Events(""))
|
|
|
|
sched := scheduler.New(config)
|
|
sched.Run()
|
|
|
|
select {}
|
|
}
|
|
|
|
func (s *SchedulerServer) createConfig(configFactory *factory.ConfigFactory) (*scheduler.Config, error) {
|
|
var policy schedulerapi.Policy
|
|
var configData []byte
|
|
|
|
if _, err := os.Stat(s.PolicyConfigFile); err == nil {
|
|
configData, err = ioutil.ReadFile(s.PolicyConfigFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Unable to read policy config: %v", err)
|
|
}
|
|
err = latestschedulerapi.Codec.DecodeInto(configData, &policy)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Invalid configuration: %v", err)
|
|
}
|
|
|
|
return configFactory.CreateFromConfig(policy)
|
|
}
|
|
|
|
// if the config file isn't provided, use the specified (or default) provider
|
|
// check of algorithm provider is registered and fail fast
|
|
_, err := factory.GetAlgorithmProvider(s.AlgorithmProvider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return configFactory.CreateFromProvider(s.AlgorithmProvider)
|
|
}
|