文章へ移動
ShemolKubeEdge、EdgeMesh、Sedna のデプロイ
流程记录 / 云原生

KubeEdge、EdgeMesh、Sedna のデプロイ

keadm をダウンロード

KubeEdge を入れるために keadm をダウンロードする。公式ドキュメント: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 の taint を外していないせいで、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 のデプロイ開始

ドキュメントの前提条件どおり、taint を消して、フィルタ用ラベルを付ける。

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

それから手動で EdgeMesh を入れる:

  • Github から EdgeMesh を clone
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 はコメントの URL から生成すればいい。自分で実験するなら生成しなくても実は大丈夫(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 の情報量もゼロ。だから 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 -

正常なら普通に動く。おかしいなら、また国内ミラーに替える必要があるかもしれない。

参考記事