PLEG(PodLifecycleEventGenerator)主要是用于周期性检测Pod的运行状态,从而对比Pod先后状态生成事件从而触发kubelet进行Pod容器状态的校证,让咱们一块儿来初探下其内部实现机制算法
Pod事件生成主要是根据对应Pod先后的状态对比来实现,首先经过runtime来获取当前节点的全部Pod的列表,并将对应的状态进行保存,这样在下一个轮训周期就能够经过先后状态的对比去发现状态发生改变的Pod的容器,而且产生对应的事件微信
Pod事件生成以后会经过管道将对应的事件同步给状态同步线程,状态同步线程感知到Pod的变动事件后,会与Pod的目标状态进行对比同步,并调用Runtime来进行最终校证操做的执行,同时在下个轮询周期中又会从新从Runtime获取状态,从而不断校证Pod的状态,直至目标状态数据结构
Pod记录其实就是一个map,并经过podRecord来保存先后轮询周期Runtime返回的Pod的信息ide
type podRecord struct {
old *kubecontainer.Pod
current *kubecontainer.Pod
}
type podRecords map[types.UID]*podRecord复制代码
首先经过runtime来获取当前节点的全部pod的状态源码分析
// Get all the pods.
podList, err := g.runtime.GetPods(true)
if err != nil {
klog.Errorf("GenericPLEG: Unable to retrieve pods: %v", err)
return
}复制代码
eventsByPodID := map[types.UID][]*PodLifecycleEvent{}
for pid := range g.podRecords {
// 获取以前的Pod信息
oldPod := g.podRecords.getOld(pid)
pod := g.podRecords.getCurrent(pid)
// 获取当前Pod的全部容器集合
allContainers := getContainersFromPods(oldPod, pod)
for _, container := range allContainers {
//
events := computeEvents(oldPod, pod, &container.ID)
for _, e := range events {
// 更新pod的events事件
updateEvents(eventsByPodID, e)
}
}
}复制代码
Pod的事件主要是经过底层容器的状态来生成的,会最终对比每一个容器的先后状态,从而获取变动事件ui
func generateEvents(podID types.UID, cid string, oldState, newState plegContainerState) []*PodLifecycleEvent {
if newState == oldState {
return nil
}
klog.V(4).Infof("GenericPLEG: %v/%v: %v -> %v", podID, cid, oldState, newState)
switch newState {
case plegContainerRunning:
return []*PodLifecycleEvent{{ID: podID, Type: ContainerStarted, Data: cid}}
case plegContainerExited:
return []*PodLifecycleEvent{{ID: podID, Type: ContainerDied, Data: cid}}
case plegContainerUnknown:
return []*PodLifecycleEvent{{ID: podID, Type: ContainerChanged, Data: cid}}
case plegContainerNonExistent:
switch oldState {
case plegContainerExited:
// We already reported that the container died before.
return []*PodLifecycleEvent{{ID: podID, Type: ContainerRemoved, Data: cid}}
default:
return []*PodLifecycleEvent{{ID: podID, Type: ContainerDied, Data: cid}, {ID: podID, Type: ContainerRemoved, Data: cid}}
}
default:
panic(fmt.Sprintf("unrecognized container state: %v", newState))
}
}复制代码
在k8s中有不少相似PLEG的设计,总的设计目标都是为了经过事件的变动和实际指望状态,不断的进行调整,从而达到最终的指望状态, 之后我尽可能只给出组件最核心的一点代码,梳理清除整个流程中核心的数据结构与算法spa
k8s源码阅读电子书地址: www.yuque.com/baxiaoshi/t…线程
微信号:baxiaoshi2020
设计
关注公告号阅读更多源码分析文章
3d
更多文章关注 www.sreguide.com
本文由博客一文多发平台 OpenWrite 发布