还是传统的套路在cmd包下面kubelet.go文件启动kubelet,首先是解析参数启动server
func main() {
//创建kubelet服务
s := options.NewKubeletServer()
//添加参数如“max-pods(节点上最大pod数目)”
s.AddFlags(pflag.CommandLine)
//初始化参数
flag.InitFlags()
util.InitLogs()
defer util.FlushLogs()
verflag.PrintAndExitIfRequested()
//启动app
if err := app.Run(s, nil); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}
根据KubeletConfig启动kubelet,在run方法里面,创建client
kcfg = cfg
//创建一个调用apiserver的client配置
clientConfig, err := CreateAPIServerClientConfig(s)
if err == nil {
//创建client
kcfg.KubeClient, err = clientset.NewForConfig(clientConfig)
//创建一个events 的 client
eventClientConfig := *clientConfig
eventClientConfig.QPS = float32(s.EventRecordQPS)
eventClientConfig.Burst = int(s.EventBurst)
kcfg.EventClient, err = clientset.NewForConfig(&eventClientConfig)
}
if err != nil && len(s.APIServerList) > 0 {
glog.Warningf("No API client: %v", err)
}
下面是创建client 配置的
func CreateAPIServerClientConfig(s *options.KubeletServer) (*restclient.Config, error) {
if len(s.APIServerList) < 1 {
//没有传入一个apiserver报错下面
return nil, fmt.Errorf("no api servers specified")
}
// HA功能可以是多个apiserver但这部分代码还没有完善,只选择第一个
if len(s.APIServerList) > 1 {
glog.Infof("Multiple api servers specified. Picking first one")
}
clientConfig, err := createClientConfig(s)
if err != nil {
return nil, err
}
clientConfig.ContentType = s.ContentType
// Override kubeconfig qps/burst settings from flags
clientConfig.QPS = float32(s.KubeAPIQPS)
clientConfig.Burst = int(s.KubeAPIBurst)
addChaosToClientConfig(s, clientConfig)
return clientConfig, nil
}
从配置创建client通过NewForConfig方法
//创建核心client
clientset.CoreClient, err = unversionedcore.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
//创建认证client
clientset.AuthenticationClient, err = unversionedauthentication.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
//创建授权client
clientset.AuthorizationClient, err = unversionedauthorization.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
//创建自动扩缩容的client
clientset.AutoscalingClient, err = unversionedautoscaling.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
//创建批量操作的api
clientset.BatchClient, err = unversionedbatch.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
上面的代码创建各种客户端,每种客户端本质就是api rest请求的客户端,如下创建一个restclient
func NewForConfig(c *restclient.Config) (*CoreClient, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &CoreClient{client}, nil
}
创建完apiserver请求client以后创建CloudProvider是为了对接openstack或者aws请求他们的api
下面的代码很重要,创建ContainerManager,这个是管理容器
kcfg.ContainerManager, err = cm.NewContainerManager(kcfg.Mounter, kcfg.CAdvisorInterface, cm.NodeConfig{
RuntimeCgroupsName: kcfg.RuntimeCgroups,
SystemCgroupsName: kcfg.SystemCgroups,
KubeletCgroupsName: kcfg.KubeletCgroups,
ContainerRuntime: kcfg.ContainerRuntime,
CgroupsPerQOS: kcfg.CgroupsPerQOS,
CgroupRoot: kcfg.CgroupRoot,
})
等这些都创建完成就可以启动了
if err := RunKubelet(kcfg); err != nil {
return err
}
在RunKubelet方法里面会通知apiserver有新节点启动,并且启动kubelet的server,监听端口
func startKubelet(k KubeletBootstrap, podCfg *config.PodConfig, kc *KubeletConfig) {
// start the kubelet
go wait.Until(func() { k.Run(podCfg.Updates()) }, 0, wait.NeverStop)
// start the kubelet server
//创建时候可以指定端口 --port=10250: The port for the Kubelet to serve on.
if kc.EnableServer {
go wait.Until(func() {
k.ListenAndServe(kc.Address, kc.Port, kc.TLSOptions, kc.Auth, kc.EnableDebuggingHandlers)
}, 0, wait.NeverStop)
}
if kc.ReadOnlyPort > 0 {
go wait.Until(func() {
k.ListenAndServeReadOnly(kc.Address, kc.ReadOnlyPort)
}, 0, wait.NeverStop)
}
}