apiserver相当于是k8集群的一个入口,不论通过kubectl还是使用remote api 直接控制,都要经过apiserver。apiserver说白了就是一个server负责监听指定的端口.
main函数的代码位于./kubernetes/cmd/kube-apiserver:
func main() { runtime.GOMAXPROCS(runtime.NumCPU()) rand.Seed(time.Now().UTC().UnixNano()) s := app.NewAPIServer() s.AddFlags(pflag.CommandLine) util.InitFlags() util.InitLogs() defer util.FlushLogs() verflag.PrintAndExitIfRequested() if err := s.Run(pflag.CommandLine.Args()); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } }这一部分主要是进行一些初始化的设置,启动一个apiserver实例,再将其run起来。 主要关注一下,
app.NewAPIServer()
以及
s.AddFlags(pflag.CommandLine)
两个函数,New一个apiserver的时候会放入许多默认的初始化参数:
func NewAPIServer() *APIServer {
s := APIServer{
InsecurePort: 8080,
InsecureBindAddress: util.IP(net.ParseIP("127.0.0.1")),
BindAddress: util.IP(net.ParseIP("0.0.0.0")),
SecurePort: 6443,
APIRate: 10.0,
APIBurst: 200,
APIPrefix: "/api",
EventTTL: 1 * time.Hour,
AuthorizationMode: "AlwaysAllow",
AdmissionControl: "AlwaysAdmit",
EtcdPathPrefix: master.DefaultEtcdPathPrefix,
EnableLogsSupport: true,
MasterServiceNamespace: api.NamespaceDefault,
ClusterName: "kubernetes",
CertDirectory: "/var/run/kubernetes",
RuntimeConfig: make(util.ConfigurationMap),
KubeletConfig: client.KubeletConfig{
Port: ports.KubeletPort,
EnableHttps: true,
HTTPTimeout: time.Duration(5) * time.Second,
},
}
return &s
}
启动时候的全部参数通过 s.AddFlags(pflag.CommandLine)
这个函数传入,里面包括了apiserver启动时候的全部参数,这个使用的是"github.com/spf13/pflag"
这个库,可以具体查看每个相关参数的含义以及初始值。把这些参数的含义弄清,启动的时候把对应的合适的值填进去,作为apiserver的基本使用就基本没问题了。
之后负责启动的操作都是在run函数中执行,前面初始化的具体细节暂不做分析,这里着重关注一下两部分,一个是master实例的生成:
config := &master.Config{
EtcdHelper: helper,
EventTTL: s.EventTTL,
KubeletClient: kubeletClient,
ServiceClusterIPRange: &n,
EnableCoreControllers: true,
EnableLogsSupport: s.EnableLogsSupport,
EnableUISupport: true,
EnableSwaggerSupport: true,
EnableProfiling: s.EnableProfiling,
EnableIndex: true,
APIPrefix: s.APIPrefix,
CorsAllowedOriginList: s.CorsAllowedOriginList,
ReadWritePort: s.SecurePort,
PublicAddress: net.IP(s.AdvertiseAddress),
Authenticator: authenticator,
SupportsBasicAuth: len(s.BasicAuthFile) > 0,
Authorizer: authorizer,
AdmissionControl: admissionController,
EnableV1Beta3: enableV1beta3,
DisableV1: disableV1,
MasterServiceNamespace: s.MasterServiceNamespace,
ClusterName: s.ClusterName,
ExternalHost: s.ExternalHost,
MinRequestTimeout: s.MinRequestTimeout,
SSHUser: s.SSHUser,
SSHKeyfile: s.SSHKeyfile,
InstallSSHKey: installSSH,
ServiceNodePortRange: s.ServiceNodePortRange,
}
m := master.New(config)
这个是主要是生成master实例对象,各种api请求最后都是通过master对象来处理的。
还有一个是server启动的时候:
if secureLocation != "" { secureServer := &http.Server{ Addr: secureLocation, Handler: apiserver.MaxInFlightLimit(sem, longRunningRE, apiserver.RecoverPanics(m.Handler)), ReadTimeout: ReadWriteTimeout, WriteTimeout: ReadWriteTimeout, MaxHeaderBytes: 1 << 20, TLSConfig: &tls.Config{ // Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability) MinVersion: tls.VersionTLS10, }, } if len(s.ClientCAFile) > 0 { clientCAs, err := util.CertPoolFromFile(s.ClientCAFile) if err != nil { glog.Fatalf("unable to load client CA file: %v", err) } // Populate PeerCertificates in requests, but don't reject connections without certificates // This allows certificates to be validated by authenticators, while still allowing other auth types secureServer.TLSConfig.ClientAuth = tls.RequestClientCert // Specify allowed CAs for client certificates secureServer.TLSConfig.ClientCAs = clientCAs } glog.Infof("Serving securely on %s&