Mise en oeuvre d’un Service Mesh avec MicroStack, Linkerd 2.x et K3S …

Karim
12 min readSep 23, 2019

--

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 …

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 :

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 :

Et ceci simplement via Snap :

J’en avais parlé dans un ancien article :

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 :

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

$ snap install microstack --edge --classic

avec une initialisation d’OpenStack en quelques minutes :

$ microstack.init

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

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

et ces accès API par défaut :

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

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

avec le déploiement de ZeroTier :

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 :

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

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

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

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

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 -

Le cluster est alors prêt :

Déploiement de MetalLB en se basant sur ZeroTier :

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

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.

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

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 namespace dédié. Ces services accomplissent diverses choses : agrégation des données de télémétrie, fourniture d’API orienté 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 envoyant des signaux de télémesure au plan de contrôle et en recevant des signaux de la part du plan de contrôle.

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

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

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

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 -

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

$ linkerd check$ kubectl -n linkerd get deploy

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

Serveo me retourne l’URL du tableau de bord :

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

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 -

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

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 -

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

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

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

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

$ curl -L https://goo.gl/S1Dc3R | bash -s 20 "http://192.168.191.11"

avec ces changements dans Grafana :

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

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

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

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

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

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

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

ou simplement via htop :

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 :

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 :

A suivre ! …

--

--

Karim
Karim

Written by Karim

Above the clouds, the sky is always blue ...