邊緣計算平臺 KubeEdge 雲邊協同機制解析
本文作者:周浩,中國移動雲能力中心軟件研發工程師,專注於雲原生、微服務、算力網絡等領域。
KubeEdge 介紹
KubeEdge 是一個致力於解決邊緣場景問題的開源系統,在 Kubernetes 原生的容器編排和調度能力之上,實現了雲邊協同、計算下沉、海量邊緣設備管理、邊緣自治等能力。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[1]
-
• KubeEdge Proposals - github.com[2]
-
• Kubeedge 設備添加以及 mapper 管理 - blog.csdn.net[3]
-
• KubeEdge 整體介紹 - zhuanlan.zhihu.com[4]
引用鏈接
[1]
KubeEdge 文檔 - kubedege.io: https://kubeedge.io/en/docs
[2]
KubeEdge Proposals - github.com: https://github.com/kubeedge/kubeedge/tree/master/docs/proposals
[3]
Kubeedge 設備添加以及 mapper 管理 - blog.csdn.net: https://blog.csdn.net/qq_33690342/article/details/125226572
[4]
KubeEdge 整體介紹 - zhuanlan.zhihu.com: https://zhuanlan.zhihu.com/p/350335104
雲原生社區動態 雲原生社區是國內最大獨立第三方雲原生終端用戶社區。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/CM5qjHIROHrsLRU_JSxkDw