- apiserver 启动流程
- CreateServerChain创建3个server
- CreateKubeAPIServer创建 kubeAPIServer代表 API核心服务,包括常见的Pod/Deployment/Service
- createAPIExtensionsServer创建 apiExtensionsServer 代表API扩展服务,主要针对CRD
- createAggregatorServer创建aggregatorServer 代表 处理metrics的服务
apiserver 启动流程
入口地址
- 位置 cmd\kube-apiserver\apiserver.go
- 初始化apiserver的cmd并执行
package main
import (
"os"
_ "time/tzdata"
"k8s.io/component-base/cli"
_ "k8s.io/component-base/logs/json/register"
_ "k8s.io/component-base/metrics/prometheus/clientgo"
_ "k8s.io/component-base/metrics/prometheus/version"
"k8s.io/kubernetes/cmd/kube-apiserver/app"
)
func main() {
command := app.NewAPIServerCommand()
code := cli.Run(command)
os.Exit(code)
}
newCmd执行流程
// The *Run functions are executed in the following order:
// * PersistentPreRun()
// * PreRun()
// * Run()
// * PostRun()
// * PersistentPostRun()
// All functions get the same args, the arguments after the command name.
//
PersistentPreRunE 准备
PersistentPreRunE: func(*cobra.Command, []string) error {
rest.SetDefaultWarningHandler(rest.NoWarnings{})
return nil
},
runE解析 准备工作
verflag.PrintAndExitIfRequested()
...
func PrintAndExitIfRequested() {
if *versionFlag == VersionRaw {
fmt.Printf("%#v\n", version.Get())
os.Exit(0)
} else if *versionFlag == VersionTrue {
fmt.Printf("%s %s\n", programName, version.Get())
os.Exit(0)
}
}
fs := cmd.Flags()
cliflag.PrintFlags(fs)
func PrintFlags(flags *pflag.FlagSet) {
flags.VisitAll(func(flag *pflag.Flag) {
klog.V(1).Infof("FLAG: --%s=%q", flag.Name, flag.Value)
})
}
err := checkNonZeroInsecurePort(fs)
func checkNonZeroInsecurePort(fs *pflag.FlagSet) error {
for _, name := range options.InsecurePortFlags {
val, err := fs.GetInt(name)
if err != nil {
return err
}
if val != 0 {
return fmt.Errorf("invalid port value %d: only zero is allowed", val)
}
}
return nil
}
completedOptions, err := Complete(s)
if errs := completedOptions.Validate(); len(errs) != 0 {
return utilerrors.NewAggregate(errs)
}
func (s *ServerRunOptions) Validate() []error {
var errs []error
if s.MasterCount <= 0 {
errs = append(errs, fmt.Errorf("--apiserver-count should be a positive number, but value '%d' provided", s.MasterCount))
}
errs = append(errs, s.Etcd.Validate()...)
errs = append(errs, validateClusterIPFlags(s)...)
errs = append(errs, validateServiceNodePort(s)...)
errs = append(errs, validateAPIPriorityAndFairness(s)...)
errs = append(errs, s.SecureServing.Validate()...)
errs = append(errs, s.Authentication.Validate()...)
errs = append(errs, s.Authorization.Validate()...)
errs = append(errs, s.Audit.Validate()...)
errs = append(errs, s.Admission.Validate()...)
errs = append(errs, s.APIEnablement.Validate(legacyscheme.Scheme, apiextensionsapiserver.Scheme, aggregatorscheme.Scheme)...)
errs = append(errs, validateTokenRequest(s)...)
errs = append(errs, s.Metrics.Validate()...)
errs = append(errs, s.Logs.Validate()...)
errs = append(errs, validateAPIServerIdentity(s)...)
return errs
}
- 举一个例子,比如这个校验etcd的 src\k8s.io\apiserver\pkg\server\options\etcd.go
func (s *EtcdOptions) Validate() []error {
if s == nil {
return nil
}
allErrors := []error{}
if len(s.StorageConfig.Transport.ServerList) == 0 {
allErrors = append(allErrors, fmt.Errorf("--etcd-servers must be specified"))
}
if s.StorageConfig.Type != storagebackend.StorageTypeUnset && !storageTypes.Has(s.StorageConfig.Type) {
allErrors = append(allErrors, fmt.Errorf("--storage-backend invalid, allowed values: %s. If not specified, it will default to 'etcd3'", strings.Join(storageTypes.List(), ", ")))
}
for _, override := range s.EtcdServersOverrides {
tokens := strings.Split(override, "#")
if len(tokens) != 2 {
allErrors = append(allErrors, fmt.Errorf("--etcd-servers-overrides invalid, must be of format: group/resource#servers, where servers are URLs, semicolon separated"))
continue
}
apiresource := strings.Split(tokens[0], "/")
if len(apiresource) != 2 {
allErrors = append(allErrors, fmt.Errorf("--etcd-servers-overrides invalid, must be of format: group/resource#servers, where servers are URLs, semicolon separated"))
continue
}
}
return allErrors
}