怎么分析kubelet中的Pod同步流程,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
kubelet最核心的功能就是根据master的指示,在节点上创建并管理pod。目前对于kubelet而言,有三种途径来获取所管理的pod清单:
文件 - 通过启动参数–config指定配置目录,定期检查变更。
HTTP Endpoint - 通过--manifest-url参数指定,定期检查更新。
API Server - 通过API Server监听etcd目录,实时同步pod清单。
通过API Server监听Pod清单,并在节点上维护对应的Pod实例,这是整个kubelet进程的核心主流程。下图近似描述了这个过程:
注意:在实际研究过程中,发现go语言实现的系统在调用逻辑上和Java/C++这些语言实现的系统有很大差异。go语言除了对象之间相互方法调用之外,还存在大量的goroutine间通过channel发送消息调用的情况。因此,从逻辑上来讲,go语言的调用事实上是并发的,类似于网状的。而不是传统的同步调用,线性的关系。因此,感觉很难用UML图来表示对象间的调用顺序。上图仅仅是把关键的对象及方法入口表示出来而已,而且有很多省略。当中如果有错误或更好的表述方式,也请告知作者。
/pkg/kubelet/kubelet.go文件中的Kubelet结构体是整个kubelet进程的核心数据结构,它持有了所有关联的实体对象。Kubelet有两个主要的入口方法:
NewMainKubelet - 创建并初始化一个Kubelet结构(将所有关联实例都初始化好)。
Run - 启动所有辅助的goroutines以及上文中提到的主流程。
在NewMainKubelet方法中,调用了一个makePodSourceConfig的私有方法,该方法会返回一个PodConfig对象指针。其中有一个field叫做updates chan kubetypes.PodUpdate,用于传递pod更新消息。
updates通道一边连接着从三种来源获取pod更新信息的goroutines。一边被kubelet的主流程消费,即获取pod更新信息,并同步操作Pod实例。
kubelet的主流程方法入口是Kubelet.syncLoopIteration,用于不断分发updates通道中的消息。
/pkg/kubelet/pod_workers.go文件中的podWorkers结构,是一个协程池。podWorkders会为每个pod单独起一个goroutine,专门用于消费该pod相关的update信息,实施pod的操作。
podWorkers有两个关键方法:
UpdatePod - update入口,启动并管理每个pod的update协程。
managePodLoop - worker的实际逻辑,最终调用Kubelet.syncPod方法。
在managePodLoop每次Pod同步完成之后,会调用wrapUp方法。该方法用于周期性同步pod,即使没有收到API Server推送的变更。
wrapUp方法会在podWorkers的workQueue中push下次发生同步的时间戳。同时kubelet.syncLoopIteration方法会周期性从podWorkers.workQueue中拉取当前时刻需要同步的pod列表,并触发SyncPod操作。
在1、Kubelet关键模块 文档中有描述,该结构体实现了kubecontainer.Runtime接口,封装了Container & Image相关的操作。
主流程中调用的是该结构体的SyncPod方法,它会计算出当前该Pod上所需要执行的操作,通过CRI接口执行。
dockershim中对CRI接口的实现,kubeGenericRuntimeManager和dockerService之间实际上通过gRPC来通讯。
kubeDockerClient是对libdocker.Interface接口的封装,通过HTTP(s)和docker daemon通讯。
看完上述内容,你们掌握怎么分析kubelet中的Pod同步流程的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。