statusManager 的运行
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的启动时间等信息。
先看一下接口的声明:
![](https://img.haomeiwen.com/i12042804/3d1dd87f729c9df6.jpg)
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中:
![](https://img.haomeiwen.com/i12042804/996926f957c3b2e4.jpg)
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。
![](https://img.haomeiwen.com/i12042804/e62328c5f17c9a6b.jpg)
syncPod 中 m.syncPod 根据参数中的 pod 和它的状态信息对 apiserver 中的数据进行更新,如果发现 pod 已经被删除也会把它从内部数据结构中删除。
![](https://img.haomeiwen.com/i12042804/4c2e42e53eaa9295.jpg)