跳至文章
Shemol部署 KubeEdge、EdgeMesh、Sedna
流程记录 / 云原生

部署 KubeEdge、EdgeMesh、Sedna

下載 keadm

下載 keadm 用於安裝 KubeEdge,官方文件:https://kubeedge.io/docs/setup/install-with-keadm/

(英文版裡有下載的部分中文版文件卻沒有,就有點迷惑...)

shell
wget <https://github.com/kubeedge/kubeedge/releases/download/v1.16.2/keadm-v1.16.2-linux-amd64.tar.gz>

tar -zxvf keadm-v1.16.2-linux-amd64.tar.gz
cp keadm-1.16.2-linux-amd64/keadm/keadm /usr/local/bin/keadm

設定雲端(KubeEdge 主節點)

shell
sudo keadm init --advertise-address=主机ip地址 --kubeedge-version=v1.16.2 --set iptablesManager.mode="external" --set cloudCore.modules.dynamicController.enable=true

還有一個配置項其實是 --kube-config=/root/.kube/config,但預設就是這個我就刪掉了,如果 config 檔案不在預設路徑需要設定一下,具體也可以 keadm --help 查看一下。

如果沒有成功,可能有很多很多原因啦(心酸)。

一個原因可能是沒有移除 node 上的汙點,導致 node 上無法部署業務服務,解決方法:

shell
kubectl taint nodes master node-role.kubernetes.io/control-plane:NoSchedule-

還有一個原因可能是 cloudcore 鏡像沒 pull 下來,這個時候可以再檢查一下給 containerd 配置的代理是否生效,或者用國內鏡像來代替,我當時用的是渡渡鳥鏡像同步站,搜尋的話能看到我當時用的 cloudcore v1.16.2 版本。

shell
kubectl edit pod/daemonset/deployment ** -n **

然後替換為國內鏡像的地址就好了。

我還遇到過 disk pressure 的問題...但是這個應該比較少見。

總之遇到問題積極 describe pod/node 查看日誌資訊就好啦。

當 cloudcore 正常執行後,我們就要 keadm gettoken --kube-config=... 查看 token,準備部署 edgecore。

設定邊端(KubeEdge 工作節點)

在邊端裝置上(已經裝好 containerd 和 keadm):

shell
sudo keadm join  --kubeedge-version=1.16.2 --cloudcore-ipport="云端ip地址":10000  --remote-runtime-endpoint=unix:///run/containerd/containerd.sock --cgroupdriver=systemd --token=**

感覺前面如果都做好了一般沒有問題,如果出現問題,記得查看日誌,還要多搜搜 Github 上的 issue。

部署 EdgeMesh

這是我犯錯最多的地方,也是花費時間最多的地方,如果沒有部署好的話,後面聯合推理實例是根本跑不起來的。

官方文件:https://edgemesh.netlify.app/guide/

開啟邊緣 Kube-API 端點功能

  • 1.雲端開啟 dynamicController 模組

如果是用上面的命令部署的 cloudcore,這裡是已經開啟的,因為我加了 -set cloudCore.modules.dynamicController.enable=true。

  • 2.邊緣端打開 metaServer 模組,注意配置完成後,要重啟 edgecore。
yaml
vim /etc/kubeedge/config/edgecore.yaml
modules:
  ...
  edgeMesh:
    enable: false
  ...
  metaManager:
    metaServer:
      enable: true

重啟 edgecore

shell
systemctl restart edgecore
  • 3.在邊緣節點,配置 clusterDNS 和 clusterDomain,配置完成後,需要重啟 edgecore。
plain text
$ vim /etc/kubeedge/config/edgecore.yaml
modules:
  ...
  edged:
    ...
    tailoredKubeletConfig:
      ...
      clusterDNS:
      - 169.254.96.16
      clusterDomain: cluster.local
...

一定要注意配置的位置(都是淚啊)...

clusterDNS 的值不要變。

如同文件裡說的,clusterDNS 設定的值 '169.254.96.16' 來自於 commonConfig在新窗口打開 中 bridgeDeviceIP 的預設值,正常情況下無需修改,非得修改請保持兩者一致。

重啟 edgecore。

shell
systemctl restart edgecore
  • 4.最後,在邊緣節點,測試邊緣 Kube-API 端點功能是否正常:
shell
$ curl 127.0.0.1:10550/api/v1/services
{"apiVersion":"v1","items":[{"apiVersion":"v1","kind":"Service","metadata":{"creationTimestamp":"2021-04-14T06:30:05Z","labels":{"component":"apiserver","provider":"kubernetes"},"name":"kubernetes","namespace":"default","resourceVersion":"147","selfLink":"default/services/kubernetes","uid":"55eeebea-08cf-4d1a-8b04-e85f8ae112a9"},"spec":{"clusterIP":"10.96.0.1","ports":[{"name":"https","port":443,"protocol":"TCP","targetPort":6443}],"sessionAffinity":"None","type":"ClusterIP"},"status":{"loadBalancer":{}}},{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"prometheus.io/port":"9153","prometheus.io/scrape":"true"},"creationTimestamp":"2021-04-14T06:30:07Z","labels":{"k8s-app":"kube-dns","kubernetes.io/cluster-service":"true","kubernetes.io/name":"KubeDNS"},"name":"kube-dns","namespace":"kube-system","resourceVersion":"203","selfLink":"kube-system/services/kube-dns","uid":"c221ac20-cbfa-406b-812a-c44b9d82d6dc"},"spec":{"clusterIP":"10.96.0.10","ports":[{"name":"dns","port":53,"protocol":"UDP","targetPort":53},{"name":"dns-tcp","port":53,"protocol":"TCP","targetPort":53},{"name":"metrics","port":9153,"protocol":"TCP","targetPort":9153}],"selector":{"k8s-app":"kube-dns"},"sessionAffinity":"None","type":"ClusterIP"},"status":{"loadBalancer":{}}}],"kind":"ServiceList","metadata":{"resourceVersion":"377360","selfLink":"/api/v1/services"}}

如果回傳值是空列表,或者回應時長很久(接近 10s)才拿到回傳值,說明你的配置可能有誤,請仔細檢查。

完成上述步驟之後,KubeEdge 的邊緣 Kube-API 端點功能就已經開啟了,接著繼續部署 EdgeMesh 即可。

開始部署 EdgeMesh

按照文件中先決條件清除一下汙點,新增過濾標籤。

shell
$ kubectl taint nodes --all node-role.kubernetes.io/master-
$ kubectl label services kubernetes service.edgemesh.kubeedge.io/service-proxy-name=""

然後手動安裝 EdgeMesh:

  • 從 Github 上 clone 下 EdgeMesh
shell
$ git clone <https://github.com/kubeedge/edgemesh.git>
$ cd edgemesh
  • 建立 CRD
plain text
$ kubectl apply -f build/crds/istio/
customresourcedefinition.apiextensions.k8s.io/destinationrules.networking.istio.io created
customresourcedefinition.apiextensions.k8s.io/gateways.networking.istio.io created
customresourcedefinition.apiextensions.k8s.io/virtualservices.networking.istio.io created
  • 部署 edgemesh-agent

在下面有一個提示,需要修改 build/agent/resources/04-configmap.yaml 檔案中 relayNodes 部分,並重新生成 PSK 密碼。

relaynode 一般就配一個雲上的節點作為中繼,用 master,ip 就是 master 節點 ip。PSK 根據註釋中的網址生成一下就可以,不過自己做實驗的話其實不生成也行(bushi

yaml
relayNodes:
- nodeName: cloud #master的名字
  advertiseAddress:
  - *.*.*.*  #master的ip

後面的註釋掉就好了。

然後部署 edgemesh-agent

plain text
$ kubectl apply -f build/agent/resources/
serviceaccount/edgemesh-agent created
clusterrole.rbac.authorization.k8s.io/edgemesh-agent created
clusterrolebinding.rbac.authorization.k8s.io/edgemesh-agent created
configmap/edgemesh-agent-cfg created
configmap/edgemesh-agent-psk created
daemonset.apps/edgemesh-agent created
  • 檢查一下
shell
$ kubectl get all -n kubeedge -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
pod/edgemesh-agent-7gf7g   1/1     Running   0          39s   192.168.0.71    k8s-node1    <none>           <none>
pod/edgemesh-agent-fwf86   1/1     Running   0          39s   192.168.0.229   k8s-master   <none>           <none>
pod/edgemesh-agent-twm6m   1/1     Running   0          39s   192.168.5.121   ke-edge2     <none>           <none>
pod/edgemesh-agent-xwxlp   1/1     Running   0          39s   192.168.5.187   ke-edge1     <none>           <none>

NAME                            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE   CONTAINERS       IMAGES                           SELECTOR
daemonset.apps/edgemesh-agent   4         4         4       4            4           <none>          39s   edgemesh-agent   kubeedge/edgemesh-agent:latest   k8s-app=kubeedge,kubeedge=edgemesh-agent

這是官網的檢查方法,但感覺沒太大用處,就算是 running 也有可能不能正常工作的。

可以在邊端

shell
crictl logs edgemesh的containerID

檢查一下,看看日誌是不是正常的,或者卡在了哪個地方,如果是正常的會有 heartbeat 定期發送。

執行 EdgeMesh 測試案例

牆裂推薦跑一下,能發現很多問題。向前輩求助,前輩也都會先問測試案例有沒有跑通。我跑了帶星號的那個跨邊雲通訊測試(Cross-Edge-Cloud)。

  • 1.部署測試 pod。
shell
$ kubectl apply -f examples/test-pod.yaml
pod/alpine-test created
pod/websocket-test created
  • 2.部署邊雲通訊測試需要的
shell
$ kubectl apply -f examples/cloudzone.yaml
namespace/cloudzone created
deployment.apps/tcp-echo-cloud created
service/tcp-echo-cloud-svc created
deployment.apps/busybox-sleep-cloud created
shell
$ kubectl apply -f examples/edgezone.yaml
namespace/edgezone created
deployment.apps/tcp-echo-edge created
service/tcp-echo-edge-svc created
deployment.apps/busybox-sleep-edge created

當時實驗進行到這一步的時候我遇到了第一個問題,應該被部署到邊端,namespace 為 edgezone 的 pod 一直處於 ContainerCreating 狀態,因為 Pod 沒辦法被部署上,自然沒辦法查看日誌(crictl logs containerID),又沒辦法從雲端查看(kubectl logs),kubectl describe pod 資訊量又為 0,所以我就 systemctl status edgecore,終於看到了相關報錯資訊(雖然好像有更好的方法?),原因是邊端 /run/flannel/subnet.env 檔案不存在,我看了一下雲端有,於是就在邊端創造了一份和雲端內容相同的檔案,過了一小會 pod 都顯示為 running 狀態。

  • 3.雲訪問邊
plain text
$ BUSYBOX_POD=$(kubectl get all -n cloudzone | grep pod/busybox | awk '{print $1}')
$ kubectl -n cloudzone exec $BUSYBOX_POD -c busybox -i -t -- sh
$ telnet tcp-echo-edge-svc.edgezone 2701
Welcome, you are connected to node ke-edge1.
Running on Pod tcp-echo-edge.
In namespace edgezone.
With IP address 172.17.0.2.
Service default.
Hello Edge, I am Cloud.
Hello Edge, I am Cloud.

我是沒有遇到問題的。

  • 4.邊訪問雲

官網用的是 docker,所以用了 docker ps,用 crictl 就直接

shell
crictl ps
# 找到busybox的containerID,然后
crictl exec -it containerID sh

然後我執行

plain text
$ telnet tcp-echo-cloud-svc.cloudzone 2701

出現了問題,大概是 name or server unknow,這個其實是因為我不小心把邊緣 Kube-API 給配置錯了導致的。

然後我配置正確之後,再進行這一步,又出現了問題,顯示 no route to host,和這個 issue 問題一樣, 然後我按照 issue 裡說的全網最全 EdgeMesh Q&A 手冊問題三,清理 iptables 規則,然後重新部署 edgemesh,發現就可以跑通了!太激動了當時。

plain text
$ telnet tcp-echo-cloud-svc.cloudzone 2701
Welcome, you are connected to node k8s-master.
Running on Pod tcp-echo-cloud.
In namespace cloudzone.
With IP address 10.244.0.8.
Service default.
Hello Cloud, I am Edge.
Hello Cloud, I am Edge.

到這裡 EdgeMesh 就算真正部署成功了。不知道因為 EdgeMesh 我花費了多少時間。不過其實都是學習必須要經歷。自己一開始沒有看日誌的意識,自己瞎嘗試解決問題,現在慢慢出問題第一反應找日誌,然後就可以快速解決問題。

部署 Sedna

官方文件:https://sedna.readthedocs.io/en/latest/setup/install.html

shell
curl <https://raw.githubusercontent.com/kubeedge/sedna/main/scripts/installation/install.sh> | SEDNA_ACTION=create bash -

有一個問題是,這個腳本有時候識別不出來版本號,所以要留意一下它輸出的資訊,如果沒有識別出版本號,中斷安裝過程,卸載 Sedna,然後再試一下。

shell
# 卸载的命令
curl <https://raw.githubusercontent.com/kubeedge/sedna/main/scripts/installation/install.sh> | SEDNA_ACTION=create bash -

然後正常的話就正常執行啦,不正常的話有可能還是需要換成國內鏡像。

參考文章