使用 KubeEdge 和 EdgeMesh 實現邊緣複雜網路場景下的節點通訊

語言: CN / TW / HK

作者:吳波,來自北京的運維工程師,專注於雲原生,KubeSphere 狂熱愛好者。

簡介

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

  • 雲上是統一的控制面,包含原生的 K8s 管理元件,以及 KubeEdge 自研的 CloudCore 元件,負責監聽雲端資源的變化,提供可靠和高效的雲邊訊息同步。

  • 邊側主要是 EdgeCore 元件,包含 Edged、MetaManager、EdgeHub 等模組,通過接收雲端的訊息,負責容器的生命週期管理。

  • 端側主要是 device mapper 和 eventBus,負責端側裝置的接入。

底層邏輯

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

KubeEdge 功能元件

  • Edged [1] : 在邊緣節點上執行並管理容器化應用程式的代理。

  • EdgeHub [2] : Web 套接字客戶端,負責與 Cloud Service 進行互動以進行邊緣計算(例如 KubeEdge 體系結構中的 Edge Controller)。這包括將雲側資源更新同步到邊緣,並將邊緣側主機和裝置狀態變更報告給雲。

  • CloudHub [3] : Web 套接字伺服器,負責在雲端快取資訊、監視變更,並向 EdgeHub 端傳送訊息。

  • EdgeController [4] : kubernetes 的擴充套件控制器,用於管理邊緣節點和 pod 的元資料,以便可以將資料定位到對應的邊緣節點。

  • EventBus [5] : 一個與 MQTT 伺服器(mosquitto)進行互動的 MQTT 客戶端,為其他元件提供釋出和訂閱功能。

  • DeviceTwin [6] : 負責儲存裝置狀態並將裝置狀態同步到雲端。它還為應用程式提供查詢介面。

  • MetaManager [7] : Edged 端和 EdgeHub 端之間的訊息處理器。它還負責將元資料儲存到輕量級資料庫(SQLite)或從輕量級資料庫(SQLite)檢索元資料。

KubeEdge

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

配置雲端(KubeEdge Master 節點)

1、啟用 KubeEdge

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

  1. edgeruntime
    kubeedge
    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 文件 [9] 。為了確保 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 叢集中的容器應用提供與 K8s 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 工作原理

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

核心優勢:

  1. 跨子網邊邊 / 邊雲服務通訊:無論應用部署在雲上,還是在不同子網的邊緣節點,都能夠提供通 K8s Service 一致的使用體驗。

  2. 低時延:通過 UDP 打洞,完成 EdgeMesh-Agent 之間的 P2P 直連,資料通訊無需經過 EdgeMesh-Server 中轉。

  3. 輕量化:內建 DNS Server、EdgeProxy,邊緣側無需依賴 CoreDNS、KubeProxy、CNI 外掛等原生元件。

  4. 非侵入:使用原生 K8s 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" [email protected]
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.
[email protected]'
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
[[email protected] ~]#

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

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

錯誤處理

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% 以內。

引用連結

[1]

Edged: https://kubeedge.io/zh/docs/architecture/edge/edged

[2]

EdgeHub: https://kubeedge.io/zh/docs/architecture/edge/edgehub

[3]

CloudHub: https://kubeedge.io/zh/docs/architecture/cloud/cloudhub

[4]

EdgeController: https://kubeedge.io/zh/docs/architecture/cloud/edge_controller

[5]

EventBus: https://kubeedge.io/zh/docs/architecture/edge/eventbus

[6]

DeviceTwin: https://kubeedge.io/zh/docs/architecture/edge/devicetwin

[7]

MetaManager: https://kubeedge.io/zh/docs/architecture/edge/metamanager

[8]

KubeSphere 官方文件: https://kubesphere.com.cn/docs/v3.3/

[9]

KubeEdge 文件: https://docs.kubeedge.io/zh/docs/advanced/cri/

KubeSphere (https://kubesphere.io)是在 Kubernetes 之上構建的 開源容器平臺 ,提供全棧的 IT 自動化運維的能力,簡化企業的 DevOps 工作流。

KubeSphere 已被  Aqara 智慧家居、愛立信、本來生活、東軟、華雲、新浪、三一重工、華夏銀行、四川航空、國藥集團、微眾銀行、杭州數跑科技、紫金保險、去哪兒網、中通、中國人民銀行、中國銀行、中國人保壽險、中國太平保險、中國移動、中國聯通、中國電信、天翼雲、中移金科、Radore、ZaloPay  等海內外數萬家企業採用。KubeSphere 提供了開發者友好的嚮導式操作介面和豐富的企業級功能,包括  Kubernetes   多雲與多叢集管理、DevOps (CI/CD)、應用生命週期管理、邊緣計算、微服務治理 (Service Mesh)、多租戶管理、可觀測性、儲存與網路管理、GPU support  等功能,幫助企業快速構建一個強大和功能豐富的容器雲平臺。

 :sparkles: GitHub :https://github.com/kubesphere

 :computer: 官網(中國站) :https://kubesphere.com.cn

:man:‍:computer:‍  微信群: 請搜尋新增群助手微訊號  kubesphere

 :link: 企業服務 https://kubespher e.cloud