Aller au texte
ShemolDéployer KubeEdge, EdgeMesh et Sedna
流程记录 / 云原生

Déployer KubeEdge, EdgeMesh et Sedna

Télécharger keadm

Télécharger keadm pour installer KubeEdge. Doc officielle : https://kubeedge.io/docs/setup/install-with-keadm/

(la version anglaise a la partie téléchargement, la chinoise non — un peu déroutant...)

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

Configurer le cloud (nœud master KubeEdge)

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

Il y a aussi un flag --kube-config=/root/.kube/config, mais c’est la valeur par défaut donc je l’ai enlevé. Si le fichier config n’est pas au chemin par défaut, il faut le régler ; tu peux aussi regarder keadm --help.

Si ça ne marche pas, il peut y avoir plein de raisons (c’est douloureux).

Une raison possible : tu n’as pas enlevé le taint du node, donc tu ne peux pas y déployer de services métier. Solution :

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

Une autre : l’image cloudcore n’a pas été pull. Là tu peux revérifier si le proxy configuré pour containerd marche, ou remplacer par une image domestique. J’utilisais 渡渡鸟镜像同步站 ; en cherchant tu verras le cloudcore v1.16.2 que j’avais.

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

Ensuite tu remplaces par l’adresse de l’image domestique.

J’ai aussi eu disk pressure... mais ça devrait être assez rare.

Bref, face à un problème, describe pod/node et lis les logs.

Quand cloudcore tourne normalement, on fait keadm gettoken --kube-config=... pour voir le token, et on prépare le déploiement d’edgecore.

Configurer le edge (nœud worker KubeEdge)

Sur l’appareil edge (containerd et keadm déjà installés) :

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

Si tout ce qui précède est bien fait, en général ça passe. S’il y a un souci, regarde les logs, et cherche beaucoup les issues Github.

Déployer EdgeMesh

C’est là que j’ai le plus foiré, et où j’ai passé le plus de temps. Si ce n’est pas bien déployé, l’exemple de joint inference ne démarrera tout simplement pas.

Doc officielle : https://edgemesh.netlify.app/guide/

Activer l’endpoint Kube-API edge

    1. Activer le module dynamicController côté cloud

Si tu as déployé cloudcore avec la commande ci-dessus, c’est déjà activé, parce que j’ai mis -set cloudCore.modules.dynamicController.enable=true.

    1. Ouvrir le module metaServer côté edge. Après la config, il faut redémarrer edgecore.
yaml
vim /etc/kubeedge/config/edgecore.yaml
modules:
  ...
  edgeMesh:
    enable: false
  ...
  metaManager:
    metaServer:
      enable: true

Redémarrer edgecore

shell
systemctl restart edgecore
    1. Sur le nœud edge, configurer clusterDNS et clusterDomain. Après la config, il faut redémarrer edgecore.
plain text
$ vim /etc/kubeedge/config/edgecore.yaml
modules:
  ...
  edged:
    ...
    tailoredKubeletConfig:
      ...
      clusterDNS:
      - 169.254.96.16
      clusterDomain: cluster.local
...

Fais très gaffe à l’endroit de la config (des larmes, vraiment)...

Ne change pas la valeur de clusterDNS.

Comme le dit la doc, la valeur clusterDNS '169.254.96.16' vient de la valeur par défaut de bridgeDeviceIP dans commonConfig在新窗口打开. En temps normal, pas besoin de la changer ; si tu insistes, garde les deux identiques.

Redémarrer edgecore.

shell
systemctl restart edgecore
    1. Enfin, sur le nœud edge, tester si l’endpoint Kube-API edge marche :
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"}}

Si la réponse est une liste vide, ou si ça met longtemps (près de 10s) à revenir, ta config est probablement fausse. Vérifie bien.

Après ces étapes, l’endpoint Kube-API edge de KubeEdge est activé. Ensuite tu peux continuer à déployer EdgeMesh.

Commencer le déploiement d’EdgeMesh

Suivre les prérequis de la doc : enlever les taints, ajouter un label de filtre.

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

Puis installer EdgeMesh à la main :

  • Cloner EdgeMesh depuis Github
shell
$ git clone <https://github.com/kubeedge/edgemesh.git>
$ cd edgemesh
  • Créer les 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
  • Déployer edgemesh-agent

Il y a une note en dessous : il faut modifier la partie relayNodes de build/agent/resources/04-configmap.yaml, et régénérer le PSK.

Pour relaynode on met en général un nœud cloud comme relais, le master, et l’ip c’est l’ip du master. Le PSK se génère via l’URL dans les commentaires. Pour une manip perso, ne pas le générer ça passe aussi (bushi

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

Le reste, tu le commentes.

Puis déployer 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
  • Vérifier
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

C’est la méthode de check du site officiel, mais je la trouve pas super utile — même en running ça peut ne pas marcher vraiment.

Côté edge tu peux

shell
crictl logs edgemesh的containerID

regarder si les logs sont normaux, ou où ça coince. Si c’est bon, il y a un heartbeat envoyé régulièrement.

Lancer le cas de test EdgeMesh

Fortement recommandé, tu vas trouver plein de problèmes. Quand je demandais de l’aide à des seniors, ils demandaient d’abord si le cas de test passait. J’ai lancé celui avec l’étoile, Cross-Edge-Cloud.

    1. Déployer les pods de test.
shell
$ kubectl apply -f examples/test-pod.yaml
pod/alpine-test created
pod/websocket-test created
    1. Déployer ce qu’il faut pour le test de comms edge–cloud
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

À cette étape de l’expérience j’ai eu le premier problème : le pod qui devait aller sur le edge, namespace edgezone, restait en ContainerCreating. Comme le Pod ne se déployait pas, évidemment pas de logs (crictl logs containerID), pas non plus depuis le cloud (kubectl logs), et kubectl describe pod n’avait zéro info. Donc j’ai fait systemctl status edgecore, et j’ai enfin vu l’erreur (même s’il y a peut-être une meilleure méthode ?). La cause : /run/flannel/subnet.env n’existait pas côté edge. J’ai vu que le cloud l’avait, donc j’ai créé sur le edge un fichier au même contenu. Un petit moment plus tard les pods étaient tous running.

    1. Cloud vers edge
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.

Là je n’ai pas eu de problème.

    1. Edge vers cloud

Le site officiel utilise docker, donc docker ps. Avec crictl, directement

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

Puis j’ai lancé

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

Problème, genre name or server unknow. En fait c’était parce que j’avais mal configuré le Kube-API edge.

Après avoir corrigé la config, cette étape encore : no route to host, comme cette issue. Puis j’ai suivi la question 3 du manuel Q&A EdgeMesh le plus complet cité dans l’issue, nettoyé les règles iptables, redéployé edgemesh, et ça passait ! J’étais trop content.

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.

Là EdgeMesh était vraiment déployé. Je ne sais même pas combien de temps EdgeMesh m’a pris. Mais c’est ce que l’apprentissage demande. Au début je n’avais pas le réflexe des logs, je tentais au pif. Maintenant, premier réflexe : les logs, et ça se règle vite.

Déployer Sedna

Doc officielle : 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 -

Un souci : ce script ne détecte parfois pas le numéro de version, donc surveille ce qu’il affiche. S’il ne le voit pas, interromps l’install, désinstalle Sedna, et réessaie.

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

Si c’est normal, ça tourne. Sinon, il faudra peut-être encore passer sur une image domestique.

Articles de référence