Kube-scheduler Component Source Reading notes
Before I start, let's talk about the way I read the project source code for the Go language. Reading other people's frame code is often a painful thing to read, especially the go (because of the way the interface is implemented, and so on). This is how I read, first find the relevant components of the Main method, and then go down one layer of the rationale, and finally do the general idea of finishing.
Next we enter the Kube-scheduler source interpretation (Kubernetes version 1.3.6):
entrance:
K8s.io/kubernetes/plugin/cmd/kube-scheduler/schduler.go:
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)
}
first of all:
S: = options. Newschedulerserver () Creates a new scheduler server that invokes the K8s.io/kubernetes/plugin/cmd/kube-scheduler/options/options.go in the
func newschedulerserver () *schedulerserver {
config: = componentconfig. kubeschedulerconfiguration{}
API. Scheme.convert (&V1ALPHA1. kubeschedulerconfiguration{}, &config)
s: = schedulerserver{
kubeschedulerconfiguration:config,
} return
&s
}
In this method, an empty kubeschedulerconfiguration structure is constructed, and then a schedulerserver is constructed through the structure:
Type schedulerserver struct {
componentconfig. Kubeschedulerconfiguration//Master is the ' address ' of the
kubernetes API server (Overrides any
//value in Kubec Onfig).
Master string
//Kubeconfig is Path to kubeconfig file with authorization and master
//Location Information.
kubeconfig string
}
Schedulerserver contains the boot configuration required to start up, connect master URL information, and a kubeconfig configuration file url,kubeconfig The file in this URL contains some information about the master connection authentication.
Kubeschedulerconfiguration This structural weight defines some of the startup configuration parameters for Kube-scheduler:
Type kubeschedulerconfiguration struct {unversioned.
Typemeta//port is the port of that scheduler ' s HTTP service runs on.
Port int ' JSON: ' Port '//address is the IP addresses to serve on.
Address string ' JSON: ' Address '//Algorithmprovider are the scheduling algorithm provider to use. Algorithmprovider string ' JSON: ' Algorithmprovider '//Policyconfigfile is the filepath to the Scheduler Config
Uration.
Policyconfigfile string ' JSON: ' policyconfigfile '//enableprofiling enables profiling via web interface.
Enableprofiling *bool ' json: ' enableprofiling '//ContentType is contentType of requests to sent.
ContentType string ' JSON: ' ContentType '//KUBEAPIQPS is the QPS to use while talking with Kubernetes Apiserver. KUBEAPIQPS float32 ' json: ' KUBEAPIQPS '//Kubeapiburst is the QPS burst to use while talking with Kubernetes Apiserver
. Kubeapiburst int ' JSON: "Kubeapiburst" '//Schedulername is name Of the scheduler, used to select which pods/would be processed from this scheduler, based on pod ' s annotation with
Key ' Scheduler.alpha.kubernetes.io/name '. Schedulername string ' JSON: ' schedulername '//requiredduringscheduling affinity is not symmetric, but there-is-an imp
Licit preferredduringscheduling affinity rule//corresponding to every requiredduringscheduling rule. Hardpodaffinitysymmetricweight represents the weight of implicit preferredduringscheduling affinity rule, in the range 0-100. Hardpodaffinitysymmetricweight int ' json: ' hardpodaffinitysymmetricweight '//indicate ' all topologies '
Set for empty Topologykey when it's used for preferredduringscheduling pod anti-affinity.
Failuredomains string ' JSON: ' failuredomains '//leaderelection defines the configuration of leader election client. Leaderelection leaderelectionconfiguration ' JSON: Leaderelection '}
This includes information such as IP and port of the Scheduler service
And then:
App. Run (s) calls the Run method in K8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go:/Run runs the specified schedulerserver.
This should never exit. Func Run (S *options. Schedulerserver) Error {if c, err: = Configz. New ("Componentconfig"); Err = = Nil {c.set (s.kubeschedulerconfiguration)} else {Glog. Errorf ("Unable to register Configz:%s", err)} kubeconfig, err: = Clientcmd. Buildconfigfromflags (S.master, s.kubeconfig) If Err!= nil {return err} kubeconfig. ContentType = s.contenttype//Override kubeconfig Qps/burst settings from Flags Kubeconfig. QPS = S.kubeapiqps Kubeconfig. Burst = Int (s.kubeapiburst) 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)} configz. Installhandler (MUX) mux. Handle ("/metrics", Prometheus. Handler ()) Server: = &http. server{addr:net. Joinhostport (S.address, StrConv. itoa (int (s.port))), Handler:mux, Glog. Fatal (server. Listenandserve ())} () Configfactory: = Factory. Newconfigfactory (Kubeclient, S.schedulername, s.hardpodaffinitysymmetricweight, s.failuredomains) config, err: = Crea Teconfig (S, configfactory) if Err!= nil {glog. Fatalf ("Failed to create Scheduler configuration:%v", Err)} eventbroadcaster: = record. Newbroadcaster () config. Recorder = Eventbroadcaster.newrecorder (API. Eventsource{component:s.schedulername}) eventbroadcaster.startlogging (Glog. INFOF) Eventbroadcaster.startrecordingtosink (Kubeclient.events ("")) Sched: = scheduler. New (config) run: = Func(_ <-chan struct{}) {Sched. Run () Select {}} if!s.leaderelection.leaderelect {run (nil) glog. Fatal ("This statement is unreachable") Panic ("unreachable")} ID, err: = OS. Hostname () If Err!= nil {return err} leaderelection. Runordie (leaderelection. leaderelectionconfig{Endpointsmeta:api. objectmeta{Namespace: "Kube-system", Name: "Kube-scheduler",}, Client: Kubeclient, Identity:id, Eventrecorder:config. Recorder, leaseduration:s.leaderelection.leaseduration.duration, Renewdeadline:s.leaderelection.renewdea Dline. Duration, Retryperiod:s.leaderelection.retryperiod.duration, Callbacks:leaderelection. leadercallbacks{Onstartedleading:run, Onstoppedleading:func () {glog. Fatalf ("Lost Master")},},}) Glog. Fatal ("This StAtement is unreachable ") Panic (" unreachable ")}
Here we mainly analyze this run method:
First Look:
If C, err: = Configz. New ("Componentconfig"); Err = = Nil {
c.set (s.kubeschedulerconfiguration)
} else {
glog. Errorf ("Unable to register Configz:%s", err)
}
This code is to register the s.kubeschedulerconfiguration in the K8s.io\kubernetes\pkg\util\configz\configz.go
Type Config struct {
val interface{}
}
Then:
Kubeconfig, err: = Clientcmd. Buildconfigfromflags (S.master, s.kubeconfig)
If err!= nil {return
err
}
Generate Restclient from this code. Config structure body, where the parameter is mainly the URL of master and the file specified by kubeconfig this path
Restclient. Config this structure in file: K8s.io\kubernetes\pkg\client\restclient\config.go, its main function is to connect scheduler connection master configuration information:
Type Config struct {//host must is a host string, a Host:port pair, or a URL to the base of the apiserver. If a URL is given then the (optional) Path of this URL represents a prefix that must//being appended to all request URIs used to access the apiserver.
This is allows a frontend//proxy to easily relocate all of the apiserver endpoints.
Host string//Apipath is a sub-path the points to a API root. Apipath string//Prefix is the sub path of the server. If not specified, the client would set//a default value. Use '/' to indicate the server root should is used Prefix string//Contentconfig contains settings that affect h
ow objects are transformed when//sent to the server. Contentconfig//server requires Basic authentication Username string Password string//server requires Bearer authentication.
This client won't attempt to use//refresh tokens for a OAuth2 flow. Todo:demonstrate an OAUTH2 compatible client. Bearertoken string//Impersonate is the username, this restclient would impersonate impersonate string/
/Server requires plugin-specified authentication. Authprovider *clientcmdapi.
Authproviderconfig//Callback to persist config for Authprovider. Authconfigpersister authproviderconfigpersister//Tlsclientconfig contains settings to enable Transport layer Ty Tlsclientconfig//Server should be accessed without verifying the TLS//certificate.
For testing.
insecure bool//useragent is a optional field that specifies the caller of this request. UserAgent string//transport may is used for custom HTTP behavior. This attribute may is not//is specified with the TLS client certificate options.
Use Wraptransport//For most client level operations. Transport HTTP. Roundtripper//Wraptransport'll be invoked for custom HTTP behavior after the underlying//TranspoThe RT is initialized (either the transport created from tlsclientconfig,//transport, or HTTP. Defaulttransport).
The config may layer other roundtrippers//in top of the returned roundtripper. Wraptransport func (Rt http. Roundtripper) http. Roundtripper//QPS indicates the maximum QPS to the master from this client.
If Zero, QPS is unlimited. QPS float32//Maximum burst for throttle burst int//Rate limiter for limiting connections to the master F Rom this client. If present overwrites Qps/burst Ratelimiter FlowControl. Ratelimiter}
This includes a lot of connection information, such as Master URL, certified Username,password, and so on.
The configuration information for the connection Mster is there, so the next step is to connect master and get the client:
Kubeclient, Err: = client. New (kubeconfig)
If err!= nil {
glog. Fatalf ("Invalid API configuration:%v", err)
}
after:
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)
}
Configz. Installhandler (MUX)
mux. Handle ("/metrics", Prometheus. Handler ())
server: = &http. server{
Addr: net. Joinhostport (S.address, StrConv. itoa (int (s.port))),
Handler:mux,
glog. Fatal (server. Listenandserve ())
} ()
Now I'm going to focus on this goroutine. In general, the code is a number of routes (HTTP routes) that are registered for initialization, including health checks (scheduler health checks), and so on.
1 Create a new router:
MUX: = http. Newservemux ()
2 Registration of the Health Check route (processing method), its URL is master Url/healthz
Healthz. Installhandler (MUX)
3 to determine whether the API interface can be invoked via the Web: host:port/debug/pprof/, allowing invocation, then setting the associated route:
If s.enableprofiling {
mux. Handlefunc ("/debug/pprof/", Pprof. Index)
Mux. Handlefunc ("/debug/pprof/profile", Pprof. Profile)
Mux. Handlefunc ("/debug/pprof/symbol", Pprof. Symbol)
}
4 Registering the/configz route:
Configz. Installhandler (MUX)
The Installhandler method is defined as follows:
Func Installhan