VT2021 Kind fiche

KiND est une solution pour déployer des clusters Kubernetes(K8S) localement pour simplifier les processus de développement et de test.



= Présentation de KiND =

GITTON Antoine - antoine.gitton@etu.univ-grenoble-alpes.fr

MINIER MANCINI Titouan - titouan.minier-mancini@etu.univ-grenoble-alpes.fr

Résumé
Kind est un outil permettant le déploiement de clusters Kubernetes dans un environnement local, en utilisant directement des conteneurs Docker en tant que machine du cluster. Cet outil a été créé avec comme but principal de tester Kubernetes lui-même, mais il est maintenant très utilisé pour obtenir un cycle de développement et de tests end-to-end plus rapide, ainsi qu’une facilité de mise en place de CI (Continuous Integration). Dans un premier temps nous allons présenter l’architecture haut niveau de cette solution, pour ensuite discuter ses avantages et inconvénients, que l’on peut comparer à des concurrents comme Minikube.

Mot clés: Docker, Kubernetes, Conteneurs, Systèmes distribués, tests E2E

Abstract
Kind is a tool that enables running Kubernetes clusters in a local environment, using Docker containers as the nodes of the cluster. This tool was initially created with the main purpose of testing Kubernetes itself, but it is nowadays widely used to perform end-to-end testing and develop more efficiently, as well as ease the implementation of CI (Continuous Integration). In the first part, we will present the high level concepts of Kind architecture, then we will discuss pros and cons of such a solution in comparison with close concurrents like Minikube.

Keywords: Docker, Kubernetes, Containers, Distributed systems, E2E testing

Mettre son infrastructure en bouteille
Kubernetes est un outil qui a pour objectif de partager des machines (noeud ou node) connectées en réseau entre plusieurs applications. Il permet d’automatiser le déploiement et la maintenance d’infrastructures décrites au travers de fichiers spécifiques (manifestes, yaml) par les ingénieurs. Ces infrastructures, nécessitant habituellement beaucoup de ressources (puissance de calcul, mémoire vive et stockage), sont la plupart du temps complexes. De ce fait, il est difficile de les tester dans un environnement réaliste (qui se rapproche de l'environnement de production) localement, donc sur une seule machine qui est limitée en termes de ressources.

C’est sur ce point que Kind propose une solution intéressante, car il permet de créer virtuellement des clusters qui peuvent imiter potentiellement tout cluster réel. On entend par là notamment la capacité de déployer des clusters multi-noeuds en n’utilisant fondamentalement qu’une seule machine physique. C’est de là que vient l’image de mettre son cluster Kubernetes en bouteille, environnement à échelle réduite qu’il est facile à manœuvrer.

Il simplifie alors le processus de test, puisqu’il donne accès à un environnement réaliste, mais qui reste local et donc plus léger et simple à manoeuvrer pour le testeur. Au delà du test, Kind donne accès à un environnement favorable au développement. Il est tout à fait compatible avec des solutions de développement pour Kubernetes, telles que Skaffold.



Architecture haut niveau
Kind, en tant que solution, incorpore différents composants. Il y a notamment la Command Line Interface (CLI) qui permet d'interagir avec le cluster, et l’image Docker du node. Cette image est le cœur du fonctionnement de Kind puisqu’elle fournit cet environnement dans lequel peut s'exécuter le cluster Kubernetes.

Cette image contient trois couches. La couche centrale est l’image de Ubuntu 21.10. Par dessus celle-ci il y a la couche de base implémentée par Kind pour fournir un environnement qui respecte l’API CRI. CRI (Container Runtime Interface) est une API définie par Kubernetes pour que le Kubelet du nœud puisse communiquer correctement avec le container runtime (containerd, CRI-O, etc). De plus cette couche doit permettre l’utilisation de conteneurs imbriqués, puisque Kubernetes utilisera des conteneurs en étant lui-même dans un conteneur. Concrètement cette couche intègre systemd, avec uniquement les services utiles, containerd, et d’autres paquets nécessaires au bon fonctionnement des composants du Kube.

Ensuite la troisième couche de l’image node est dédiée entièrement au fonctionnement de Kubernetes. Elle contient donc les composants du Kube avec Kubeadm et Weave. Kubeadm est un outil qui permet la mise en place facile et rapide d’un cluster Kubernetes minimum. Il déploie les composants du kube et gère les certificats pour assurer une bonne communication entre eux. Weave quant à lui est une implémentation de la CNI qui est une API définie par Kubernetes comme son modèle de networking. Weave fournit à Kubernetes un overlay sur le réseau sur lequel il peut faire communiquer ses pods au travers d’adresses IP.

Killer features et Minikube
Kind et Minikube sont tous deux des produits issus des K8S SIG (Special Interest Groups), c'est-à-dire de la communauté autour de Kubernetes. De ce fait, on pourrait trouver étrange qu’une même communauté ait créé deux produits très similaires. Là où Kind se démarque très clairement de Minikube est en fait la capacité de déployer un cluster avec plusieurs nœuds, ce qui est absolument impossible avec Minikube.

“Pourquoi avoir besoin d’un cluster multi-nœuds ?” - C’est une question qu’il est légitime de se poser lorsque l’on souhaite choisir entre Kind et Minikube (ou autre). La différence fondamentale se situe dans la qualité réaliste de l'environnement utilisé. En production, donc dans un “vrai” cluster, il est évident que plusieurs (voire énormément de) machines sont utilisées pour faire tourner l'infrastructure. De cette différence d'environnement naît un problème de réalisme, en effet le comportement des éléments dans le cluster peut être très différent selon que celui-ci ne contient qu’un nœud ou plusieurs. Il s’agit même de tout l’enjeu des systèmes distribués. Comment vérifier que ma base de données distribuée fonctionne alors que je n’ai qu’une seule machine ? Ce n’est pas possible, ou du moins c'est un problème difficile qui requerrait des outils suplémentaires, rajoutant à la charge du système.

Kind apporte cet environnement un maximum proche de celui de production en donnant la possibilité de choisir son nombre de nœuds. Dans le cadre de test end-to-end c’est une fonctionnalité absolument incroyable en comparaison de Minikube.

En revanche, il est intéressant de se poser la question dans le cadre du développement. Dans ce cas là cet aspect de réalisme n’est pas aussi important (à distinguer selon le contexte). Cela dit, Kind est également natif sur les systèmes Linux puisqu'il tourne dans des conteneurs Docker (natifs pour Linux et Windows servers). De ce fait, il est fondamentalement moins lourd que Minikube qui utilise une machine virtuelle. Bien sûr cela ne sera pas vrai si l’on déploie un cluster de dix nœuds avec Kind, qui deviendra alors plus consommateur en ressources.

1. Image sideload
Tout cluster Kind possède son propre gestionnaire d’images Docker, il n’interfère pas avec celui de l’hôte. Il existe cependant un moyen de les interfacer, et ainsi charger une image de l’hôte vers les nœuds. Il permet aussi d’abstraire le niveau de gestionnaire d’image privés, afin de ne faire l’authentification qu’à un seul endroit (sur l’hôte). De manière générale, cela permet de ne pas avoir recours à un Docker registry pour partager ses images entre l’hôte et les nœuds.

2. Attribution dynamique de volumes
Depuis 2019, Kind intègre une configuration de la solution “local-host-path” de Rancher. Celle-ci fournit une StorageClass qui assigne automatiquement des PV (Persistance Volume) au cluster à chaque PVC (Persistent Volume Claim) faite par des applications. De ce fait, le développeur n’a plus à se préoccuper de l’assignation des volumes sur son espace de stockage et peut se concentrer sur son activité principale.

3. Contrôleur Ingress
Kind supporte des contrôleurs ingress, notamment Nginx, Contour et Ambassador. Pour les mettre en place il suffit d’appliquer leur manifeste avec Kubectl. Ces contrôleurs ingress permettent alors la création d’objets Ingress par les développeurs. Le contrôleur ingress gère notamment le routage des services en fonction de noms de DNS et chemin d’URL, et autorisent également l’utilisation du protocole TLS pour une communication en HTTPS.

4. Load-balancing et MetalLB
Parmi les services Kubernetes, il existe les LoadBalancer. Ce type de service permet à chaque service de disposer d’une adresse IP qui sera accessible par l’extérieur du cluster au travers de ce load balancer. Cette solution est fournie par les cloud providers à la demande, toutefois lorsque l’on utilise un cluster bare-metal (comprendre sur ses propres machines) cette fonctionnalité n’est pas disponible sans implémentation supplémentaire. MetalLB apporte une solution à ce problème, en créant un load balancer virtuel. Kind supporte parfaitement cette solution.

1. Mises à jours et rythme de développement
Kind est un outil développé par la communauté, et non pas l’équipe derrière Kubernetes lui-même. De ce fait l’effort mis dans son développement n’est pas le même. Le projet a démarré en 2018 et a suivi un rythme de mise à jour assez correct depuis. Il n'y a cependant pas eu de nouvelle release depuis mai 2021. A noter qu’il est en version 0.11.1, et n’a donc pas encore atteint sa version 1.0.

2. Consommation en espace de stockage
Du fait de la manière dont il a été conçu, Kind consomme un espace disque important. En effet, pour chaque image utilisée dans le cluster, il est nécessaire d’en avoir une copie sur la machine hôte, ainsi que sur chaque nœud afin qu’ils puissent les démarrer. Il faut donc bien faire attention à la place restante sur la machine hôte.

L’espace utilisé est d’autant plus important que l’on utilise des solutions comme Skaffold qui produisent une grande quantité de volumes pour fournir du hot-reloading. On peut considérer que pour une dizaine de microservices sur quatre nœuds, l’espace disque nécessaire approche les 100 Go.

3. Consommation en RAM et CPU
De plus, il faut se rappeler que l’utilisation de containers affecte (même si légèrement) les performances. Kubernetes est toujours un processus daemon qui se doit de fonctionner en arrière-plan sur chaque nœud, afin de répondre au mieux à l’état dans lequel se trouve le cluster.

Couplé avec Skaffold pour le développement par exemple, si l’on souhaite déployer de nombreux microservices, alors la quantité de RAM consommée grimpe en flèche, et est proportionnelle au nombre de nœuds utilisés. On peut considérer que pour une dizaine de microservices et quatre nœuds, la consommation en mémoire vive dépasse les 10 Go et il est préférable d’avoir un processeur puissant (8+ coeurs).

Références
https://kind.sigs.k8s.io/ - Site web de Kind

https://github.com/kubernetes-sigs/kind/pull/1157 - Pull request PV

https://minikube.sigs.k8s.io/docs/ - Site web de Minikube