diff --git a/tutorial/docker-orchestration/Makefile b/tutorial/docker-orchestration/Makefile index 8877a49..fa5c318 100644 --- a/tutorial/docker-orchestration/Makefile +++ b/tutorial/docker-orchestration/Makefile @@ -1,4 +1,4 @@ -SOURCES = tutorial.md setup.md what.md ../dockerfiles/supervisor.md manual.md compose.md machine.md swarm.md stack.md config-secrets.md project.md +SOURCES = tutorial.md setup.md what.md manual.md compose.md machine.md swarm.md stack.md project.md PANDOCOPTS = --latex-engine=xelatex \ --standalone \ --normalize \ diff --git a/tutorial/docker-orchestration/project.md b/tutorial/docker-orchestration/project.md index 54492d3..e27f7ef 100644 --- a/tutorial/docker-orchestration/project.md +++ b/tutorial/docker-orchestration/project.md @@ -85,7 +85,7 @@ Voici les notes retrouvées dans les derniers échanges avec le sous-traitant : -### Stage 0 : Récupérer les images +### Pallier 0 : Récupérer les images Le sous-traitant a laissé des images Docker sur le Docker Hub, vous pourrez vous baser dessus pour commencer. @@ -94,56 +94,120 @@ vous baser dessus pour commencer. * `nemunaire/fic-backend` * `nemunaire/fic-frontend` +Faites-vous la main sur ces trois images : lancez les ; l'ordre suggéré par les +notes du prestataire devraient vous aider. -### Stage 2 : `docker-compose.yml` simple +Pensez à inspecter les conteneurs pour voir les objets Docker qu'ils créent +et/ou exposent. -* admin -* backend -* frontend -* mysql +Vous devriez pouvoir lancer `docker container run nemunaire/fic-IMAGE --help` +sur les images. + +Durant la durée du projet, les images seront peut-être amenés à être mis à +jour, si vous vous trouvez bloqué, commencez par vérifier que vous avez bien la +dernière version disponible de l'image : + +```shell +docker pull nemunaire/fic-admin nemunaire/fic-backend nemunaire/fic-frontend +``` -### Stage 2 (bis) : `docker-compose.yml` avec autentification +### Pallier 1 : `docker-compose.yml` -* admin -* backend -* frontend -* mysql -* nginx (auth) +Maintenant que vous arrivez à lancer les images, rendez cela reproductible en +inscrivant tout ça dans un fichier YAML, compréhensible par `docker-compose` ! + +Vous devriez avoir ces services : + +* `mariadb` (ou `mysql`) +* `admin` +* `backend` +* `frontend` +* `nginx` (ou `apache`, ...) -### Stage 3 : `fic-server.yml` sécurisé +#### Astuces -* admin -* backend -* frontend -* mysql -* nginx (auth) - -Utilisant `docker secrets` et `docker config`. +Aidez-vous -### Stage 4 : retrouver les `Dockerfile` +### Pallier 2 : retrouver les `Dockerfile` + +Maintenant que vous êtes en mesure de lancer le service, il serait temps de ne +plus dépendre d'une image que l'on ne peut plus modifier facilement. + +Pour ce palier, vous allez devoir réécrire les trois fichiers `Dockerfile`, +pour chacun des service : * admin * backend * frontend +Arriverez-vous à générer des images plus propres que celles du prestataire +disparu ?! -### Stage 5 : `fic-server.yml` production ready -ssh between back and front et sur deux machines distinctes +#### Astuces + +Les différents projets sont organisés au sein d'un +[dépôt monolithique](https://danluu.com/monorepo/). Les projets ont des +dépendances entre les dossiers qui se trouvent à la racine (qui sont +l'équivalent de bibliothèques). Vous allez sans doute vouloir placer les trois +`Dockerfile` à la racine pour simplifier les étapes de construction des images : + +```shell +docker image build --file Dockerfile-admin . +``` + +Les +[*multi-stage builds*](https://docs.docker.com/engine/userguide/eng-image/multistage-build/) +vous seront d'une grande aide. + +Si vous n'avez pas le choix d'utiliser une vieille version de Docker qui ne +supporte pas la syntaxe au sein d'un seul fichier, vous pouvez ajouter des +scripts et autant de `Dockerfile` que nécessaire à la tarball (mais vous +devriez considérer l'option de mettre à jour votre Docker). + + +### Pallier 3 : `fic-server.yml` prêt pour le déploiement + +À présent, faites les éventuelles adaptations nécessaires pour que votre +fichier `docker-compose.yml` puisse s'exécuter au sein d'un cluster de +plusieurs machines. Via `docker stack deploy`. + + +### Pallier 4 : `fic-server.yml` prêt pour la production + +Comme indiqué dans les notes du prestataire, en production, le frontend se +trouve sur une machine distincte du backend. + +À vous de trouvez une solution élégante pour gérer la synchronisation des +données ! Il est fort probable que vous ayez à ajouter des services à votre +fichier YAML. + + +### Pallier 5 (bonus) : `fic-server.yml` sécurisé + +Vous avez indiqués des mots de passes bidons dans votre YAML ? Rangez les +informations sensibles au sein de +[`docker secret`](https://docs.docker.com/engine/swarm/secrets/) et les +éléments de configuration qui pourraient être changés au sein de +[`docker config`](https://docs.docker.com/engine/swarm/configs/). ## Modalité de rendu -Un service automatique s'occupe de réceptionner vos rendus, de faire les -vérifications nécessaires et de vous envoyer un accusé de réception (ou de +Un service automatique s'occupe de réceptionner vos rendus, de faire des +vérifications élémentaires et de vous envoyer un accusé de réception (ou de rejet). Ce service écoute sur l'adresse , c'est donc à cette adresse et exclusivement à celle-ci que vous devez envoyer vos rendus. Tout rendu -envoyé à une autre adresse et/ou non signé ne sera pas pris en compte. +envoyé à une autre adresse et/ou non signé et/ou reçu après la correction ne +sera pas pris en compte. + +Par ailleurs, n'oubliez pas de répondre à +[l'évaluation du cours](https://www.epitaf.fr/moodle/mod/quiz/view.php?id=33). ## Tarball @@ -151,18 +215,13 @@ envoyé à une autre adresse et/ou non signé ne sera pas pris en compte. Tous les fichiers identifiés comme étant à rendre pour ce TP sont à placer dans une tarball (pas d'archive ZIP, RAR, ...). -Les réponses aux questions sont à regrouper dans un fichier `questions.txt` à -placer à la racine de votre rendu. - -Voici une arborescence type: +Voici une arborescence type (vous pourriez avoir des fichiers supplémentaires, +cela dépendra de votre avancée dans le projet) :
``` -login_x-TP2/influxdb -login_x-TP2/influxdb/Dockerfile -login_x-TP2/influxdb/influxdb.conf -login_x-TP2/docker-compose.yml -login_x-TP2/mymonitoring.yml +login_x-TP2/tp/docker-compose.yml +login_x-TP2/tp/mymonitoring-stack.yml login_x-TP2/fic-server login_x-TP2/fic-server/fic-server.yml login_x-TP2/fic-server/Dockerfile-admin diff --git a/tutorial/docker-orchestration/stack.md b/tutorial/docker-orchestration/stack.md index e72371d..a64a14e 100644 --- a/tutorial/docker-orchestration/stack.md +++ b/tutorial/docker-orchestration/stack.md @@ -3,4 +3,158 @@ Déploiement de services ======================= -TODO +## 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 : + +```shell +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 : + +```shell +docker service create --name myWebS nginx +``` + +Allons-y, essayons ! + +On peut consulter l'état du service avec, comme d'habitude `ls` : + +```shell +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 : + +```shell +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. + +\newline + +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](https://docs.docker.com/engine/swarm/networking/). + + +### 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 à +: + +```shell +docker service update --replicas 3 myWebS +``` + +Roulement de tambours ....... + +```shell +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` : + +```shell +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. + +```yaml +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.