在Kubernetes集群中,每个Node节点(又称Minion)上都会启动一个Kubelet服务进行。该进程用于处理Master节点下发到本节点的任务,管理Pod及Pod中的容器。每个Kubelet进程会在API Server上注册节点自身信息,定期向Master节点汇报节点资源的使用情况,并通过cAdvise监控容器和节点资源。
此源码分析基于 K8s 1.14.6
Kubelet 架构
若想解读 Kubelet 源码,首先我们需要了解 Kubelet 的主要架构及组件。
启动入口
kubelet 的主函数入口在 cmd/kubelet/kubelet.go
中,启动代码很简洁:
func main() {
rand.Seed(time.Now().UnixNano())
// 这里则是启动 kubelet 服务进程,返回一个*cobra.Command
command := app.NewKubeletCommand(server.SetupSignalHandler())
logs.InitLogs()
defer logs.FlushLogs()
if err := command.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}
app.NewKubeletCommand
函数则是对 kubelet 进行参数化配置并启动 kubelet,然后生成kubelet对象以及该kubelet维护pod所需要用到的服务。主要步骤如下
- 解析参数,加载当前flag,对参数的合法性进行判断。flag 包含两种:
- kubeletFlags:kubelet -- 后追加的参数
- kubeletConfig: 通过解析特定配置文件获取
- 构造 cobra.Command 对象,此对象用于执行用户输入的命令行交互。此对象结构体为
{
Use: componentKubelet,
Long: ...,
// The Kubelet has special flag parsing requirements to enforce flag precedence rules,
// so we do all our parsing manually in Run, below.
// DisableFlagParsing=true provides the full set of flags passed to the kubelet in the
// `args` arg to Run, without Cobra's interference.
DisableFlagParsing: true,
Run: func(cmd *cobra.Command, args []string) {...
},
}
其中的 Run
则是用于具体执行用户命令的函数,这个函数的流程也就是 kubelet的主流程,创建 kubelet 对象,创建各种服务。
启动流程
这一部分解析一下 Run 函数。首先我们需要了解两个比较重要的配置结构体KubeletFlags
kubeletconfig.KubeletConfiguration
:
启动流程如下:
- 新建一个watch的功能,主要是用来watch kubelet的配置文件是否改变,如果已经改变,那么就重新load kubelet的配置文件 用的是kubernetes常用到的Controller,也就是Informer的架构,watch ConfigMap对象
> controller 相关代码在 `pkg/kubelet/kubeletconfig/controller.go`中 *//TODO 介绍下 controller informer 机制*