kubelet 对象(类型为 Kubelet)则代表 kubelet 内部跟 pod 息息相关的子模块,比如 podManager(pod 信息存储模块),probeManager(pod 测活模块)等等。

    那么 kubelet 中各个子模块之间是如何配合工作的呢?主要是基于生产者消费者的模型。
    整个 kubelet 的工作模式就是在围绕着不同的生产者生产出来的不同的有关 pod 的消息来调用相应的消费者(不同的子模块)完成不同的行为,比如创建 pod,删除 pod,如下图所示
    image.png
    那么 kubelet 中主要包含哪几个消息的生产者呢?消费者又是怎么消费的呢?
    我们可以在 kubelet 的 syncLoopIteration 函数中看到 kubelet 到底同时接收哪几个信息源

    | // configCh: dispatch the pods for the config change to the appropriate
    // handler callback for the event type
    //
    plegCh: update the runtime cache; sync pod
    // syncCh: sync all pods waiting for sync
    //
    houseKeepingCh: trigger cleanup of pods
    // liveness manager: sync pods that have failed or in which one or more
    // containers have failed liveness checks
    func (kl
    Kubelet) syncLoopIteration(…) {
    case u, open := <-configCh:

    case e := <-plegCh:

    case <-syncCh:

    case update := <-kl.livenessManager.Updates():

    case <-housekeepingCh:

    } | | :—- |

    通过代码注释可以看出,kubelet 主要有 5 个不同的信息源

    • configCh: 该信息源由 kubeDeps 对象中的 PodConfig 子模块提供,该模块将同时 watch 3 个不同来源的 pod 信息的变化(file,http,apiserver),一旦某个来源的 pod 信息发生了更新(创建/更新/删除),这个 channel 中就会出现被更新的 pod 信息和更新的具体操作。
    • plegCh: 该信息源由 kubelet 对象中的 pleg 子模块提供,该模块主要用于周期性地向 container runtime 查询当前所有容器的状态,如果状态发生变化,则这个 channel 产生事件。[1]
    • syncCh: 该信息源是一个周期性的信号源(默认1秒),周期性同步所有需要再次同步的 pod。
    • liveness manager update: 该信息源是由 kubelet 对象中 livenessManager管理,当某个容器的 liveness probe 状态发生了变化,则会产生事件。
    • housekeepingCh: 该信息源也是一个周期性信号源(默认2秒),周期性的清理一些无用 pod。

    所有的这些消息源产生的消息都由 kubelet 对象统一接受,并且调用相应的功能函数来完成相应的操作。
    kubelet 对象自身实现一系列处理不同事件的 handler 函数,并且汇总成 SyncHandler 接口,其中包含针对不同信息源里不同消息类型的处理函数

    | type SyncHandler interface {
    HandlePodAdditions(pods []v1.Pod)
    HandlePodUpdates(pods []
    v1.Pod)
    HandlePodRemoves(pods []v1.Pod)
    HandlePodReconcile(pods []
    v1.Pod)
    HandlePodSyncs(pods []*v1.Pod)
    HandlePodCleanups() error
    } | | :—- |

    当然,每一个处理函数背后可能都需要 kubelet 对象去调用背后多个内部子模块来共同完成,比如 HandlePodAddition 函数,处理 Pod 的创建,其中可能需要

    • 调用 kubelet.podManager 子模块 AddPod 函数,注册该 pod 信息
    • 调用 kubelet.podWorker 子模块为这个 Pod 创建单独的 worker goroutine 完成具体的操作
    • 调用 kubelet.containerManager 子模块为这个 Pod 创建相应的 Pod Level Cgroup
    • 调用 kubelet.volumeManager 子模块为这个 Pod 准备需要被 Mount 到容器中的文件系统
    • 调用 kubelet.containerRuntime 子模块真正的创建 Pod 的实体
    • ….

    所以综上,整个 kubelet 的所有内部子模块就是通过这种生产者消费者模型协调工作,及时将 Pod 以用户期望的状态维护在它所在的机器上。