本文从消息流的角度总结KubeEdge云端的消息传输。
0. 消息通信基础
KubeEdge组件间的消息传输是通过beehiveContext进行的,本文不再具体分析消息在组件间是如何传输的。
1. 下行消息流
1.1. EdgeController下行控制器的消息流
EdgeController下行控制器负责监听pod、configmap、secret、node、service和endpoints相关事件,消息流如下:
- 各个资源manager:启动了SharedInformer协程并创建了一个信道,从k8s监听到的event送入这个信道(pod与其他资源流程略有不同,具体请看相关博文)
- 各个资源同步协程:从信道获得event,构建对应的消息,发送到CloudHub
- node、pod、configmap和secret的相关信息也会被更新到下行控制器的本地缓存中
消息流完成,剩下的交给CloudHub。
1.2. DeviceController下行控制器的消息流
DeviceController下行控制器负责监听devicemodle和device相关事件,其中configMapManager相关的程序1.2版本可能还没有完善,暂时跳过。消息流如下:
- 两个manager:启动了SharedInformer协程并创建了一个信道,从k8s监听到的event送入这个信道
- syncDeviceModel协程:从信道获得设备模板event,更新到manager的Map中去。注意,设备模板相关事件无需发给边缘
- syncDevice协程:从信道获得设备event,更新到manager的Map中去,并构建相应消息发送到CloudHub
消息流完成,剩下的交给CloudHub。
1.3. SyncController下行消息流
SyncController负责不断地检查每个ObjectSync对应的资源云边消息版本号/删除与否是否一致,消息流如下:
- wait.Until协程:循环运行reconcile函数
- reconcile函数:对于所有的ObjectSync,由于当收到边缘的ACK消息后才会被更新,其代表边缘资源的最新状态。当云端资源的状态比ObjectSync中的新时,就需要发送更新/删除事件消息到边缘,消息发送给CloudHub。
消息流完成,剩下的交给CloudHub。
1.4. CloudHub下行消息流
从云端发往边缘的消息有两种,EdgeController/SyncController发出的event消息和DeviceController发出的设备相关消息,消息流如下:
- DispatchMessage协程:接收控制器发来的消息,将消息和存到ChannelMessageQueue中,同时通过ObjectSyncController判断消息是不是旧消息。消息分为Message和ListMessage,前者需要ACK而后者不用
- CloudhubHandle:通过MessageWriteLoop和ListMessageWriteLoop分别处理上面的两种消息,它们从ChannelMessageQueue中取得消息,交给handleMessage函数处理
- handleMessage:对于ListMessage,直接发给边缘并删除ChannelMessageQueue中的备份;对于Message,发给边缘后等待ACK消息
消息流完成,剩下的参见CloudHub对上行ACK消息的处理。
2. 上行消息流
2.1. CloudHub上行消息流
从边缘发往云端的消息目前有四种:
- keepalive消息:心跳消息,发到KeepaliveChannel,确定边缘节点保持连接
- resp消息:当云端发出一个同步消息到边端后,会在ChannelContext的anonChannels中创建一个信道,并一直等待边端回应resp消息。当收到边端的resp消息后,将消息发到刚刚创建的那个信道,云端就会知道边端回应了消息,SendSync成功完成。当然,如果一直收不到就会超时报错。注意:判断消息是resp消息的依据是通过一个正则表达式判断的,注意和ack消息区分
- ack消息:1.2版本云端发送普通消息给边端后,会创建一个ack信道,并要求边端发一个ACK消息回云端,代表边端成功处理了消息。这个ack信道存在MessageHandle的MessageAcks中。收到ack消息后,CloudHub给这个信道发一个空消息并关闭这个信道,发送程序就知道了。发送程序会根据发送成功的这个消息更新对应的ObjectSync。注意:判断消息是ack消息的依据是
Router.Operation == "response"
,不要和上面的resp消息搞混了 - 其他消息:即需要发给控制器进行处理的消息。如果是设备相关消息就发给DeviceController,否则发给EdgeController。
消息流完成,剩下的交给EdgeController和DeviceController处理。
2.2. EdgeController上行控制器的消息流
EdgeController上行控制器负责……消息流如下:
- dispatchMessage协程:收到CloudHub分配过来的消息,根据resourceType发到对应的信道
- 处理资源更新/请求/删除的协程:对于更新操作,通过kubeClient更新k8s中的资源,回复ACK消息;对于请求操作,查找到请求的资源,回复ACK消息;对于删除操作,目前只有删除pod操作,直接通过kubeClient在k8s中删除,无需回复。
对于上面的回复消息,当EdgeSite模式开启的时候,调用的是SendResp,而当EdgeSite模式关闭的时候,调用的是Send。原因可能是EdgeSite模式下边缘不会接收ACK消息。
消息流完成。
2.3. DeviceController上行控制器的消息流
DeviceController上行控制器负责同步边缘设备的状态给云端,消息流如下:
- dispatchMessage协程:收到CloudHub分配过来的消息,发到自己的信道
- updateDeviceStatus协程:从信道接收消息,从下行控制器的deviceManager中的Map缓存里获取相应的设备,更新后存回去。另外,通过crdClient更新k8s中设备实例的状态
消息流完成。