您现在的位置是:首页 > 文章详情

图解kubernetes Pod生命周期事件生成器

日期:2020-02-21点击:397

PLEG(PodLifecycleEventGenerator)主要是用于周期性检测Pod的运行状态,从而对比Pod前后状态生成事件从而触发kubelet进行Pod容器状态的校证,让我们一起来初探下其内部实现机制

1. 图解设计

1.1 Pod事件生成

image.png Pod事件生成主要是根据对应Pod前后的状态对比来实现,首先通过runtime来获取当前节点的所有Pod的列表,并将对应的状态进行保存,这样在下一个轮训周期就可以通过前后状态的对比去发现状态发生改变的Pod的容器,并且产生对应的事件

1.2 事件通知与状态同步

image.png Pod事件生成之后会通过管道将对应的事件同步给状态同步线程,状态同步线程感知到Pod的变更事件后,会与Pod的目标状态进行对比同步,并调用Runtime来进行最终校证操作的执行,同时在下个轮询周期中又会重新从Runtime获取状态,从而不断校证Pod的状态,直至目标状态

2. Pod记录

Pod记录其实就是一个map,并通过podRecord来保存前后轮询周期Runtime返回的Pod的信息

type podRecord struct { old *kubecontainer.Pod current *kubecontainer.Pod } type podRecords map[types.UID]*podRecord 

3. Pod事件生成器

3.1 获取Pod状态

首先通过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 } 

3.2 对比Pod信息生成事件

 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) } } } 

3.3对比容器状态事件生成

Pod的事件主要是通过底层容器的状态来生成的,会最终对比每个容器的前后状态,从而获取变更事件

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)) } } 

4. 整体事件流程总览

image.png 在k8s中有很多类似PLEG的设计,总的设计目标都是为了通过事件的变更和实际期望状态,不断的进行调整,从而达到最终的期望状态, 以后我尽量只给出组件最核心的一点代码,梳理清除整个流程中核心的数据结构与算法

k8s源码阅读电子书地址: https://www.yuque.com/baxiaoshi/tyado3 > 微信号:baxiaoshi2020 > 关注公告号阅读更多源码分析文章 21天大棚 > 更多文章关注 www.sreguide.com > 本文由博客一文多发平台 OpenWrite 发布

原文链接:https://my.oschina.net/u/4131034/blog/3168899
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章