kubelet源码分析(一):工作原理
从 kubelet 源码来分析它的工作原理.
kubelet 工作原理

Kubelet 的工作核心就是一个控制循环 syncLoop ,驱动这个控制循环运行的事件,包括: Pod 更新事件, Pod 生命周期变化, Kubelet 本身设置的执行周期、定时的清理任务(GC ).
在这个大循环 syncLoop 之外, kubelet 还维护着许多其他的字控制循环,就是图中的小圆圈, 比如:
podManager: 主要用于存储和管理期望的Pod集合,包括被接受的常规pod和镜像pod(mirror pods).podWorkers: 主要负责管理pod生命周期状态机的关键组件, 它会处理pod的几个状态- syncing:pod 应该正在运行(调用
syncPod方法)。 - terminating:pod应该正在停止(调用
syncTerminatingPod方法)。 - terminated:pod应该已经清理了所有资源(调用
syncTerminatedPod方法)。
- syncing:pod 应该正在运行(调用
evictionManager: 负责监控节点的状态,以识别可能影响节点稳定性的情况,并通过驱逐pod(将pod状态设置为Failed,并给出原因Evicted)来减轻资源压力; 并依赖podWorker的权威性来执行驱逐操作。这样可以确保在资源压力过大或其他影响节点稳定性的情况下,能够及时采取措施,恢复节点的正常运行probeManager: 会定时去监控Pod中容器的健康状况,当前支持两种类型的探针:livenessProbe和readinessProbe.secretManager: 是kubelet中负责缓存和管理运行在节点上的pod所使用的secret的组件,它通过与podWorkers的协作,确保在pod启动和终止时正确地获取和清理secret,并保持secret的最新状态。configMapManager: 是kubelet中负责缓存和管理运行在节点上的pod所使用的configmap的组件。它通过与podWorkers的协作,确保在pod启动和终止时正确地获取和清理configmap, 并保持configmap的最新状态。volumeManager: 是kubelet中负责管理运行在节点上的pod所使用的卷的组件。它通过观察pod的生命周期,执行必要的卷操作,并定期同步卷状态以确保与实际期望的卷集合一致,并管理这些pod的生命周期中涉及的卷(volumes)操作,包括:- 挂载(attaching):将卷连接到节点。
- 挂载(mounting):将卷挂载到pod的文件系统。
- 卸载(unmounting):从pod的文件系统卸载卷。
- 分离(detaching):从节点断开卷的连接。
statusManager: 是kubelet中负责更新和管理pod状态的组件。它从podWorker接收状态更新,并将这些更新同步到API服务器中。statusManager对于kubelet合成的pod状态具有权威性,其他组件应该咨询它以获取正确的状态信息。同时,由于statusManager依赖于podWorker,因此需要检查pod运行状态的组件应该直接咨询podWorker。这样可以确保pod状态的一致性和准确性,从而保证整个系统的正常运行。imageManager: 是kubelet中负责管理镜像垃圾回收的组件。它通过定期检查和清理不再使用的镜像,帮助维护节点的磁盘空间,确保节点有足够的资源来运行新的podcontainerLogManager: 是kubelet中负责管理容器日志的组件。它通过收集、存储、轮转和清理容器日志,确保日志数据的可用性和节点的磁盘空间不会被过度消耗。serverCertificateManager: 是kubelet中负责处理证书轮换的组件。它通过监控证书的有效期,自动进行证书轮换,并确保所有相关组件能够使用新的证书。这个组件对于维护集群的安全通信和防止证书过期导致的服务中断非常重要。cloudResourceSyncManager: 是kubelet中负责处理向云服务提供商发送请求的组件。它通过设置请求的超时时间,确保请求在预定的时间内完成,并处理请求过程中可能出现的错误。Runtime相关的字段:containerRuntime: 是kubelet中负责管理容器生命周期的组件。它与底层的容器运行时(如Docker、containerd、CRI-O等)进行通信,执行以下任务streamingRuntime: 负责处理容器的流式操作,如日志流、exec命令和端口转发等runtimeService: 是一个内部API服务,它提供了与容器运行时进行交互的接口。这个服务通常是容器运行时接口(Container Runtime Interface, CRI)的一部分;在内部主要是调用containerRuntime这个对象去管理容器。
PLEG相关的字段:PLEG 是基于轮询的定期检查机制,用于检测和报告容器状态的变化, eventedPleg 是基于事件驱动的实时响应机制,用于以低延迟提供容器状态的变化。PLEG(Pod Lifecycle Event Generator):- 定期检查:PLEG 定期(通常是每隔几秒钟)检查所有pod和容器的状态,并将状态变化生成事件。
- 轮询机制:PLEG 使用轮询机制来检测容器状态的变化,这意味着它需要定期扫描所有容器,即使没有状态变化也会进行检查。
- 延迟:由于是定期检查,PLEG 可能会有一定的延迟,因为它需要等待下一个检查周期才能发现状态变化。
eventedPleg:- 事件驱动:
eventedPleg通过监听容器运行时的事件来实时获取容器状态的变化,而不是定期检查。 - 低延迟:
eventedPleg可以在容器状态发生变化时立即响应,因此具有更低的延迟。 - 边缘驱动:
eventedPleg在容器状态变化的边缘(即事件发生时)触发响应,而不是在周期性的检查点。
- 事件驱动:
containerRefManager: 容器引用的管理,用来报告容器的创建、失败事件等.
上述描述了 Kubelet 结构体中定义的核心的字段,除此之外还有很多字段,一些字段比较简单,这里不一一描述。

Kubelet 启动之后会创建 syncLoopIteration 的循环,它接受一个 podUpdate 的 chan ,分别从静态文件、HTTP URL、List-Watch(API) 三个来源写入创建、更新、删除的 Pod ;
接收到 podUpdate 对象之后,会进入 podWorkers.UpdatePod 的方法中进行处理,之后发往 podWork chan 里面,在 podWorkLoop 中,针对每个 pod 会创建一个协程,然后在 syncPod 中处理,里面主要就是把 pod 发往 podStatus 中进行状态处理,还有就是创建容器,然后就是调用 CRI 的接口拉镜像、调用 device-plugin 的接口进行设备的分配,以及 CRI 的容器服务接口创建容器等。
在 syncLoopIteration 中还会通过 syncCh 和 cleanupCh 配置的 time.Ticker 定期的处理 pod,以及在 containerCh chan 中接受 device-plguin 上报的设备健康信息,还有 probeCh 这个根据 livenessManager、readinessManager、startupManager 这三个探针的结果影响 pod 的状态更新;
plegCh 会接受 Pod 的 Lifecycle Event ,根据 Event 来决定 pod 的 sync.