kubelet 理解

statusManager 的运行

2018-05-11  本文已影响0人  shinwing

statusManager 负责维护状态信息,并把 pod 状态更新到 apiserver,但是它并不负责监控 pod 状态的变化,而是提供对应的接口供其他组件调用,比如 probeManager。probeManager 会定时去监控 pod 中容器的健康状况,一旦发现状态发生变化,就调用 statusManager 提供的方法更新 pod 的状态。

Pod的状态(Phase)有5种:运行中(PodRunning),等待中(PodPending),正常终止(PodSucceeded),异常停止(PodEailed),未知状态(PodUnkonwn)。

PodStatus struct {

        Phase PodPhase

        Conditions []PodCondition

        Message string

        Reason string

        NominatedNodeName string

        HostIP string

        PodIP string

        StartTime *metav1.Time

        InitContainerStatuses []ContainerStatus

        ContainerStatuses []ContainerStatus

        QOSClass PodQOSClass

}

从上面可以看出,Pod的状态也包括了它里面运行的Container的状态。另外也给出了导致当前状态的原因说明,Pod的启动时间等信息。

先看一下接口的声明:

type PodStatusProvider interface {

    GetPodStatus(uid types.UID) (v1.PodStatus, bool)

}

type Manager interface {

    PodStatusProvider

    Start()

    SetPodStatus(pod *v1.Pod, status v1.PodStatus)

    SetContainerReadiness(podUID types.UID, containerID kubecontainer.ContainerID, ready bool)

    TerminatePod(pod *v1.Pod)

    RemoveOrphanedStatuses(podUIDs map[types.UID]bool)

}

这个接口的方法可以分成三组:1. 获取某个 pod 的状态、2. 后台运行 goroutine 执行同步工作、3. 修改 pod 的状态。修改状态的方法有多个,每个都有不同的用途:

        1) SetPodStatus:如果 pod 的状态发生了变化,会调用这个方法,把新状态更新到 apiserver,一般在 kubelet 维护 pod 生命周期的时候会调用

        2)SetContainerReadiness:如果健康检查发现 pod 中容器的健康状态发生变化,会调用这个方法,修改 pod 的健康状态

        3)TerminatePod:kubelet 在删除 pod 的时候,会调用这个方法,把 pod 中所有的容器设置为 terminated 状态

        4)RemoveOrphanedStatuses:删除孤儿 pod,直接把对应的状态数据从缓存中删除即可

如果调用了修改状态的方法,那么就触发Pod状态变化(updateStatusInternal),生成podStatusSyncRequest放入chan中:

start 方法启动了一个goroutine来负责同步,

    go wait.Forever(func() {

        select {

        case syncRequest := <-m.podStatusChannel:

            m.syncPod(syncRequest.podUID, syncRequest.status)

        case <-syncTicker:

            m.syncBatch()

        }

    }, 0)

这个 goroutine 就能不断地从两个 channel 监听数据进行处理:syncTicker 是个定时器,也就是说它会定时保证 apiserver 和自己缓存的最新 pod 状态保持一致;

podStatusChannel 是所有 pod 状态更新发送到的地方,调用方不会直接操作这个 channel,而是通过调用上面提到的修改状态的各种方法,这些方法内部会往这个 channel 写数据。goroutine 从podStatusChannel读取信息,然后更新Pod。由于statusManager有一个podStatuses map[types.UID]versionedPodStatus 的成员变量,本身缓存了pod的status信息,因此可以定期syncBatch,在 podStatusChannel  channel 满的时候,异步上报到APIServer。

syncPod 中 m.syncPod 根据参数中的 pod 和它的状态信息对 apiserver 中的数据进行更新,如果发现 pod 已经被删除也会把它从内部数据结构中删除。

上一篇 下一篇

猜你喜欢

热点阅读