本文分析的代码为当前的github master(即介于1.5与1.6)之间,主要对kubelet启动的整个流程的代码进行解析。
其main函数在 cmd/kubelet/kubelet.go
中,首先整理了kubelet的参数,并放入KubeletServer
中。然后,使用KubeletServer
作为参数调用Run
函数来启动kubelet。Run
函数主要调用了cmd/kubelet/app/server.go
中的函数进行kubelet的启动。从文件名也能出,kubelet是一个daemon进程。
Run
函数主要进行了以下操作:
- 启动一个后台进程对kubelet的配置与API server进行实时同步:首先创建可以于API server进行交互的kubeclient,通过这个client取得当前node的configmap。在configmap中取得
kubelet.config
字段所对应的值,就是kubelet配置对应的json格式。然后启动一个go程,将现在的配置和API server中的进行对比,如果两者不同则重启kubelet,以此来确保kubelet使用了最新的配置。 - 对kubelet的crt与key文件(kubelet与其他组件通信的公私钥文件)进行设置。
- 创建与apiserver通信的
EventClient
,用来获取kubelet所需的各种事件。 - 调用
UnsecuredKubeletDeps
创建了kubdeps对象。在此过程中,如果使用docker作为runtime,那么则会调用github.com/docker/engine-api/client
来创建docker的client。 - 对QOS(即服务质量,通过cgroup实现)进行解析和设置。
- 初始化
kubeDeps.ContainerManager
,并创建container manager。其中储存了是否使用CRI和使用何种runtime等信息。 - 调用
RunKubelet
函数,继续kubelet的启动工作。 - 再给点的端口healthz端口提供健康检查服务。
RunKubelet
继续整理各种参数。然后调用CreateAndInitKubelet
来真正实例化一个kubelet对象。在CreateAndInitKubelet
中首先调用了NewMainKubelet
。
- 首先对container/image的垃圾回收(GC)和disk space policy进行了配置。
- 创建工作节点本地的service和node的cache,并且使用list/watch机制持续对其进行更新。
- 创建DiskSpaceManager,用以与cadvisor配合进行工作节点的磁盘管理,这与kubelet是否接受新的pod在该工作节点上运行有密切关系。
- 创建ContainerRefManager,用以记录每个container及其对应的引用的映射关系,主要用于在pod更新或者删除时进行事件的记录。
- 创建OOMWatcher,用以从cadvisor中获取系统的内存溢出(out of memory, oom)事件,并对其进行记录。
- 解析kubeconfig中的DNS设置。
- 初始化kubelet网络插件,可以指定传入一个文件夹中的plugin作为kubelet的网络插件。
- 对容器的runtime进行判断,如果是docker&&CRI,则启动dockershim。
kubelet启动完成后通过事件收集器向APIServer发送一个kubelet已经启动的event,表明集群新加入了一个新的工作节点,kubelet将这一过程称为BirthCry
,即”出生的啼哭”。并且开始进行容器和镜像的垃圾回收,对应的时间间隔分别为1分钟和5分钟。
最后调用startKubelet
。startKubelet
则主要对指定的kubelet端口进行监听,以此与其他组件进行交互。