邊緣計算 KubeEdge+EdgeMash

2022-07-13 18:00:32

簡介

KubeEdge是面向邊緣計算場景、專為邊雲協同設計的業界首個雲原生邊緣計算框架,在 Kubernetes 原生的容器編排排程能力之上實現了邊雲之間的應用協同、資源協同、資料協同和裝置協同等能力,完整打通了邊緣計算中雲、邊、裝置協同的場景。其中KubeEdge架構主要包含雲邊端三部分:

  • 雲上是統一的控制面,包含原生的Kubernetes管理元件,以及KubeEdge自研的CloudCore元件,負責監聽雲端資源的變化,提供可靠和高效的雲邊訊息同步。
  • 邊側主要是EdgeCore元件,包含Edged、MetaManager、EdgeHub等模組,通過接收雲端的訊息,負責容器的生命週期管理。
  • 端側主要是device mapper和eventBus,負責端側裝置的接入。

底層邏輯

KubeEdge是Kubernetes在邊緣場景下的延伸。目標是將Kubernetes對容器編排的能力延伸到邊緣上;
KubeEdge主要包含兩個元件,雲端的CloudCore和邊緣節點上EdgeCore,同時還有一個Device模組,用於管理海量的邊緣裝置。

KubeEdge功能元件

  • Edged: 在邊緣節點上執行並管理容器化應用程式的代理。
  • EdgeHub: Web通訊端使用者端,負責與Cloud Service進行互動以進行邊緣計算(例如KubeEdge體系結構中的Edge Controller)。這包括將雲側資源更新同步到邊緣,並將邊緣側主機和裝置狀態變更報告給雲。
  • CloudHub: Web通訊端伺服器,負責在雲端快取資訊、監視變更,並向EdgeHub端傳送訊息。
  • EdgeController: kubernetes的擴充套件控制器,用於管理邊緣節點和pod的後設資料,以便可以將資料定位到對應的邊緣節點。
  • EventBus: 一個與MQTT伺服器(mosquitto)進行互動的MQTT使用者端,為其他元件提供釋出和訂閱功能。
  • DeviceTwin: 負責儲存裝置狀態並將裝置狀態同步到雲端。它還為應用程式提供查詢介面。
  • MetaManager: Edged端和Edgehub端之間的訊息處理器。它還負責將後設資料儲存到輕量級資料庫(SQLite)或從輕量級資料庫(SQLite)檢索後設資料。

KubeEdge

為了更好的支援KubeEdge並提供視覺化介面管理邊緣節點,本檔案使用KubeSphere平臺用來管理邊緣節點,KubeSphere官方檔案

設定雲端(KubeEdge Master節點)

1、啟用KubeEdge

使用admin身份存取KubeSphere控制檯,進入叢集管理,點選客製化資源定義,找到ClusterConfiguration,編輯ks-install

  1. 在該組態檔中找到edgeruntimekubeedge,將enabled的值修改為true
  2. 修改edgeruntime.kubeedge.cloudCore.cloudHub.advertiseAddress的值設定為公網IP地址;

完成後點選右下角的"確定",並檢查ks-installer的紀錄檔檢視部署狀態。

2、設定公網埠轉發

啟動完成後使用如下命令即可看到cloudcore的NodePort埠。

$ kubectl get svc -n kubeedge -l k8s-app=kubeedge
NAME        TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                                                                           AGE
cloudcore   NodePort   10.96.0.106   <none>        10000:30000/TCP,10001:30001/TCP,10002:30002/TCP,10003:30003/TCP,10004:30004/TCP   3m

需要按照下列埠設定公網埠轉發,將10000-10004埠轉發到NodePort的30000-30004埠。

欄位 外網埠 欄位 內網埠
cloudhubPort 10000 cloudhubNodePort 30000
cloudhubQuicPort 10001 cloudhubQuicNodePort 30001
cloudhubHttpsPort 10002 cloudhubHttpsNodePort 30002
cloudstreamPort 10003 cloudstreamNodePort 30003
tunnelPort 10004 tunnelNodePort 30004

如果有云廠商,則需要建立負載均衡按照上述表格的規則進行轉發。
如果沒有云廠商,可以使用如下命令設定iptables規則進行埠轉發:

iptables -t nat -A PREROUTING -p tcp --dport 10000 -j REDIRECT --to-ports 30000
iptables -t nat -A PREROUTING -p tcp --dport 10001 -j REDIRECT --to-ports 30001
iptables -t nat -A PREROUTING -p tcp --dport 10002 -j REDIRECT --to-ports 30002
iptables -t nat -A PREROUTING -p tcp --dport 10003 -j REDIRECT --to-ports 30003
iptables -t nat -A PREROUTING -p tcp --dport 10004 -j REDIRECT --to-ports 30004

3、設定iptables守護行程

部署完成後,發現DaemonSet資源iptables未排程到k8s-master節點上,需要設定容忍master汙點。

$ kubectl get pod -o wide -n kubeedge
NAME                               READY   STATUS    RESTARTS   AGE   IP             NODE           NOMINATED NODE   READINESS GATES
cloud-iptables-manager-q9bsx       1/1     Running   0          28m   172.20.1.12    k8s-node02     <none>           <none>
cloud-iptables-manager-vvpv8       1/1     Running   0          28m   172.20.1.11    k8s-node01     <none>           <none>
cloudcore-54b7f4f699-wcpjc         1/1     Running   0          70m   10.244.0.27    k8s-node02     <none>           <none>
edgeservice-855fdd8f94-8zd8k       1/1     Running   0          53m   10.244.0.42    k8s-node02     <none>           <none>

找到"應用負載"-"工作負載"-"守護行程集",編輯"cloud-iptables-manager"新增如下設定:

kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: cloud-iptables-manager
  namespace: kubeedge
spec:
  template:
    spec:
      ......
      # 新增如下設定
      tolerations:
        - key: node-role.kubernetes.io/master
          operator: Exists
          effect: NoSchedule

注:如果未修改以上設定,則在KubeSphere上無法對邊緣節點的Pod檢視紀錄檔和執行命令。

設定完成後再次檢查iptables守護行程是否已經排程到所有節點

$ kubectl get pod -o wide -n kubeedge
NAME                               READY   STATUS    RESTARTS   AGE   IP             NODE           NOMINATED NODE   READINESS GATES
cloud-iptables-manager-q9bsx       1/1     Running   0          28m   172.20.1.12    k8s-node02     <none>           <none>
cloud-iptables-manager-vvpv8       1/1     Running   0          28m   172.20.1.11    k8s-node01     <none>           <none>
cloud-iptables-manager-zwmdg       1/1     Running   0          29m   172.20.1.10    k8s-master     <none>           <none>
cloudcore-54b7f4f699-wcpjc         1/1     Running   0          70m   10.244.0.27    k8s-node02     <none>           <none>
edgeservice-855fdd8f94-8zd8k       1/1     Running   0          53m   10.244.0.42    k8s-node02     <none>           <none>

設定邊端(KubeEdge Node節點)

新增邊緣節點檔案:https://kubesphere.com.cn/docs/installing-on-linux/cluster-operation/add-edge-nodes/

KubeEdge 支援多種容器執行時,包括 Docker、containerd、CRI-O 和 Virtlet。有關更多資訊,請參見 KubeEdge 檔案
為了確保 KubeSphere 可以獲取 Pod 指標,需要在邊緣端安裝 Docker v19.3.0 或更高版本。

新增邊緣節點

到邊緣端執行KubeSphere上覆制過來的命令

arch=$(uname -m); if [[ $arch != x86_64 ]]; then arch='arm64'; fi;  curl -LO https://kubeedge.pek3b.qingstor.com/bin/v1.9.2/$arch/keadm-v1.9.2-linux-$arch.tar.gz \
 &&  tar xvf keadm-v1.9.2-linux-$arch.tar.gz \
 && chmod +x keadm && ./keadm join --kubeedge-version=1.9.2 --region=zh --cloudcore-ipport=1x.xx.xx.28:10000 --quicport 10001 --certport 10002 --tunnelport 10004 --edgenode-name edge-node-01 --edgenode-ip 192.168.1.63 --token c2d7e72e15d28aa3e2b9340b9429982595b527b334a756be919993f45b7422b1.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTY2NDU5NDJ9.bQeNr4RFca5GByALxVEQbiQpEYTyyWNzpDQVhm39vc8 --with-edge-taint
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 52.3M  100 52.3M    0     0  1020k      0  0:00:52  0:00:52 --:--:-- 1057k
./keadm
install MQTT service successfully.
kubeedge-v1.9.2-linux-amd64.tar.gz checksum:
checksum_kubeedge-v1.9.2-linux-amd64.tar.gz.txt content:
[Run as service] start to download service file for edgecore
[Run as service] success to download service file for edgecore
kubeedge-v1.9.2-linux-amd64/
kubeedge-v1.9.2-linux-amd64/cloud/
kubeedge-v1.9.2-linux-amd64/cloud/cloudcore/
kubeedge-v1.9.2-linux-amd64/cloud/cloudcore/cloudcore
kubeedge-v1.9.2-linux-amd64/cloud/iptablesmanager/
kubeedge-v1.9.2-linux-amd64/cloud/iptablesmanager/iptablesmanager
kubeedge-v1.9.2-linux-amd64/cloud/csidriver/
kubeedge-v1.9.2-linux-amd64/cloud/csidriver/csidriver
kubeedge-v1.9.2-linux-amd64/cloud/admission/
kubeedge-v1.9.2-linux-amd64/cloud/admission/admission
kubeedge-v1.9.2-linux-amd64/edge/
kubeedge-v1.9.2-linux-amd64/edge/edgecore
kubeedge-v1.9.2-linux-amd64/version
 
KubeEdge edgecore is running, For logs visit: journalctl -u edgecore.service -b

檢視邊緣節點是否新增成功

$ kubectl get nodes
NAME           STATUS   ROLES                  AGE   VERSION
edge-node-01   Ready    agent,edge             23h   v1.21.4-kubeedge-v1.9.2
k8s-master     Ready    control-plane,master   16d   v1.21.5
k8s-node01     Ready    <none>                 16d   v1.21.5
k8s-node02     Ready    <none>                 25h   v1.21.5

邊緣節點加入叢集後,部分 Pod 在排程至該邊緣節點上後可能會一直處於 Pending 狀態。由於部分守護行程集(例如,Calico)有強容忍度,您需要使用以下指令碼手動 Patch Pod 以防止它們排程至該邊緣節點。

#!/bin/bash
NodeSelectorPatchJson='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/master": "","node-role.kubernetes.io/worker": ""}}}}}'
 
NoShedulePatchJson='{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"node-role.kubernetes.io/edge","operator":"DoesNotExist"}]}]}}}}}}}'
 
edgenode="edgenode"
if [ $1 ]; then
        edgenode="$1"
fi
 
namespaces=($(kubectl get pods -A -o wide |egrep -i $edgenode | awk '{print $1}' ))
pods=($(kubectl get pods -A -o wide |egrep -i $edgenode | awk '{print $2}' ))
length=${#namespaces[@]}
 
for((i=0;i<$length;i++)); 
do
        ns=${namespaces[$i]}
        pod=${pods[$i]}
        resources=$(kubectl -n $ns describe pod $pod | grep "Controlled By" |awk '{print $3}')
        echo "Patching for ns:"${namespaces[$i]}",resources:"$resources
        kubectl -n $ns patch $resources --type merge --patch "$NoShedulePatchJson"
        sleep 1
done

收集邊緣節點監控資訊

1、在 ClusterConfigurationks-installer 中,將metrics_serverenable改為true

2、到邊緣節點編輯 vim /etc/kubeedge/config/edgecore.yaml 組態檔將edgeStreamenable改為true

edgeStream:
  enable: true
  handshakeTimeout: 30
  readDeadline: 15
  server: 1x.xx.xx.x8:10004
  tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
  tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
  tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key
  writeDeadline: 15

3、重啟systemctl restart edgecore.service

部署到邊緣節點的Pod需要設定容忍汙點

spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: "node-role.kubernetes.io/edge"
    operator: "Exists"
    effect: "NoSchedule"

EdgeMesh

簡介

EdgeMesh的定位是KubeEdge使用者資料面輕量化的通訊元件,完成節點之間網路的Mesh,在邊緣複雜網路拓撲上的節點之間建立P2P通道,
並在此通道上完成邊緣叢集中流量的管理和轉發,最終為使用者KubeEdge叢集中的容器應用提供與Kubernetes Service一致的服務發現與流量轉發體驗。

官網:https://edgemesh.netlify.app/zh/

上圖展示了 EdgeMesh 的簡要架構,EdgeMesh 包含兩個微服務:edgemesh-server 和 edgemesh-agent。

EdgeMesh-Server:

  • EdgeMesh-Server執行在雲上節點,具有一個公網IP,監聽來自EdgeMesh-Agent的連線請求,並協助EdgeMesh-Agent之間完成UDP打洞,建立P2P連線;
  • 在EdgeMesh-Agent之間打洞失敗的情況下,負責中繼EdgeMesh-Agent之間的流量,保證100%的流量中轉成功率。

EdgeMesh-Agent:

  • EdgeMesh-Agent的DNS模組,是內建的輕量級DNS Server,完成Service域名到ClusterIP的轉換。
  • EdgeMesh-Agent的Proxy模組,負責叢集的Service服務發現與ClusterIP的流量劫持。
  • EdgeMesh-Agent的Tunnel模組,在啟動時,會建立與EdgeMesh-Server的長連線,在兩個邊緣節點上的應用需要通訊時,會通過EdgeMesh-Server進行UDP打洞,嘗試建立P2P連線,一旦連線建立成功,後續兩個邊緣節點上的流量不需要經過EdgeMesh-Server的中轉,進而降低網路時延。

EdgeMesh工作原理

雲端是標準的Kubernetes叢集,可以使用任意CNI網路外掛,比如Flannel、Calico,可以部署任意Kubernetes原生元件,比如Kubelet、KubeProxy;
同時雲端部署KubeEdge雲上元件CloudCore,邊緣節點上執行KubeEdge邊緣元件EdgeCore,完成邊緣節點向雲上叢集的註冊。

核心優勢:

  1. 跨子網邊邊/邊雲服務通訊:無論應用部署在雲上,還是在不同子網的邊緣節點,都能夠提供通Kubernetes Service一致的使用體驗。
  2. 低時延:通過UDP打洞,完成EdgeMesh-Agent之間的P2P直連,資料通訊無需經過EdgeMesh-Server中轉。
  3. 輕量化:內建DNS Server、EdgeProxy,邊緣側無需依賴CoreDNS、KubeProxy、CNI外掛等原生元件。
  4. 非侵入:使用原生Kubernetes Service定義,無需自定義CRD,無需自定義欄位,降低使用者使用成本。
  5. 適用性強:不需要邊緣站點具有公網IP,不需要使用者搭建VPN,只需要EdgeMesh-Server部署節點具有公網IP且邊緣節點可以存取公網。

部署EdgeMesh

使用admin身份登入KubeSphere,點選工作臺進入"system-workspace"工作空間,在kubesphere-master叢集專案中找到kubeedge並進入,

在該專案應用負載中建立基於模板的應用,選擇從"應用商店"搜尋找到"edgemesh"並點選安裝,安裝前請確認安裝位置是否正確。

在應用設定中修改如下幾處內容並點選安裝:

server:
  nodeName: "k8s-node01"   # 指定edgemesh-server部署的節點
  advertiseAddress:
    - 1x.xx.xx.x8         # 指定edgemesh-server對外暴漏服務的IP列表(此處填寫的是華為雲ELB的公網IP)
  modules:
    tunnel:
      enable: true
      listenPort: 20004    # 需要將該埠暴漏到公網(無需修改)
agent:
  modules:
    edgeProxy:
      enable: true
      socks5Proxy:
        enable: true       # 開啟SSH隧道代理
        listenPort: 10800

部署完成後需要設定edgemesh-agent的節點容忍,使其能排程到master和edge節點上。

spec:
  template:
    spec:
      # 新增如下內容
      tolerations:
        - key: node-role.kubernetes.io/edge
          operator: Exists
          effect: NoSchedule
        - key: node-role.kubernetes.io/master
          operator: Exists
          effect: NoSchedule

最後檢視部署結果(確保edgemesh-agent在每一個節點都執行了一個pod):

$ kubectl get pod -n kubeedge -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP             NODE           NOMINATED NODE   READINESS GATES
cloud-iptables-manager-q9bsx       1/1     Running   0          16h   172.20.1.12    k8s-node02     <none>           <none>
cloud-iptables-manager-vvpv8       1/1     Running   0          16h   172.20.1.11    k8s-node01     <none>           <none>
cloud-iptables-manager-zwmdg       1/1     Running   0          16h   172.20.1.10    k8s-master     <none>           <none>
cloudcore-54b7f4f699-wcpjc         1/1     Running   0          16h   10.244.0.27    k8s-node02     <none>           <none>
edgemesh-agent-2l25t               1/1     Running   0          15m   172.20.1.12    k8s-node02     <none>           <none>
edgemesh-agent-cd67c               1/1     Running   0          14m   172.20.1.11    k8s-node01     <none>           <none>
edgemesh-agent-jtl9l               1/1     Running   0          14m   192.168.1.63   edge-node-01   <none>           <none>
edgemesh-agent-vdmzc               1/1     Running   0          16m   172.20.1.10    k8s-master     <none>           <none>
edgemesh-server-65b6db88fb-stckp   1/1     Running   0          16h   172.20.1.11    k8s-node01     <none>           <none>
edgeservice-855fdd8f94-8zd8k       1/1     Running   0          16h   10.244.0.42    k8s-node02     <none>           <none>

SSH隧道代理

前提條件

  1. 請確保edgemesh-agent已經開啟了socks5Proxy。
  2. 確保執行k8s-master節點安裝了nc命令,如沒有請執行yum -y install nc進行安裝。
$ kubectl get nodes
NAME           STATUS   ROLES                  AGE   VERSION
edge-node-01   Ready    agent,edge             21h   v1.21.4-kubeedge-v1.9.2
k8s-master     Ready    control-plane,master   16d   v1.21.5
k8s-node01     Ready    <none>                 16d   v1.21.5
k8s-node02     Ready    <none>                 23h   v1.21.5
 
$ ssh -o "ProxyCommand nc --proxy-type socks5 --proxy 169.254.96.16:10800 %h %p" root@edge-node-01
The authenticity of host 'edge-node-01 (<no hostip for proxy command>)' can't be established.
ECDSA key fingerprint is SHA256:alzjCdezpa8WxcW6lZ70x6sZ4J5193wM2naFG7nNmOw.
ECDSA key fingerprint is MD5:56:b7:08:1d:79:65:2e:84:8f:92:2a:d9:48:3a:15:31.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'edge-node-01' (ECDSA) to the list of known hosts.
root@edge-node-01's password:
Last failed login: Fri Jul  1 09:33:11 CST 2022 from 192.168.1.63 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Fri Jul  1 09:25:01 2022 from 192.168.20.168
[root@edge-node-01 ~]#

注:由於節點的 IP 可能重複,所以只支援通過節點名稱進行連線。

在v3.3.0版本中可支援在ks控制檯中登入終端。


錯誤處理:

1、kubeedge和edgemesh的服務都正常且紀錄檔沒有報錯,但是雲和邊無法互相存取。

雲端設定

# 在雲端,開啟 dynamicController 模組,並重啟 cloudcore
$ kubectl edit cm cloudcore -n kubeedge
modules:
  ..
  dynamicController:
    enable: true
..
$ kubectl rollout restart deploy cloudcore -n kubeedge

邊緣端設定

# 開啟 metaServer 模組(如果你的 KubeEdge < 1.8.0,還需關閉 edgeMesh 模組)
vim /etc/kubeedge/config/edgecore.yaml
modules:
  ..
  edgeMesh:
    enable: false
  ..
  metaManager:
    metaServer:
      enable: true
# 設定 clusterDNS 和 clusterDomain
$ vim /etc/kubeedge/config/edgecore.yaml
modules:
  ..
  edged:
    clusterDNS: 169.254.96.16
    clusterDomain: cluster.local
 
# 重啟 edgecore
$ systemctl restart edgecore

驗證

$ curl 127.0.0.1:10550/api/v1/services
{"apiVersion":"v1","items":[{"apiVersion":"v1","kind":"Service","......}

關鍵術語:

  • 輕邊緣:輕邊緣側重各類裝置的解析、資料預處理和前端的推理。
  • 重邊緣:重邊緣產品除了具備輕邊緣的功能之外,還具有更多儲存空間、更高計算力,可以滿足客戶對於資料預處理、資料區域性彙集儲存等等一系列要求,並結合邊緣端實現對於端側也就是邊緣側的資料資源排程和管理。

相關文章:

相關視訊:

相關問題:

Q:安全信怎麼做防護的?
A:EdgeMesh-Server與EdgeMesh-Agent之間都有證書進行加密。

Q:服務之間通訊效率?
A:在500 qps以記憶體取接近於直連網路,網路損耗特別低,打洞成功會有10%左右中繼的消耗。

Q:資源消耗情況?
A:每一個EdgeMesh-Agent佔用記憶體不到40兆,CPU只有1%-5%以內。