KubeEdge云边协同设计原理 (2)

KubeEdge云边协同设计原理

 

 DeviceController的内部设计跟EdgeController是很相像的,主要也是上行和下行。

边缘存储的集成与设计

边缘存储所需要的工作量会大很多,主要因为存储的后端本身交互上有一些额外的操作。

k8s推荐的CSI部署方式

KubeEdge云边协同设计原理

 

 KubeEdge中CSI部署方案

KubeEdge云边协同设计原理

 

经过几种方案的选择Kubeedge最终把kubernetes社区提供的存储相关组件放到云上去,把存储方案提供商相关组件放到边缘去。这里有一个问题:当进行Provisioner操作和Attacher操作的时候所调用的存储后端在边缘,这里采取的做法是伪装一个存储后端,即CSI Driver from KubeEdge这个组件的外部行为。在Provisionner看来,通过UDS访问的CSI Driver就是一个真正的存储方案的Driver,但实际上是kubeedge里面伪装出来。它的实际实现是把这个请求按照云边协同的消息格式做封装传给CloudHub直到边缘的Edged,这里CSI Volume Plugin是之前kubelet的关于存储的一段代码,在Edged相应对等的位置有一个csi的实现,它会将消息解开去调用处在边缘的存储后端。

 

CloudHub与EdgeHub的通信机制 下行-通过CloudHub下发元数据

KubeEdge云边协同设计原理

 

 

CloudHub的实现上比较简单。MessageDispatcher在下发元数据的时候会用到,KubeEdge的设计是每个节点上通过websocket需要维护一个长连接,所以会有一个连接池这么一层。在这个连接池之上每个websocket会有一个对应的MessageQueue,因为从云上下发到边缘上的数据会比较多的,虽然说比原生的kubernetes的list-watch下发的少,但同一时刻不可能只有一个数据等着下发。

EdgeController、DeviceController下发的数据会经过MessageDispatcher分发到每一个节点对应的待发送队列中,因为每个EdgeNode有它自己关心的数据,如果是一些通用的数据比如configMap,那么dispatcher就会往每一个队列中去丢消息的副本。待发送队列会将消息通过websocket发送到边缘去,然后边缘节点再去做后续的处理。

实际上整个过程就是一个分发塞队列的过程。

上行-通过CloudHub刷新状态

KubeEdge云边协同设计原理

 

上行会更简单一点,因为上行会直接到Controller里去,没有经过队列的处理了,controller在通过api-server去做相应的变更通知,这里controller本身内部会有消息处理的队列 。因此上行时候不会经过待发送队列以及MessageDispatcher。

CloudHub与Controller的通信是用beehive模块间通信的框架来实现的。

消息格式的封装

KubeEdge云边协同设计原理

 

消息格式的封装是云边协同设计的核心,云边协同里面封装的消息其实是K8s的API对象,kubernetes中采用的是声明式api设计,对象上某个字段的变化实际上都是一个期望值或者是最终的一个状态。之所以选择把整个k8s的api对象原封不动的丢进Message结构体里,就是为了保留这种设计的理念,即最终对象的变化需要产生什么样的动作,相应组件会去处理比较来产生差异,然后去更新,而不是提前计算好差异在往下丢。提前计算好差异往下丢带来的问题是:计算差异的时候需要感知befor、after这两个对象,before对象的获取会有一个时间差,如果在获取处理的过程中这个对象被其他组件更新发生变化,这时候计算的差异就是不准的。所以把这个对象原封不动往下丢,丢到最后在去做diff。

声明式 API是 Kubernetes 项目编排能力“赖以生存”的核心所在: 首先,“声明式”指的就是只需要提交一个定义好的 API 对象来“声明”,所期望的状态是什么样子; 其次,“声明式 API”允许有多个 API 写端,以 PATCH 的方式对 API 对象进行修改,而无需关心本地原始 YAML 文件的内容; 最后,也是最重要的,有了上述两个能力,Kubernetes 项目才可以基于对 API 对象的增、 删、改、查,在完全无需外界干预的情况下,完成对“实际状态”和“期望状态”的调谐 (Reconcile)过程。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzwfd.html