virli/tutorial/docker-orchestration/stack.md
2018-10-17 22:30:02 +02:00

4.7 KiB

\newpage

Déploiement de services

Services ?

Une petite minute terminologie avant de continuer, car lorsque l'on passe sur les clusters de Docker, cela change un peu :

  • une tâche correspond à un unique conteneur, lancé sur l'un des nœuds workers du cluster ;
  • un service est un groupe de tâches (oui, les tâches du point précédent), exécutant la même image.

Les services sont donc très utiles lorsque l'on veut avoir de la redondance, de la haute-disponibilité ou pour répartir la charge.

### Hello world, again?

Non, pas d'hello-world ici, mais nous allons prendre en main les services avec un serveur web, qui sera bien plus représentatif de ce que l'on pourra obtenir.

Précédemment, nous lancions notre serveur web favori avec :

    docker container run --name mywebs -d nginx

La même commande, mais déployée à partir d'un nœud manager, vers un nœud workers, est :

    docker service create --name myWebS nginx

Allons-y, essayons !

On peut consulter l'état du service avec, comme d'habitude ls :

    42sh$ docker service ls
    ID              NAME        MODE          REPLICAS    IMAGE         PORTS
    iyue3rgd0ohs    myWebS      replicated    1/1         nginx:latest

Vous pouvez constater que sur l'un des nœuds, sur lequel votre serveur aura été déployé, le tâche apparaît dans la liste des conteneurs !

Rien de très excitant pour le moment, car nous ne pouvons pas vraiment accéder à notre serveur. Essayons de modifier sa configuration en direct, afin d'ajouter une redirection de port :

    docker service update --publish-add 80 myWebS

À chaque modification de configuration, les conteneurs lancés au sein du service sont stoppés puis, le manager voyant que le service n'est pas dans l'état demandé, va lancer des tâches avec la nouvelle configuration.

La commande update est très puissante : vous pouvez mettre à jour pratiquement n'importe quel élément de configuration, y compris le nom de l'image ou son tag. Grâce à cela, faire des mises à jour se fait de manière transparente.

Magie du mesh

Lorsque l'on publie un port de cette manière, chaque nœud du cluster devient un point d'entrée pour ce port, même si la tâche ne s'exécute pas sur ce nœud particulièrement.

Essayons de nous connecter aux ports 80 des deux IP correspondant à nos deux nœuds. Vous devriez voir la même page.

Lorsque plusieurs tâches s'exécutent pour ce service, le nœud d'entrée choisi selon un round-robin à quelle tâche il va diriger la requête. C'est grâce à ce mécanisme qu'il est possible faire une répartition de charge très simplement.

\

Cette méthode n'est pas la seule permettant d'exposer des ports. Mais c'est sans doute la plus intuitive. Si vous souhaitez en apprendre plus, vous deviez consulter la documentation à ce sujet.

Mise à l'échelle et placement

On parle depuis toute à l'heure de lancer plusieurs tâches pour le même service. La mise à l'échelle c'est ça : exécuter plusieurs conteneurs pour la même tâche afin de mieux répartir la charge, idéalement sur des machines physique différentes.

Ce qui se fait souvent avec beaucoup de douleur hors de Docker, se résume ici à :

    docker service update --replicas 3 myWebS

Roulement de tambours .......

    docker service ps myWebS

nous montre bien, a priori 3 tâches en cours d'exécution pour ce service !

Enfin, vous avez compris le principe !

Stack ?

Refermons cette longue parenthèse et revenons-en au sujet du jour : la supervision de nos machines.

Une stack est un groupe de services. Un projet, par exemple un site web dans son ensemble : frontend, API, base de données, ...

Notre système de monitoring est une stack lui aussi, d'ailleurs, nous pouvons la lancer grâce à notre docker-compose.yml :

    docker stack deploy --compose-file docker-compose.yml tic

Règle de déploiement

Par rapport à docker-compose, nous pouvons indiquer dans ce fichier des paramètres qui ne serviront qu'au déploiement de notre tâche.

    version: '3'
    services:
      redis:
        image: redis:alpine

    	deploy:
    	  replicas: 6
    	  update_config:
    	    parallelism: 2
    		delay: 10s
    	  restart_policy:
    	    condition: on-failure
    	  placement:
    	    constraints:
    		  - node.role == manager
    	  resources:
    	    memory: 50M

Certaines informations comme les ressources, permettent à l'orchestrateur de mieux choisir le workers de destination, en fonction de certaines de ses caractéristiques.