kubernetes源码-kubelet 原理和源码分析(一)
kubelet 的启动流程,源码为 kubernetes 的 release-1.22 分支 .
写在前面
kubelet 运行在每个节点之上,功能就是上报 Node 节点信息,管理(创建、销毁)Pod ,单纯从功能上来看,貌似很简单,实际不然。每一个点单独拿出来看,都需要花很多精力去分析,记录起来也需要很大的篇幅。
面对这么多的内容,我们一时间也不知道从何看起,不如就先从 kubelet 启动流程开始看起。
入口函数
我们从入口函数开始,入口位于 cmd/kubelet/app/server.go 。
其中 RunKubelet() 接口下的 startKubelet 即是启动 kubelet 的启动函数。
|
|
跟随 k.Run() 接口我们跳转到 pkg/kubelet/kubelet.go ,这里就是 kubelet 的启动接口代码所在。
|
|
启动流程
-
StartGarbageCollection() ,启动垃圾回收器,初始化 podWorkers (第一步是在 构造 kubelet 阶段完成,接着才运行 startKubelet )。
-
cloudResourceSyncManager.Run() ,启动云提供商资源同步管理器,如获取当前节点 ip 列表。
-
initializeModules() ,初始化模块,这里的模块不依赖容器运行时的运行状态。
a. metrics.Register ,注册 Prometheus 监控指标。
b. setupDataDirs ,设置文件目录。
-
a. the root directory .
-
b. the pods directory .
-
c. the plugins directory .
-
d. the pod-resources directory .
c. ContainerLogsDir ,创建容器日志目录。
d. imageManager.Start() ,启动镜像管理器。
e. serverCertificateManager.Start() ,启动证书管理器。
f. oomWatcher.Start() ,启动 oom 监听器。
g. resourceAnalyzer.Start() ,启动资源分析管理器。
-
-
volumeManager.Run() ,启动存储卷管理器。
-
syncNodeStatus, 同步节点状态。.
-
nodeLeaseController.Run() ,同步节点租约。
-
initializeRuntimeDependentModules() ,初始化运行时所依赖的模块。
-
containerManager.Start() ,启动容器管理器。
-
evictionManager.Start() ,驱逐管理器。
-
containerLogManager.Start() ,容器日志管理器。
-
kl.pluginManager.Run() ,启动插件管理器。
-
kl.shutdownManager.Start() ,启动 shutdown 管理器。
-
-
initNetworkUtil ,设置 iptables规则。
-
statusManager.Start() ,同步 pod 状态,并更新 pod 状态到缓存。
-
runtimeClassManager.Start() ,启用 RuntimeClasses 管理器,为 Pod 选择合适运行时,检测集群运行时等。
-
pleg.Start() ,启动 plge ,管理和上报 pod 生命周期。
-
syncLoop() ,启动主进程,接口 kl.syncLoopIteration() 监听来自 file/apiserver/http 事件源发送过来的事件,并对事件做出对应的同步处理。
a. 从 configCh 通道获取配置更新事件,事件类型:
-
ADD
-
UPDATE
-
REMOVE
-
RECONCILE
-
DELETE
b. 从生命周期通道 plegCh 获取事件。
c. 从 syncCh 通道获取事件,跟踪并更新 Pod 状态,如果 pod 状态发生变化,则触发跟 apiserver 同步最新的 pod 信息。
d. livenessManager.Updates() 事件。
e. readinessManager.Updates() 事件。
f. startupManager.Updates() 事件。
g. 从 housekeepingCh 通道获取事件。
-
流程图
光看上面那些文字可能不太好理解,我们可以画个思维导图,来重新帮我们整理一下他们之间的关系。
总结
kubelet 也是代码量相当庞大的组件之一,我们光从启动流程我们就能得出这个结论。
光靠我们一个人,一口气吃不下这么大的信息量,我们只能拆分成一个个点去看,搞清楚它的启动流程后,我们就可以先从它是如何创建 pod 这一部分的代码来看。