Mise en oeuvre d’un Service Mesh avec MicroStack, Linkerd 2.x et K3S …
Tags: kubernetes, servicemesh, docker, openstack
Published: 2019-09-23 02:05:53

---
title: Mise en oeuvre d’un Service Mesh avec MicroStack, Linkerd 2.x et K3S …
published: true
tags: kubernetes,service-mesh,docker,openstack
canonical_url: https://medium.com/@abenahmed1/mise-en-oeuvre-dun-service-mesh-avec-microstack-linkerd-2-x-et-k3s-23242310246c
---


![](https://cdn-images-1.medium.com/max/1024/1*UIEQQ3sVLuFy6bK8uHeV2A.jpeg)

Canonical a récemment publié un article intéressant intitulé “Non, Kubernetes n’est pas le nouvel OpenStack” (dont on peut comprendre les préoccupations commerciales sous-jacentes) pour souligner le fait que le principal facteur qui distingue OpenStack de Kubernetes est :

- qu’OpenStack a été conçu essentiellement comme une solution permettant de créer des infrastructures multi-tenants
- alors que Kubernetes est conçu pour la gestion des services …

[No, Kubernetes is Not the New OpenStack, Says Canonical - Container Journal](https://containerjournal.com/topics/container-ecosystems/no-kubernetes-is-not-the-new-openstack-says-canonical/)

Ils existent pour certaines pratiques visant à la mise en oeuvre du “multi-tenant” dans un cluster Kubernetes via l’isolation au niveau des noeuds ou des namespaces par exemple :

- [Multi-tenancy in kubernetes cluster](https://dev.to/ankitbansal/multi-tenancy-in-kubernetes-cluster-44me)
- [Cluster multi-tenancy | Kubernetes Engine Documentation | Google Cloud](https://cloud.google.com/kubernetes-engine/docs/concepts/multitenancy-overview)

![](https://cdn-images-1.medium.com/max/1024/1*vy1W8SYa2TgJ6WG8deHKgw.jpeg)

Quoiqu’il en soit, je profite de la première mouture de MicroStack en version Stein (toujours en Edge) pour initier un service Mesh avec Linkerd. Pour rappel, MicroStack est une version d’OpenStack destinée à être déployée sur un station de travail, dans un contexte d’Edge Computing et d’IoT par exemple :

- [microstack](https://opendev.org/x/microstack)
- [MicroStack - OpenStack in a snap](https://microstack.run/)

![](https://cdn-images-1.medium.com/max/1024/1*L_x0G69OxcLHaE0fkuIwmg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*SBAnLJ1ZH3Se9u9sMwxGSQ.jpeg)

Et ceci simplement via Snap :

![](https://cdn-images-1.medium.com/max/1024/1*NvDLgKvParMvxBRQ35jLwQ.jpeg)

J’en avais parlé dans un ancien article :

[Un cluster OpenStack sur sa station en une minute avec Microstack …](https://medium.com/@abenahmed1/un-cluster-openstack-sur-sa-station-en-une-minute-avec-microstack-8da478196299)

Je pars donc pour cette expérience d’une instance Bare Metal de type C2M (16 Go RAM et 100 Go pour le disque) chez Scaleway sous Ubuntu 18.04 LTS :

![](https://cdn-images-1.medium.com/max/1024/1*4Q7rGBJ8u3Fh5CDXR7J2sg.jpeg)

L’installation de MicroStack en version Stein est réalisée avec Snap :

[Install microstack on your Linux distribution](https://snapcraft.io/microstack)

```
$ snap install microstack --edge --classic
```

![](https://cdn-images-1.medium.com/max/1024/1*U0OKlLZdZDwdUFBn-Nnp6g.jpeg)

avec une initialisation d’OpenStack en quelques minutes :

```
$ microstack.init
```

![](https://cdn-images-1.medium.com/max/1024/1*MkfT0_xlJyXQvNNxvkfg_g.jpeg)

Via une redirection de port sous SSH, je me connecte au dashboard Horizon (_admin/keystone_ par défaut pour les identifiants) :

[SSH Tunneling - Local, Remote & Dynamic](https://dev.to/__namc/ssh-tunneling---local-remote--dynamic-34fa)

![](https://cdn-images-1.medium.com/max/1024/1*44wCWqwPZceFkSZ7mPd2cQ.png)

![](https://cdn-images-1.medium.com/max/1024/1*67HBtlLwOSwzAuqaskTsfw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*33YB_jzUzo98dyVEA7V7DQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*hxCw5EoLrCDAthJgiBSXoA.jpeg)

J‘ai un routeur avec deux réseaux par défaut (public et privé) :

![](https://cdn-images-1.medium.com/max/1024/1*4fF-GJ2zUQcIwonTEN5Fdg.jpeg)

et ces accès API par défaut :

![](https://cdn-images-1.medium.com/max/1024/1*mcyCIfXH_qXRe3tDEqEKOA.jpeg)

Je peux charger une image Ubuntu 18.04 avec Glance qui va me servir à la constitution d’un cluster avec K3S :

```
$ microstack.openstack image create Ubuntu-18.04-LTS --disk-format qcow2 --container-format bare \
 --public --file ./bionic-server-cloudimg-amd64.img
```

![](https://cdn-images-1.medium.com/max/1024/1*qTABczqSHOcjsxDbLwfzfg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*tMMA99Mvq43hIBfn0ydO-g.jpeg)

Je lance 3 instances Ubuntu en utilisant le réseau privé par défaut (sans besoin du réseau public fourni) via le dashboard :

![](https://cdn-images-1.medium.com/max/1024/1*J2DMwMu_u77AOC2ftQzPhw.jpeg)

avec le déploiement de ZeroTier :

![](https://cdn-images-1.medium.com/max/1024/1*zDw3JssXqd7jvAad9zMc8g.jpeg)

J’ai au final mes trois instances qui sont accessibles via les adresses IP fournies dans ZeroTier et la paire de clé SSH que j’ai préalablement chargée via le dashboard Horizon :

![](https://cdn-images-1.medium.com/max/1024/1*LFzTbpi2xqgjQsBfAUleUg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*zj9ptNhAmK58nn42lEjRsg.jpeg)

J’ai activé la fonction “Ethernet Bridging” pour chacune de ces instances dans ZeroTier en prévision de l’utilisation de MetalLB :

![](https://cdn-images-1.medium.com/max/601/1*G-x9ba5zFWm8V0O-tj9jrg.jpeg)

Je peux initialiser mon cluster Kubernetes avec K3S en utilisant sa dernière version (v0.9.0) :

[rancher/k3s](https://github.com/rancher/k3s/releases)

![](https://cdn-images-1.medium.com/max/1022/1*v1slwdlcaUGds74QnLbC5g.jpeg)

avec ce petit script maintenant bien connu pour le noeud maître :

```
$ curl -sfL https://get.k3s.io | sh -
```

![](https://cdn-images-1.medium.com/max/1024/1*zUd4Dr91X8cfMRphmcYoQA.jpeg)

Je relie mes deux noeuds Worker via ce script :

```
$ curl -sfL https://get.k3s.io | K3S\_URL=https://192.168.191.38:6443 K3S\_TOKEN=XXX sh -
```

![](https://cdn-images-1.medium.com/max/1024/1*B2jn5jkQ-pztrJycEvF9jw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*QV36bgqFLSxFJNJ-Vx6_QA.jpeg)

Le cluster est alors prêt :

![](https://cdn-images-1.medium.com/max/1024/1*etIUME2cxtec8wS2vyN1Vw.jpeg)

Déploiement de MetalLB en se basant sur ZeroTier :

```
$ kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.1/manifests/metallb.yaml
```

![](https://cdn-images-1.medium.com/max/1024/1*8NnrFL1WJE7zlKBsKX010g.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*sPAaO4VvgwUhEZZt27xA-w.jpeg)

avec ce segment d’adresses IP en DHCP :

```
kubectl apply -f l2.yaml
```

![](https://cdn-images-1.medium.com/max/892/1*j8B9oQGAYuVwIfDJk1evyw.png)

Tout est prêt pour le déploiement d’un Service Mesh avec Linkerd 2.X.

> Un Service Mesh est un moyen de contrôler la façon dont différents éléments d’une application partagent des données les uns avec les autres. Contrairement à d’autres systèmes de gestion des communications, un Service Mesh est une couche d’infrastructure dédiée, créée directement dans l’application. Cette couche d’infrastructure visible peut indiquer la manière dont les différents éléments d’une application interagissent entre eux. Il devient dès lors plus facile d’optimiser les communications et d’éviter les temps d’arrêt lorsque l’application évolue. Linkerd a été créé par les co-fondateurs de Buoyant, William Morgan et Oliver Gould, en 2015. S’appuyant sur Finagle (le système RPC extensible pour la JVM développé sur Twitter), Linkerd est utilisé pour construire des applications basées sur les microservices, polyglottes et pour des cas d’utilisation simultanée à plusieurs endroits comme c’est le cas chez Expedia, Monzo, Salesforce ou PayPal.

- [Homepage](https://linkerd.io/)
- [Buoyant's Conduit Service Mesh Officially Becomes Linkerd 2](https://www.infoq.com/news/2018/07/conduit-merges-linkerd2/)

Le code de Linkerd 2.x (qui fait suite à la dernière version de Conduit) est entièrement open source et disponible sur leur dépôt github :

[linkerd/linkerd2](https://github.com/linkerd/linkerd2)

> Linkerd est l’un des nombreux outils extrêmement populaires dédié au “Service Mesh” (avec Istio / Envoy, Cilium ou Consul Connect).

![](https://cdn-images-1.medium.com/max/373/0*AFv7nzXv9k-7hP_b.jpg)

Linkerd se compose d’un plan de contrôle et d’un plan de données :

- Le plan de contrôle est un ensemble de services qui s’exécutent dans un espace de noms dédié. Ces services accomplissent diverses choses : agrégation des données de télémétrie, fourniture d’une API orientée utilisateur, fourniture de données de contrôle aux proxies du plan de données, etc. Ensemble, ils déterminent le comportement du plan de données.
- Le plan de données est constitué de proxies transparents qui sont exécutés à côté de chaque instance de service. Ces proxies gèrent automatiquement tout le trafic à destination et en provenance du service. Parce qu’ils sont transparents, ces proxies agissent comme des piles réseau hors processus hautement instrumentées, envoyant des signaux de télémesure au plan de contrôle et en recevant des signaux de contrôle du plan de contrôle.

[Architecture](https://linkerd.io/2/reference/architecture/)

![](https://cdn-images-1.medium.com/max/1024/0*SB3VmlGg5lBxMR7M.png)

Et cela passe comme on va le voir avec l’utilisation conjointe de Prometheus et Grafana :

![](https://cdn-images-1.medium.com/max/1024/1*Hux4yDhIqb5sgX6JBbQL6w.jpeg)

Je récupère l’interface en ligne de commande (CLI) qui va interagir avec Linkerd, y compris au niveau de l’installation du plan de contrôle sur le cluster Kubernetes :

```
$ curl -sL https://run.linkerd.io/install | sh
```

![](https://cdn-images-1.medium.com/max/1024/1*dT9RNT7kFIKL0opURycmNw.jpeg)

Je vérifie que le binaire _linkerd_ est installé et fonctionne correctement :

```
$ export PATH=$PATH:$HOME/.linkerd2/bin

$ linkerd version
```

et que le cluster Kubernetes est configuré correctement afin d’installer le plan de contrôle de Linkerd :

```
$ linkerd check --pre
```

![](https://cdn-images-1.medium.com/max/1024/1*R4uLPA0b7sO57D7DWpsipw.png)

Il est temps d’installer le plan de contrôle dans son propre namespace (nommé par défaut, linkerd) : la commande _linkerd install_ génère un manifest Kubernetes avec toutes les ressources nécessaires au plan de contrôle …

```
$ linkerd install | kubectl apply -f -
```

![](https://cdn-images-1.medium.com/max/1024/1*8m_PQkD9Jk4RoNic72ulWA.png)

Je vérifie que le déploiement s’est bien déroulé :

```
$ linkerd check

$ kubectl -n linkerd get deploy
```

![](https://cdn-images-1.medium.com/max/1024/1*nqHTqM0hX3sRnEqjcLdZ7Q.png)

Avec le plan de contrôle installé et en cours d’exécution, on peut acceder au tableau de bord présent avec Linkerd via cette commande et Serveo :

```
$ linkerd dashboard &

$ ssh -R linkerd:80:localhost:50750 serveo.net
```

![](https://cdn-images-1.medium.com/max/1024/1*qywBZMRcgNfvuvJETe09Ow.jpeg)

Serveo me retourne l’URL du tableau de bord :

![](https://cdn-images-1.medium.com/max/1024/1*b8RfBrJxQw4UV8j0ahpx7w.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*DFHbGozx4ouum6A1CTC7LQ.jpeg)

On peut déjà observer le trafic que l’on génère en regardant le tableau de bord lui-même !

```
$ linkerd -n linkerd top deploy/linkerd-web
```

![](https://cdn-images-1.medium.com/max/1024/1*1DzMmuEu4gZ1vbFpZuy6BQ.jpeg)

![](https://cdn-images-1.medium.com/max/927/1*7FAhlZyVzCzWPcOC2bjbbw.jpeg)

Pour avoir une idée de la façon dont Linkerd fonctionne, j’installe l’application autonome “emojivoto” pour Kubernetes qui utilise un mélange d’appels gRPC et HTTP pour permettre aux utilisateurs de voter sur leurs émojis favoris via cette commande :

```
$ curl -sL https://run.linkerd.io/emojivoto.yml \
 | kubectl apply -f -
```

![](https://cdn-images-1.medium.com/max/1024/1*6TWW8mJBltISCYOlVh3ejQ.png)

MetalLB me retourne une adresse IP du segment configuré auparavant pour accéder à cette application :

![](https://cdn-images-1.medium.com/max/1024/1*AZto7U0jCYrcG-Fu13NslA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*MY--ZVz8zN7LlVBi2TcR4Q.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*PPWFjZt1fHms3k1jMymLMw.jpeg)

J’ajoute Linkerd à cette application emojivoto. Ceci par l’exécution d’une commande qui récupère tous les déploiements en cours dans le namespace emojivoto, exécute le manifeste par _linkerd inject_, puis l’applique de nouveau au cluster. La commande _linkerd inject_ ajoute des annotations à la spécification du pod en demandant à Linkerd d’ajouter (“injecter”) le proxy du plan de données :

```
$ kubectl get -n emojivoto deploy -o yaml \
 | linkerd inject - \
 | kubectl apply -f -
```

![](https://cdn-images-1.medium.com/max/1024/1*VHsRhjG7sqpf3ycUyIfjmw.png)

L’application Emojivoto est visualisable sur le tableau de bord de Linkerd :

![](https://cdn-images-1.medium.com/max/1024/1*o1AwY2c0ZsnWQRKlk4VaiA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*awRNiIsq75Jo7x4Kb1C8lw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*h_YG0TQbJGaiN7Hi2u26qg.jpeg)

Puisque cette application de démonstration est livrée avec un générateur de charge, ont peut voir les mesures de trafic en temps réel avec ces commandes :

```
$ linkerd -n emojivoto stat deploy

$ linkerd -n emojivoto top deploy

$ linkerd -n emojivoto check --proxy
```

![](https://cdn-images-1.medium.com/max/1024/1*YtzrS1bwPHgManFRlBZk5A.png)

ou directement via les tableaux de bord fournis dans Grafana (avec en backend Prometheus) :

![](https://cdn-images-1.medium.com/max/1024/1*uyLWFeJ1O3nk-EmsE5KKtw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*DcNVVC_u06JkLChK-KKU0A.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*HI7EvJUBF-4ERxHB5VvMjg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*JbzwP1ykWMN3i3CCqQ1T_A.jpeg)

Je génére de la charge sur la page web de l’application (avec 20 appels par seconde) via ce script :

[Simple load testing script (in bash)](https://medium.com/@bigomega/simple-load-testing-script-in-bash-a8c5a4968dc7)

```
$ curl -L [https://goo.gl/S1Dc3R](https://goo.gl/S1Dc3R) | bash -s 20 "[http://](http://api.myserver.com/get_info)192.168.191.11"
```

![](https://cdn-images-1.medium.com/max/1024/1*CwU1D3uCf4EiuqLuqwJOAA.jpeg)

avec ces changements dans Grafana :

![](https://cdn-images-1.medium.com/max/1024/1*CEyrPUfkvVdE2w9ZU6-aJg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*YL_nGXikC8hwDWwt0SZj-w.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*nrbF_gZnp8qAPyz3ThG9jA.jpeg)

Je recommence l’opération avec le traditionnel démonstrateur FC (ici composée d’une seul brique) :

![](https://cdn-images-1.medium.com/max/1024/1*hj9SoEJQsdAo4Eyp1gZcnA.png)

![](https://cdn-images-1.medium.com/max/1024/1*2R5U89YTh0m-r4UPS4jYbA.jpeg)

J’ai une adresse IP retournée par MetalLB pour le démonstrateur FC :

![](https://cdn-images-1.medium.com/max/1024/1*zM6K1h39crmvdg4ICVJxuA.jpeg)

Avec _linkerd inject_, le démonstrateur FC est traçable dans le tableau de bord de Linkerd :

![](https://cdn-images-1.medium.com/max/1024/1*0j3wUHwCmPiTgXYGx8fU8Q.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*pnOUl6cskIPHlSWhuiDqWg.jpeg)

Je réutilise le script générateur de charge (avec ici 30 appels par seconde) vers l’adresse IP du démonstrateur FC :

![](https://cdn-images-1.medium.com/max/1024/1*Brm8SnqYAhn4gmWDyfz7Dw.jpeg)

et obtention de métriques en temps-réel :

![](https://cdn-images-1.medium.com/max/1024/1*j9FM-iYVJQ73Fhp4cFoNVA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*wqPmA0CwU-J7sk70dSGefg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*oKI8k6yvQ_5BRqUPjLtlKA.jpeg)

Pour suivre l’état de MicroStack, j’utilise ici Dynatrace OneAgent :

![](https://cdn-images-1.medium.com/max/1024/1*pvSZ9PwoRIVN4pyB0V26Yw.jpeg)

[Dynatrace OneAgent | Dynatrace Help](https://www.dynatrace.com/support/help/setup-and-configuration/dynatrace-oneagent/)

![](https://cdn-images-1.medium.com/max/1024/1*kFXRumxsauE7v4OFq9fBWQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*zfACUI0mNzhzsdFzzlrrfQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*la1iZkK9M8SgpnoblTnWdA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*yWL0O_db0-mOcjdXERpRSQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*vzSs-ZUxO9TpgEWeVeBGPw.jpeg)

avec un focus sur le noeud maître du cluster K3S :

![](https://cdn-images-1.medium.com/max/1024/1*Pxt7OBJWlzZpqCwk6IU3vw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*ThgSP20x3ElNFW7PjokVOg.jpeg)

ou simplement via _htop_ :

![](https://cdn-images-1.medium.com/max/1024/1*1p7_zWWb09CCmOyv9T5seA.jpeg)

Un exemple de Service Mesh avec K3S dans MicroStack mais qui dans le contexte de montée en puissance de l’Edge Computing, aurait pû être mené en utilisant par exemple le projet StarlingX :

- [Home | StarlingX](https://www.starlingx.io/)
- [OpenDev: Free Software Needs Free Tools](https://opendev.org/starlingx)

![](https://cdn-images-1.medium.com/max/1024/0*YYFm0AvINuk2d1BP.jpg)

qui pourrait être déployé sur une seule instance Bare Metal avec les trois fonctions (contrôleur, calcul et stockage le tout en lien avec des services IoT) même si en backend on retrouve déjà un cluster Kubernetes sur lequel sera déployé les briques OpenStack containerisées :

[StarlingX Docs: Bare metal All-in-one Simplex R2.0](https://docs.starlingx.io/deploy_install_guides/current/bare_metal_aio_simplex.html)

![](https://cdn-images-1.medium.com/max/1024/0*9aNLmKbLf_Nnlz6q.png)

[StarlingX Docs: Install OpenStack](https://docs.starlingx.io/deploy_install_guides/current/install_openstack.html)

A suivre ! …

![](https://cdn-images-1.medium.com/max/600/1*mWOvluriTSoefsPohLO8uQ.jpeg)