virli/tutorial/docker-orchestration/swarm.md

6.5 KiB

\newpage

Déploiement de conteneurs

Historiquement, le passage d'une application en production ou simplement dans un environnement de qualification, n'est pas toujours aisé. Parfois d'ailleurs, on ne teste pas, on fait les modifications en production ... et à chaque déploiement, on prie pour ne pas écraser une modification qui faisait que notre projet tombait en marche dans cet environnement.

Déployer des conteneurs sur sa propre machine, c'est extrêmement simple grâce. Et mieux encore, tout l'environnement étant contenu dans l'image, il suffit de suivre les bonnes pratiques pour que le déploiement en production se fasse de manière transparente.

L'orchestration

Cependant, notons une différence de taille entre notre environnement de développement sur nos machines locales et la production : les clients ! Pour répondre de manière adéquate, il convient de dimensionner correctement les machines, le nombre de conteneurs que chacune peut exécuter, en fonction de caractéristiques (on privilégiera les machines avec des SSD pour les serveurs de base de données par exemple), ...

Il n'est pas question pour un administrateur système de faire cette répartition de la charge à la main : le nombre de critères à prendre en compte est beaucoup trop grand, évolue sans cesse ; cela serait trop long s'il y a beaucoup de conteneurs et de variété de machines.

Ce processus d'optimisation s'appelle l'orchestration. Il s'agit de réussir à répartir au mieux les conteneurs sur les différentes machines disponibles.

Ce sujet fait l'objet de très nombreuses thèse depuis plusieurs années (avant les conteneurs, c'était pour répartir les machines virtuelles entre différents hôtes), et autant de projets disponibles. Citons par exemple Google Kubernetes, Hashicorp Nomad ou encore Apache Mesos, ...

Le point commun entre la plupart des orchestrateurs, c'est généralement leur extrême complexité de mise en œuvre. Dans le cadre de notre TP, nous allons plutôt utiliser l'orchestrateur intégré à Docker, dont la caractéristique principale est sa simplicité1.

Concepts clefs

Regroupés au sein d'un cluster (on parle de swarm pour Docker), chaque Docker engine représente un nœud (node) dans lequel on va déployer des services.

Certain nœud ont un rôle de manager, parmi ceux-ci, un seul est élu leader et prendra les décisions d'orchestration. Les autres sont là pour prendre le relais en cas de dysfonctionnement sur le manager élu.

Les services sont un groupe de tâches (typiquement une image avec sa ligne de commande à lancer) que le manager va conserver à l'état désiré. Le service va indiquer par exemple le nombre d'instances que l'on désire avoir dans le cluster. En cas de crash d'un manager ou d'un worker, le (nouveau) manager fera en sorte de redéployer les conteneurs perdus, afin de toujours maintenir le cluster dans l'état désiré.

En terme de cluster, des tâches sont l'équivalent des conteneurs, hors de Swarm.

Création du cluster Swarm

Initialisation du cluster

La première chose à faire, est d'initialiser un cluster swarm. Pour se faire, ce n'est pas plus compliqué que de faire :

```bash docker swarm init ```

Cela va créer un cluster mono-nœud, sur la machine courante (celle pointée par la variable DOCKER_HOST). Ce nœud est automatiquement passé manager du cluster, afin de pouvoir lancer des tâches ... au moins sur lui-même en attendant d'autres nœuds.

Rejoindre le cluster

Pour rejoindre un cluster, il est nécessaire d'avoir le jeton associé à ce cluster.

La commande pour rejoindre le cluster et contenant le jeton, est indiquée lorsque vous initialisez le cluster. Si vous avez raté la sortie de la commande, vous pouvez retrouver le jeton avec :

```bash docker swarm join-token worker ```

Lançons maintenant la commande join indiquée, sur une autre machine, en utilisant docker-machine.

Pro tips: envoyez votre commande join à votre voisin qui a réussi à provisionner plusieurs machines Docker (via docker-machine ou manuellement, peu importe du moment que les VMs ont bien accès au même réseau que votre Swarm2). Et soyez fair-play, attendez un peu avant de lancer l'image embano1/cpuburn ;)

```bash eval $(docker-machine env echinoidea) docker swarm join --token SWMTKN-1-...-... 10.10.10.42:2377 ```

Une fois rejoint, vous devriez voir apparaître un nouveau nœud worker dans :

``` 42sh$ eval $(docker-machine env -u) 42sh$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS y9skzvuf989hjrkciu8mnsy echinoidea Ready Active ovgh6r32kgcbswb2we48br1 * wales Ready Active Leader ```

Rejoindre en tant que manager

Lorsqu'il est nécessaire d'avoir de la haute-disponibilité, on définit plusieurs managers. Cela permet qu'en cas de dysfonctionnement du manager, un nouveau manager soit élu.

Nous n'allons pas faire rejoindre de manager supplémentaire durant ce TP, mais vous pouvez facilement expérimenter la chose en lançant 5 machines virtuelles et en définissant trois des cinq machines comme étant managers.

Pour que l'algorithme de consensus fonctionne de manière optimale, il convient toujours un nombre impair de managers, Docker en recommande 3 ou 5. La pire configuration est avec deux managers, car si un tombe, il ne peut pas savoir si c'est lui qui est isolé (auquel cas il attendrait d'être à nouveau en ligne avant de se proclamer leader) ou si c'est l'autre manager qui est tombé. Avec trois managers, en cas de perte d'un manager, les deux restants peuvent considérer qu'ils ont perdu le troisième et peuvent élire le nouveau manager entre-eux et continuer à faire vivre le cluster.


  1. À noter qu'une annonce faite à la Docker Con EU 2017 indique le début du support de Kubernetes au sein de Docker EE, pouvant être utilisé en symbiose avec Swarm. ↩︎

  2. Si vous utilisez Docker dans une VM, il faut que celle-ci soit configurée en mode bridge pour qu'elle soit sur le même sous-réseau. Il n'y a pas de problème à avoir des nœuds workers derrière un NAT, mais il est primordial que les managers soient joignables. Vous pouvez tenter de faire des redirections de ports, mais le résultat n'est pas garanti ! ↩︎