边缘计算平台 KubeEdge 云边协同机制解析

2023年 7月 10日 24.1k 0

KubeEdge介绍

KubeEdge 是一个致力于解决边缘场景问题的开源系统,在 Kubernetes原生的容器编排和调度能力之上,实现了云边协同、计算下沉、海量边缘设备管理、边缘自治等能力。KubeEdge架构如下图所示,包括云端和边缘端两部分。

KubeEdge架构图

KubeEdge架构图

其中:

CloudHub:WebSocket服务器,负责监控云端的变化、缓存并发送消息到EdgeHub。

EdgeController:扩展的Kubernetes控制器:负责管理边缘节点和pods 的元数据,因此数据才能被发送到指定的边缘节点。

DeviceController:扩展的Kubernetes控制器,负责管理边缘设备, 实现边缘设备元数据/状态数据在云端与边缘端的同步。

EdgeHub:WebSocket客户端,负责与云边服务交互实现边缘计算。其中包括将云边资源同步更新到边缘端以及将边端主机、设备状态变化广播至云端。

Edged:负责pod生命周期的管理,可以看成一个简易版的kubelet。

EventBus:EventBus 是一个MQTT客户端负责与MQTT服务器mosquitto的交互,为其他组件提供发布与订阅功能。

ServiceBus:ServiceBus 是一个HTTP客户端与HTTP服务器使用REST进行交互,为云端组件提供HTTP客户端功能,使其请求到达运行在边缘端的HTTP服务器。

DeviceTwin:负责存储设备状态,并将设备状态同步到云端,同时也提供了了应用的查询接口。

MetaManager:MetaManager 是edged与edgehub之间的message 处理器,同时,也负责将元数据存储/查询到/从一个轻量级数据库SQLite。

基于WebSocket + 消息封装,同时优化了原生Kubernetes 中一些不必要的请求,KubeEdge实现了边缘场景下的云边可靠通信。本文从边缘设备管理和云边自定义消息传递两个方面,来解析KubeEdge的云边协同机制。

边缘设备管理

DeviceModel和Device

KubeEdge通过Kubernetes的CRD,增加了DeviceModel和Device两个资源,分别来描述设备元信息和设备实例信息,DeviceController负责边缘设备管理,在云和边之间传递这些信息。用户可以通过Kubernetes API从云中创建、更新和删除设备元数据,也可以通过CRD API控制设备属性的预期(desired)状态,从云端对设备进行CRUD操作。

DeviceModel描述了设备属性,例如“温度”或“压力”,类似一个可重复使用的模板,使用它可以创建和管理许多设备。DeviceModel示例如下:

apiVersion: devices.kubeedge.io/v1alpha2
kind: DeviceModel

metadata:
  name: counter-model
  namespace: default
spec:
 properties:
 - name: status
  description: counter status
  type:
    string:
      accessMode: ReadWrite
      defaultValue: ''

示例定义了一个计数器的DeviceModel,它包含一个string类型的属性‘status’。

一个Device实例代表一个实际的设备对象。它就像device model的实例化,引用了model中定义的属性。计数器的Device示例如下:

apiVersion: devices.kubeedge.io/v1alpha2
kind: Device

metadata:
  name: counter
  labels:
    description: 'counter'
spec:
  deviceModelRef:
    name: counter-model
  nodeSelector:
    nodeSelectorTerms:
    - matchExpressions:
     - key: 'kubernetes.io/hostname'
       operator: In
       values:
       - kube-edge-1
status:
  twins:
    - propertyName: status
     desired:
       metadata:
         type: string
       value: 'OFF'
     reported:
       metadata:
         type: string
       value: '0'

yaml中的device status包含两份数据,一个是云端希望设置的状态数据(‘desired’),一个是边缘端上报的状态数据(‘reported’)。云端的DeviceController通过Kubernetes API监听device设备的创建事件,会自动创建一个新的configmap,存储该device的status等属性信息,并保存到ectd中。EdgeController将configmap同步到边缘节点,因而边缘节点的应用也能够获取设备的属性信息。‘desired’值将初始化到边缘节点数据库以及边缘设备中,因而即使边缘节点重启,也能自动恢复到之前的状态。当然这个‘desired’值也会随着云端用户对设备的CRUD而更改。

设备信息云边同步流程

云端更新设备的操作同步到边缘端,流程如下图:

云端的DeviceController监听device设备的变更事件,并将更新的twin数据通过CloudHub发送给边缘节点。边缘节点首先将数据存储到本地数据库,再通过mqttbroker同步到边缘设备中。

边缘端设备状态信息上报到云端,流程如下图:

边缘端上报的数据首先也要存储到本地数据库,再通过EdgeHub发送给云端。

云边自定义消息传递

ruleEndpoint和rule

在一些使用场景中,用户需要在云边应用之间传递一些自定义的信息。基于K8s的CRD,KubeEdge增加了ruleEndpoint和rule两个资源。ruleEndpoint定义了信息源端和目的端,rule定义了路由规则,从而实现云边应用间消息的传递。

ruleEndpoint有三种类型: rest, eventbus, servicebus。其中:

rest:仅用于表示云端的rest接口端点。既可以作为源端,发送请求到边缘节点,也可以作为目的端,接收边缘节点发来的信息。

eventbus:仅用于表示边缘节点的端点。既可以作为源端,发送数据到云端,也可以作为目的端,接收云端发来的信息。

servicebus: 仅用于表示边缘节点的rest接口端点。可作为目的端,接收云端发来的信息。

rule描述了信息是如何从源端发送到目的端的,目前有三条路径,如下图所示,其中:

rest -> enventbus: 用户在云端通过rest接口,发送信息到边缘端的mqttbroker。

eventbus -> rest: 用户在边缘端通过mqttbroker发送信息,最终信息发送到云端的rest接口。

rest -> servicebus: 用户在云端通过rest接口,发送信息到边缘端的rest接口。

消息传递机制

消息传递机制

如何传递自定义消息

首先,通过修改cloudcore的配置文件cloudcore.yaml,在路由器模块中加”enable:true”,表示启动路由器模块,然后重启cloudcore。

下面分别演示rule定义的三条消息传递路径的使用方式。

云端通过rest接口发送信息到边缘端mqttbroker

首先需要创建rest和eventbus类型的ruleEndpoint。执行命令:

kubectl create -f ruleEndpoint-rest.yaml
kubectl create -f ruleEndpoint-eventbus.yaml

ruleEndpoint-rest.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1 
kind: RuleEndpoint 

metadata: 
  name: my-rest 
  labels: 
    description: cloud-endpoint 
spec: 
  ruleEndpointType: "rest" 
  properties: {}

ruleEndpoint-eventbus.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1
kind: RuleEndpoint 

metadata: 
  name: my-eventbus
  labels: 
    description: edge-endpoint
spec: 
  ruleEndpointType: "eventbus" 
  properties: {}

然后创建规则,执行命令:

kubectl create -f rule-rest-eventbus.yaml

rule-rest-eventbus.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1 
kind: Rule 

metadata: 
  name: my-rule 
  labels: 
    description: cloud-rest-edge-eventbus 
spec: 
  source: "my-rest" 
  sourceResource: {"path":"/a"} 
  target: "my-eventbus"
  targetResource: {"topic":"test"}

在云端调用rest接口向边缘端发送信息,rest接口定义:

方法:POST

URL: http://{rest_endpoint}/{node_name}/{namespace}/{path}, {rest_endpoint} 是 {cloudcore_ip}:9443, {node_name} 是 edgenode 的名字, {namespace} 是规则的命名空间, { path} 的前缀是 source ruleEndpoint 的sourceResource。

Body: {user_message}, {user_message} 是用户的消息,

例如:

curl -X POST -d'{"message": "123"}' http://localhost:9443/kube-edge-1/default/a

边缘端应用订阅mqttbroker的topic,执行命令

mosquitto_sub -t 'test' -d 

即可接收云端消息:{“message”:“123”}

边缘端通过mqttbroker到云端rest接口

创建rest和eventbus类型ruleEndpoint,执行命令

kubectl create -f ruleEndpoint-rest.yaml
kubectl create -f ruleEndpoint-eventbus.yaml

ruleEndpoint-rest.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1 
kind: RuleEndpoint 

metadata: 
  name: my-rest 
  labels: 
    description: cloud-endpoint 
spec: 
  ruleEndpointType: "rest" 
  properties: {}

ruleEndpoint-eventbus.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1 
kind: RuleEndpoint 

metadata: 
  name: my-eventbus 
  labels: 
    description: edge-endpoint 
spec: 
  ruleEndpointType: "eventbus" 
  properties: {}

创建规则,执行命令:

kubectl create -f rule-eventbus-rest.yaml

rule-eventbus-rest.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1 
kind: Rule 

metadata: 
  name: my-rule-eventbus-rest 
  labels: 
    description: edge-eventbus-cloud-rest 
spec: 
  source: "my-eventbus" 
  sourceResource: {"topic": "test","node_name": "k8s-edge-1"} 
  target: "my-rest" 
  targetResource: {"resource":"http://k8s-master:8080/b"}

边缘端的应用可发布信息到topic,消息将传递到云端应用的rest接口地址。

使用 mosquitto 发布数据,执行命令:

mosquitto_pub -t 'default/test' -d -m '{"edgemsg":"msgtocloud"}'

云端应用的rest接口定义:

方法:POST

URL:目标ruleEndpoint 的 targetResource。

正文:{user_api_body}

一个简单的用go写的httpserver如下,实现了该rest接口:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"

)

func sayReceived(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()           // 解析参数
    bytes, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Fatal(err)
    }
    r.Body.Close()
    fmt.Println(string(bytes));
    fmt.Fprintf(w, "云端收到!")
}

func main() {
    http.HandleFunc("/b", sayReceived)
    err := http.ListenAndServe(":8080", nil)
   if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

云端运行httpserver应用后,在边缘端发送信息,即可在云端收到。

云端rest接口到边缘端rest接口

创建rest 和 servicebus 类型的 ruleEndpoint。执行命令:

kubectl create -f ruleEndpoint-rest.yaml
kubectl create -f ruleEndpoint-servicebus.yaml

ruleEndpoint-rest.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1
kind: RuleEndpoint

metadata:  
  name: my-rest 
  labels:   
    description: cloud-endpoint
spec:  
  ruleEndpointType: "rest" 
  properties: {}

ruleEndpoint-servicebus.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1
kind: RuleEndpoint

metadata:  
  name: my-servicebus 
  labels:   
    description: edge-endpoint
spec:  
  ruleEndpointType: "servicebus" 
  properties: {"service_port":"6666"}

创建规则。执行命令:

kubectl create -f rule-rest-servicebus.yaml

rule-rest-servicebus.yaml 的内容如下:

apiVersion: rules.kubeedge.io/v1
kind: Rule

metadata:  
  name: my-rule-rest-servicebus 
  labels:   
    description: cloud-rest-end-servicebus
spec:  
  source: "my-rest" 
  sourceResource: {"path":"/source"} 
  target: "my-servicebus" 
  targetResource: {"path":"/target"} 

可以在云端调用rest 接口向边缘节点上的servicebus发送消息。

方法:POST/GET/DELETE/PUT

URL:http://{rest_endpoint}/{node_name}/{namespace}/{path}{rest_endpoint}{cloudcore_ip}:9443{node_name} 是 edgenode 的名称,{namespace} 是规则的命名空间。{path} 是 source ruleEndpoint 的 sourceResource。

Body: {user_message}, {user_message} 是用户的消息。

最后,kubeedge 的 servicebus 会调用边缘节点上应用的接口 targetResource,用户的应用程序在边缘节点即可获得 API 的请求。

总结

本文从边缘设备管理和云边自定义消息传递两个方面,介绍了KubeEdge的云边协同机制,可根据实际场景选择使用。另外就是受篇幅所限,本文并未介绍KubeEdge边缘端之间的通信框架EdgeMesh,这个将在后续文章中介绍。

参考资料

  • KubeEdge 文档 - kubedege.io
  • KubeEdge Proposals - github.com
  • Kubeedge 设备添加以及 mapper 管理 - blog.csdn.net
  • KubeEdge 整体介绍 - zhuanlan.zhihu.com

相关文章

KubeSphere 部署向量数据库 Milvus 实战指南
探索 Kubernetes 持久化存储之 Longhorn 初窥门径
征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
那些年在 Terraform 上吃到的糖和踩过的坑
无需 Kubernetes 测试 Kubernetes 网络实现
Kubernetes v1.31 中的移除和主要变更

发布评论