diff --git a/tutorial/docker-advanced/chronograf_setup.png b/tutorial/docker-advanced/chronograf_setup.png deleted file mode 120000 index dcbd7d3..0000000 --- a/tutorial/docker-advanced/chronograf_setup.png +++ /dev/null @@ -1 +0,0 @@ -../dockerfiles/chronograf_setup.png \ No newline at end of file diff --git a/tutorial/docker-advanced/chronograf_setup.png b/tutorial/docker-advanced/chronograf_setup.png new file mode 100644 index 0000000..25d005a Binary files /dev/null and b/tutorial/docker-advanced/chronograf_setup.png differ diff --git a/tutorial/dockerfiles/Makefile b/tutorial/dockerfiles/Makefile index bce6f31..df48fcd 100644 --- a/tutorial/dockerfiles/Makefile +++ b/tutorial/dockerfiles/Makefile @@ -1,4 +1,4 @@ -SOURCES = tutorial.md interactive.md dockerfile.md first.md supervisor.md goodpractices.md split.md entrypoint.md multistaged.md rendu.md +SOURCES = tutorial.md interactive.md dockerfile.md goodpractices.md entrypoint.md rendu.md PANDOCOPTS = --latex-engine=xelatex \ --standalone \ --normalize \ diff --git a/tutorial/dockerfiles/chronograf_setup.png b/tutorial/dockerfiles/chronograf_setup.png deleted file mode 100644 index 25d005a..0000000 Binary files a/tutorial/dockerfiles/chronograf_setup.png and /dev/null differ diff --git a/tutorial/dockerfiles/dockerfile.md b/tutorial/dockerfiles/dockerfile.md index b4471b2..60f9922 100644 --- a/tutorial/dockerfiles/dockerfile.md +++ b/tutorial/dockerfiles/dockerfile.md @@ -1,13 +1,11 @@ \newpage -`Dockerfile` -============ - -## Ma première image ... par `Dockerfile` +Ma première image ... par `Dockerfile` +====================================== Pour construire une image, nous ne sommes pas obligés de passer par une série -de commits. Docker dispose d'un mécanisme permettant d'automatiser la -construction de nouvelles images. Vous pouvez arriver au même résultat que ce +de *commits*. Docker dispose d'un mécanisme permettant d'automatiser la +construction de nouvelles images. Nous pouvons arriver au même résultat que ce que l'on a réussi à faire précédemment en utilisant le `Dockerfile` suivant :
@@ -19,7 +17,7 @@ que l'on a réussi à faire précédemment en utilisant le `Dockerfile` suivant ```
-La syntaxe d'un `Dockerfile` est simple, le premier mot de chaque ligne est +La syntaxe d'un `Dockerfile` est simple : le premier mot de chaque ligne est l'intitulé d'une instruction (que l'on écrit généralement en majuscule), elle est suivie de ses arguments. @@ -27,9 +25,9 @@ Dans notre exemple, nous utilisons `FROM` qui indique une image de départ à utiliser ; `RUN` est une commande qui sera exécutée dans le conteneur, dans le but de le construire. -Pour lancer la construction de la nouvelle image, créer un nouveau dossier ne -contenant que votre fichier `Dockerfile`, placez-vous dedans, puis utilisez la -commande `build` : +Pour lancer la construction de la nouvelle image, créons un nouveau dossier ne +contenant que votre fichier `Dockerfile`, plaçons-nous ensuite dedans, puis +lançons la commande `build` :
``` @@ -37,7 +35,7 @@ commande `build` : ```
-Une fois la construction de l'image terminée, vous pouvez la lancer et +Une fois la construction de l'image terminée, nous pouvons la lancer et constater l'existence de notre éditeur favori :
@@ -62,9 +60,21 @@ Cela signifie que l'exemple suivant **ne fonctionne pas** : ```
-Cet exemple ne fonctionne pas car le serveur MySQL qui est lancé dans le -premier `RUN`, n'est plus lancé au moment du deuxième `RUN`. En effet, chaque -commande du `Dockerfile` a pour but de modifier le système de fichiers. +Cet exemple ne fonctionne pas car le serveur MySQL est bien lancé dans le +premier `RUN`, mais il se trouve brûtalement arrêté dès lors que la commande +`service` se termine. En fait, à chaque instruction, Docker réalise +automatiquement un `run` suivi d'un `commit`. Et vous pouvez constater par +vous-même que, en créant l'image `tinysql` à partir d'un simple `apt install +mysql` : + +
+``` + docker container run tinysql service mysqld start +``` +
+ +rend la main directement, sans laisser de `mysqld` dans l'arborescence de +processus. Pour avoir le résultat escompté, il faut exécuter les commandes ensemble : @@ -75,13 +85,17 @@ Pour avoir le résultat escompté, il faut exécuter les commandes ensemble : ``` -Après le `RUN`, MySQL sera de nouveau arrêté, si on veut l'utiliser dans le -conteneur, il ne faudra pas oublier de lancer le processus. +Après le `RUN`, MySQL sera de nouveau tué. + +En aucun cas, une commande exécutée par un `RUN` se retrouvera en cours +d'exécution lorsque l'on invoquera un conteneur par `docker container +run`. Seul la commande fournie par l'utilisateur ou la commande par défaut de +l'image sera exécutée au lancement d'un conteneur. ## Exposer des ports -Construisons maintenant un conteneur avec un serveur web : +Construisons maintenant un conteneur avec un service web :
``` @@ -95,30 +109,90 @@ Construisons maintenant un conteneur avec un serveur web :
L'instruction `EXPOSE` sera traitée plus tard par le client Docker (équivalent -à l'argument `--expose`). Il s'agit de préciser les ports sur lesquels votre -image écoute. +à l'argument `--expose`). Il s'agit d'une métadonnée qui sera attachée à +l'image (et à toutes ses images filles). -En utilisant l'option `-P` du `run`, vous allez pouvoir assigner une -redirection de port aléatoire sur la machine hôte vers votre conteneur : +En précisant tous les ports qu'exposent une image dans ses métadonnées, ces +ports seront automatiquement exposés en utilisant l'option `-P` du `run` : cela +assigne une redirection de port aléatoire sur la machine hôte vers votre +conteneur :
``` - docker image build --tag=my_webserver . - docker container run -it -P my_webserver /bin/bash - service nginx start + 42sh$ docker image build --tag=my_webserver . + 42sh$ docker container run -it -P my_webserver /bin/bash + (cntnr)# service nginx start ```
-Dans un autre terminal, lancer un `docker ps` et consulter la colonne *PORTS* -pour connaître le port choisi par Docker pour effectuer la redirection. +Dans un autre terminal, lancer un `docker container ls` et consulter la colonne +*PORTS* pour connaître le port choisi par Docker pour effectuer la redirection. Rendez-vous ensuite dans votre navigateur sur . *À vous de jouer :* utilisez l'instruction `COPY` pour afficher votre propre -`index.html` remplaçant celui installé de base par nginx. +`index.html` remplaçant celui installé de base par `nginx`. Si vous manquez +d'inspiration, utilisez [cette page de compte à +rebours](https://virli.nemunai.re/countdown.html). -## Lancement de commande automatique +## Les caches + +Nous avons vu que chaque instruction de notre `Dockerfile` est exécutée dans un +conteneur, qui génère une image intermédiaire. Cette image intermédiaire sert +ensuite d'image de base pour le conteneur qui sera lancé avec l'instruction +suivante. + +Lorsqu'on lance la reconstruction du même `Dockerfile`, les images +intermédiaires sont réutilisées, comme un cache d'instructions. Cela permet de +gagner du temps sur les étapes qui n'ont pas changées. Ainsi, lorsque vous +modifiez une instruction dans votre `Dockerfile`, les instructions précédentes +ne sont pas réexécutées mais sont ressorties du cache. + +Le cache se base principalement sur le contenu de chaque instruction du +`Dockerfile` (pour les `COPY` et `ADD`, il va aussi regarder la date de +dernière modification de fichier à copier ou à ajouter). Donc tant qu'une +instruction n'est pas modifiée dans le `Dockerfile`, le cache sera utilisé. + +Il est possible de ne pas utiliser le cache et de relancer toutes les étapes du +`Dockerfile` en ajoutant l'option `--no-cache` au moment du `docker image +build`. + +Les couches du cache peuvent être partagées entre plusieurs conteneur, c'est +ainsi que vous pouvez partager facilement une plus grosse partie du système de +fichiers (rappelez-vous le principe d'union FS). + +Pour profiter du cache, on va placer de préférences les étapes les plus +génériques (qui seraient les plus susceptibles d'apparaître dans d'autres +images), en haut du `Dockerfile`. + + +## Métadonnées pures + +L'instruction LABEL permet d'ajouter une métadonnée à une image, sous forme de +clef/valeur. + +Une métadonnée +[courante](https://github.com/nginxinc/docker-nginx/blob/master/mainline/stretch/Dockerfile#L3) +est d'indiquer le nom du mainteneur de l'image : + +
+``` + LABEL maintainer="Pierre-Olivier Mercier " +``` +
+ +Dans notre `Dockerfile`, indiquez juste après l'image de base, vos noms, +prénoms et mails de contact avec l'instruction `LABEL maintainer`, pour +indiquer que c'est vous qui maintenez cette image, si des utilisateurs ont +besoin de vous avertir pour le mettre à jour ou s'ils rencontrent des +difficultés par exemple. + +On le place dès le début, car comme c'est une information qui n'est pas amener +à changer, elle sera toujours retrouvée en cache. + + +## Commande par défaut Vous pouvez placer dans un `Dockerfile` une instruction `CMD` qui sera exécutée si aucune commande n'est passée lors du `run`, par exemple : @@ -131,8 +205,8 @@ si aucune commande n'est passée lors du `run`, par exemple :
``` - docker image build --tag=my_nginx . - docker container run -d -P my_nginx + 42sh$ docker image build --tag=my_nginx . + 42sh$ docker container run -d -P my_nginx ```
@@ -142,16 +216,104 @@ retirez cette option pour voir ce qui ne va pas, ou utilisez la commande `docker container logs`. +## Construire son application au moment de la construction du conteneur ? + +Comment faire lorsque l'on a besoin de compiler une application avant de +l'intégrer dans le conteneur ? + +On peut vouloir lancer la compilation sur notre machine, mais cela ne sera pas +très reproductible et cela aura nécessité d'installer le compilateur et les +outils liés au langage que l'on souhaite compiler. Peut-être que plusieurs +versions de ces outils existent, laquelle choisir ? ... Ok c'est trop +compliqué. + +D'un autre côté, si l'on fait cela dans un conteneur, celui-ci contiendra dans +ses couches des données inutiles à l'exécution : les sources, les produits +intermédiaires de compilation, le compilateur, n'ont rien à faire dans les +couches de notre image. + +Le meilleur des deux mondes se trouve dans les *Multi-stage builds* : au sein +du même `Dockerfile`, on va réaliser les opérations de préparation dans un ou +plusieurs conteneurs, avant d'agréger le contenu compilé au sein du conteneur +final : + +
+``` + FROM gcc:4.9 + COPY . /usr/src/myapp + WORKDIR /usr/src/myapp + RUN gcc -static -static-libgcc -o hello hello.c + + FROM scratch + COPY --from=0 /usr/src/myapp/hello /hello + CMD ["/hello"] +``` +
+ +Dans cet exemple, deux conteneurs distincts sont créés : le premier à partir de +l'image `gcc`, il contient tout le nécessaire pour compiler notre +`hello.c`. Mais l'image finale (le dernier `FROM` de notre `Dockerfile`) est +l'image vide, dans laquelle nous recopions simplement le produit de notre +compilation. + +L'image ainsi générée est minime, car elle ne contient rien d'autre que le +strict nécessaire pour s'exécuter. + +### Étapes nommées + +Nous avons utilisé `--from=0` pour désigner la première image de notre +`Dockerfile`. Lorsque l'on réalise des montages plus complexe, on peut vouloir +donner des noms à chaque image, plutôt que de devoir jongler avec les +numéros. Dans ce cas, on indiquera : + +
+``` + FROM gcc:4.9 as builder + COPY . /usr/src/myapp + WORKDIR /usr/src/myapp + RUN gcc -static -static-libgcc -o hello hello.c + + FROM scratch + COPY --from=builder /usr/src/myapp/hello /hello + CMD ["/hello"] +``` +
+ +Par défaut la dernière étape du `Dockerfile` est retenu comme étant l'image que +l'on souhaite `tagger`, mais il est possible de préciser quelle image +spécifiquement on souhaite construire avec l'option `--target` : + +
+``` + 42sh$ docker build --target builder -t hello-builder . +``` +
+ +Cela peut être particulièrement utile si l'on dispose d'une image de debug, +incluant tous les symboles, et une image de production, plus propre. On +sélectionnera ainsi avec l'option `--target` l'un ou l'autre en fonction de +l'environnement dans lequel on souhaite se déployer. + + ## D'autres instructions ? Consultez pour la liste complète des instructions reconnues. -## Rendu +## Exercice -Rendez le fichier `Dockerfile` et son contexte (`index.html`, fichiers de conf -éventuels, ...) que vous avez utilisé pour réaliser votre image `my_webserver`. +Pour mettre en application tout ce que nous venons de voir, réalisons le +`Dockerfile` du service web [`youp0m`](https://you.p0m.fr/) que nous avons +utilisé la semaine dernière. -Une attention particulière sera apportée au respect des différentes bonnes -pratiques vues en cours pour l'écriture du `Dockerfile`. +Pour réaliser ce genre de contribution, on ajoute généralement un `Dockerfile` +à la racine du dépôt. + +Vous pouvez cloner le dépôts de sources de `youp0m` à : + +
+``` + https://git.nemunai.re/youp0m.git +``` +
diff --git a/tutorial/dockerfiles/entrypoint.md b/tutorial/dockerfiles/entrypoint.md index c1e560c..28288dc 100644 --- a/tutorial/dockerfiles/entrypoint.md +++ b/tutorial/dockerfiles/entrypoint.md @@ -1,21 +1,114 @@ \newpage -Entrypoint -========== +Personnalisation du point d'entrée du conteneur +=============================================== -Jusque là, à chaque redémarrage d'InfluxDB, il est nécessaire de reconfigurer -Grafana pour lui indiquer la nouvelle IP du conteneur. En effet, le data -container préserve les données, mais un changement d'IP n'est pas -répercuté. Pour cela, il nous fait un script d'initialisation, qui va écrire -l'ip de notre conteneur Docker dans la table `data_source` : +## Point d'entrée basique -Petit indice, les requêtes SQL sont les suivantes : +Afin de faire bénéficier à nos utilisateurs d'une immersion parfaite, nous +allons faire en sorte que notre image permette d'être utilisée ainsi :
``` - DELETE FROM "data_source"; - INSERT INTO "data_source" VALUES(1,1,0,'influxdb','influx','direct','http://${}:8086/','user','pass','metrics',0,'','',0,'null','2015-10-29 09:00:00','2015-10-29 09:05:00'); + 42sh$ docker run -d -p 80:80 youp0m -bind 80 ```
-La base se trouve dans `/var/lib/grafana/grafana.db`. + +Plutôt que de laisser l'utilisateur se débrouiller avec le chemin interne dans +lequel il va trouver le bon binaire : + +
+``` + 42sh$ docker run -d -p 80:80 youp0m /srv/youp0m -bind 80 +``` +
+ +Essayez les deux commandes, si vous avez utilisé l'instruction `CMD` dans votre +`Dockerfile` jusqu'à présent, vous devez vous trouver dans le deuxième cas. + +Pour améliorer la situation, définissez +l'[`ENTRYPOINT`](https://docs.docker.com/engine/reference/builder/#entrypoint) +de votre image sur le binaire `/srv/youp0m`. + + +## Point d'entrée avancé + +Dans certains cas, il peut être nécessaire au lancement d'un conteneur, de +faire un minimum d'étapes d'initialisation avant que le conteneur ne soit +opérationnel (rappelez-vous les options que l'on passait à l'image `mysql` pour +créer un utilisateur et une base). + +Notre but, dans cette partie, sera de créer un utilisateur administrateur +(pouvant passer le contrôle d'accès ) : + +
+``` + 42sh$ docker run -i --rm -p 8080:8080 -e YOUP0M_PASSWORD=admin youp0m +``` +
+ +### Bases du script + +Notre script d'`ENTRYPOINT` sera appelé avec en argument, ceux passés par +l'utilisateur après le nom de l'image, ou, à défaut, le contenu de `CMD`. + +C'est donc l'`ENTRYPOINT` qui est responsable de la bonne utilisation de +ceux-ci, de leur modification, ... + +À la fin d'un script d'`ENTRYPOINT`, afin de garder comme premier processus du +conteneur le programme qui nous intéresse, on réalise un `execve(2)`, sans +`fork(2)` : + +
+```shell + exec /srv/youp0m $@ +``` +
+ +Dans cet exemple : `exec` est la commande interne à notre shell pour lui +indiquer de remplacer son fil d'exécution par cette commande (sans `exec`, il +va `fork(2)` avant). `$@` est ici pour transmettre tel quel la liste des +arguments passés au script (il s'agit de ceux donnés par l'utilisateur, sur la +ligne de commande du `run`, ou du contenu de `CMD` si l'utilisateur n'a rien +précisé). + + +### Format du fichier `htpasswd` + +Le format attendu est celui d'un fichier `htpasswd` typique d'Apache. Vous +pourriez obtenir un fichier valide avec : + +
+```shell + ( + echo -n "$YOUP0M_USERNAME" + echo -n ":" + openssl passwd -crypt "$YOUP0M_PASSWORD" + ) > myhtpasswd +``` +
+ +Il faut ensuite passer le fichier sur la ligne de commande grâce à l'option +`-htpasswd`. + + +### Exercice + +Écrivez un script d'`ENTRYPOINT`, analysant les variables d'environnement, à la +recherche de `YOUP0M_USERNAME` et `YOUP0M_PASSWORD` pour initialiser le fichier +`.htpasswd` qui sera ajouté à la liste des arguments à passer au service. + +Par exemple : + +
+``` + 42sh$ docker run -d -p 8081:8081 -e YOUP0M_USERNAME=admin -e YOUP0M_PASSWORD=admin youp0m -bind=8081 + + 42sh$ curl -u admin:badpasswd http://localhost:8081/admin/ + You are not allowed to perform this request. + + 42sh$ curl -u admin:admin http://localhost:8081/admin/ + +``` +
diff --git a/tutorial/dockerfiles/first.md b/tutorial/dockerfiles/first.md index cbe3a62..cc389ed 100644 --- a/tutorial/dockerfiles/first.md +++ b/tutorial/dockerfiles/first.md @@ -11,40 +11,6 @@ La machine (notre première image Docker) contiendra tout le nécessaire pour faire fonctionner notre service de monitoring. -## Les caches - -Nous avons vu que chaque instruction de notre `Dockerfile` est exécutée dans un -conteneur, qui génère ensuite une image intermédiaire. Cette image -intermédiaire sert ensuite d'image de base pour l'instruction suivante. - -Lorsque l'on lance la reconstruction du même `Dockerfile`, les images -intermédiaires sont utilisées comme un cache d'instructions, permettant ainsi -de gagner du temps sur les étapes qui n'ont pas changées. Ainsi, lorsque vous -modifiez une instruction dans votre `Dockerfile`, les instructions précédentes -ne sont pas réexécutées mais sont ressorties du cache. - -Le cache se base principalement sur le contenu de chaque instruction du -`Dockerfile` (pour les `COPY` et `ADD`, il va aussi regarder la date de -dernière modification de fichier à copier ou à ajouter). Donc tant qu'une -instruction n'est pas modifiée dans le `Dockerfile`, le cache sera utilisé. - -Il est possible de ne pas utiliser le cache et de relancer toutes les étapes du -`Dockerfile` en ajoutant l'option `--no-cache` au moment du `docker image -build`. - -Les couches du cache peuvent être partagées entre plusieurs conteneur, c'est -ainsi que vous pouvez partager facilement une plus grosse partie du système de -fichiers. - -Pour profiter du cache, on va placer de préférences les étapes les plus -génériques (qui seraient les plus susceptibles d'apparaître dans d'autres -images), en haut du `Dockerfile`. - -Commençons donc notre `Dockerfile` : choisissez une image de base pour remplir -votre `FROM`, et indiquez votre nom avec l'instruction `LABEL maintainer` (pour -indiquer que c'est vous qui maintenez cette image, si des utilisateurs ont -besoin de vous avertir pour le mettre à jour ou s'ils rencontrent des -difficultés par exemple). ## `RUN` ou script ? diff --git a/tutorial/dockerfiles/goodpractices.md b/tutorial/dockerfiles/goodpractices.md index 482a39c..33cb584 100644 --- a/tutorial/dockerfiles/goodpractices.md +++ b/tutorial/dockerfiles/goodpractices.md @@ -4,7 +4,7 @@ Retour sur les bonnes pratiques =============================== Pour chaque bonne pratique ci-dessous, vérifiez que vous la respectez -bien, faites les modifications nécessaires. +bien, faites les modifications nécessaires dans votre `Dockerfile`. ## Utilisez le fichier `.dockerignore` diff --git a/tutorial/dockerfiles/interactive.md b/tutorial/dockerfiles/interactive.md index e290485..886bfc9 100644 --- a/tutorial/dockerfiles/interactive.md +++ b/tutorial/dockerfiles/interactive.md @@ -38,23 +38,11 @@ Installons maintenant un programme : ``` -En attendant la fin de l'installation, jetons un œil à la commande dans un -autre terminal : - -
-``` - docker container ls -``` -
- -Cette commande liste les conteneurs actifs. Notez le *Container ID* ainsi que -le *NAMES* du conteneur actuellement en cours d'installation de `nano`. - Lorsque l'installation de `nano` est terminée, quittez l'image en tapant `exit`. -Sauvegardez votre image modifiée avec la commande `commit` pour pouvoir -commencer directement de votre image avec `nano` : +Sauvegardez vos modifications en tant que nouvelle image Docker, avec +la commande `commit` :
``` @@ -62,9 +50,11 @@ commencer directement de votre image avec `nano` : ```
-en remplaçant `CONTAINER` par le nom ou l'identifiant de votre -container. `my_nano` est le nom que vous voudrez utiliser à la place -d'`ubuntu` : +en remplaçant `CONTAINER` par le nom ou l'identifiant du container qui +doit servir de modèle. `my_nano` est le nom que vous voudrez utiliser +à la place d'`ubuntu`. + +Testons sans plus attendre notre nouvelle image :
``` diff --git a/tutorial/dockerfiles/multistaged.md b/tutorial/dockerfiles/multistaged.md deleted file mode 100644 index 55d144e..0000000 --- a/tutorial/dockerfiles/multistaged.md +++ /dev/null @@ -1,6 +0,0 @@ -\newpage - -Multi-stage build -================= - -TODO diff --git a/tutorial/dockerfiles/rendu.md b/tutorial/dockerfiles/rendu.md index 89c375b..5ee8b2b 100644 --- a/tutorial/dockerfiles/rendu.md +++ b/tutorial/dockerfiles/rendu.md @@ -1,3 +1,56 @@ +\newpage + +Projet et rendu +=============== + +Projet +------ + +Avec l'aide d'un `Dockerfile` *multi-stage*, réalisez l'image la plus petite +possible (partant d'un `FROM scratch`), qui permette d'utiliser la [page de +compte à rebours](https://virli.nemunai.re/countdown.html) avec cette +configuration pour nginx : + +```conf + events {} + + http { + default_type text/html; + + index countdown.html; + + server { + listen 80; + + root /srv/http; + + rewrite "^/[0-9]+:[0-9]{2}$" /countdown.html; + rewrite "^/[0-9]+$" /countdown.html; + } + } +``` + +Vous pouvez envisager dans un premier temps d'extraire de l'image `nginx`, le +binaire `nginx` lui-même et observer les différents problèmes. Vous pourrez +ensuite par exemple envisager de compiler `nginx` (vous trouverez les sources +du projet : ). + +Dans tous les cas, votre `Dockerfile` devra être facilement maintenable +(notamment en cas de nouvelle version du serveur web), et vous devrez apporter +une attention particulière au suivi des bonnes pratiques d'écriture des +`Dockerfile`. + +### Exemple d'exécution + +
+``` + 42sh$ docker build -t countdown countdown + 42sh$ docker run -d -P countdown + 42sh$ firefox http://localhost:32198/42:23 +``` +
+ + Modalités de rendu ------------------ @@ -13,6 +66,9 @@ et exclusivement à celle-ci que vous devez envoyer vos rendus. Tout rendu 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=215). + Tarball ------- @@ -20,20 +76,23 @@ Tarball Tous les fichiers identifiés comme étant à rendre pour ce TP sont à placer dans une tarball (pas d'archive ZIP, RAR, ...). -Voici une arborescence type (vous pourriez avoir des fichiers supplémentaires, -cela dépendra de votre avancée dans le projet) : +Voici une arborescence type (vous pourriez avoir des fichiers +supplémentaires) :
``` - login_x-TP1_5/influxdb/Dockerfile - login_x-TP1_5/influxdb/influxdb.conf - login_x-TP1_5/chronograf - login_x-TP1_5/chronograf/Dockerfile - login_x-TP1_5/chronograf/chronograf.conf - login_x-TP1_5/mymonitoring - login_x-TP1_5/mymonitoring/Dockerfile - login_x-TP1_5/mymonitoring/chronograf.conf - login_x-TP1_5/mymonitoring/influxdb.conf - login_x-TP1_5/mymonitoring/supervisor.conf + login_x-TP2/ + login_x-TP2/youp0m/ + login_x-TP2/youp0m/Dockerfile + login_x-TP2/youp0m/entrypoint.sh + login_x-TP2/youp0m/.dockerignore + login_x-TP2/youp0m/... + login_x-TP2/countdown/Dockerfile + (login_x-TP2/countdown/nginx.conf) + (login_x-TP2/countdown/countdown.html) ```
+ +Les deux fichiers `nginx.conf` et `countdown.html` seront écrasés par +les fichiers fournis lors de la correction, vous n'êtes pas donc +obligés de les embarquer dans votre rendu. diff --git a/tutorial/dockerfiles/split.md b/tutorial/dockerfiles/split.md deleted file mode 100644 index 93648f9..0000000 --- a/tutorial/dockerfiles/split.md +++ /dev/null @@ -1,58 +0,0 @@ -\newpage - -Une application par conteneur -============================= - -Avec notre conteneur utilisant `supervisor`, nous ne respectons pas -cette dernière bonne pratique d'un seul processus par conteneur :-( - -L'intérêt est de permettre à chaque conteneur d'effectuer une tâche -simple et générique, de manière à pouvoir être réutilisé pour d'autres -projets dans le futur. Par exemple, notre conteneur InfluxDB pourra -être utilisé pour stocker des relevés de métriques d'autres systèmes -ou des logs. Chronograf peut être connecté à d'autres serveurs afin -de corréler les métriques, ... - - -## Séparer le `Dockerfile` - -Commençons par séparer notre `Dockerfile` en deux : dans une partie -nous allons garder la partie InfluxDB, de l'autre la partie Chronograf. - -Il va vous falloir créer deux dossiers distincts, il en faut un par -`Dockerfile` : réutilisez l'image `influxdb` créée précédemment et créez le -dossier pour l'image `chronograf`. - -\vspace{1em} - -Pour tester la bonne marche de vos conteneurs, vous pouvez le lancer votre -conteneur chronograf avec la commande suivante (en considérant que votre -conteneur influxdb de la première partie est toujours lancé). - -
-```shell - docker run --rm --link YOUR_INFLUX_CNTR_NAME:influxdb chronograf -``` -
- -Remplacez `YOUR_INFLUX_CNTR_NAME` par le nom du conteneur qui fait tourner -votre influxdb. En créant ce lien, `chronograf` sera capable de contacter une -machine nommée `influxdb` (indiqué par la partie du lien après les `:`). - - -### Visualiser les données dans `chronograf` - -Avant d'arrêter `telegraf` et nos conteneurs pour passer à une nouvelle étape, -prenez le temps d'afficher les données que vous avez collecté depuis le début -du TP. - -Après avoir ajouté le serveur (en remplaçant `localhost` proposé par défaut par -`influxdb` issue du *link*), ajouter deux visualisations avec les requêtes -suivantes : - -
-```sql - SELECT used, available, cached FROM mem WHERE tmpltime() - SELECT mean(usage_idle) FROM cpu WHERE tmpltime() GROUP BY time(20s), cpu -``` -
diff --git a/tutorial/dockerfiles/supervisor.md b/tutorial/dockerfiles/supervisor.md deleted file mode 100644 index f0d6b68..0000000 --- a/tutorial/dockerfiles/supervisor.md +++ /dev/null @@ -1,104 +0,0 @@ -\newpage - -Plusieurs daemons dans un conteneur -=================================== - -Notre système de monitoring commence enfin à ressembler à quelque chose. Mais -ce serait tellement plus pratique de voir tous ces tableaux de nombres sous -forme de graphiques ! - -Nous allons pour cela ajouter `chronograf` dans notre image. - -Avant de modifier votre `Dockerfile`, créez un nouveau dossier de rendu : -`mymonitoring`, dans lequel vous recopierez l'état actuel de notre image -`influxdb`. - - -## Chronograf - -Commençons par compléter la commande d'installation existante pour `influxdb`, -afin d'installer simultanément `chronograf`. - -La documentation de la procédure est disponible -[à cette adresse](https://docs.influxdata.com/chronograf/v1.6/introduction/installation/). - - -## Script d'init - -Lors du dernier TP, nous avons vu que les conteneurs s'arrêtaient dès que le -premier processus du conteneur (celui qui a le PID 1, à la place d'`init`) -terminait son exécution, quelque soit le statut de ses éventuels fils. - -Pour lancer tous nos daemons, nous avons donc besoin d'écrire un script qui -lance puis attend que les deux deamons aient terminés de s'exécuter. - -Écrivons ce script. Hints : `wait(1)`. - -\vspace{1em} - -Pour vérifier que votre conteneur fonctionne correctement, vous pouvez le -lancer : - -
-```shell -docker run --rm -p 10000:10000 mymonitoring -``` -
- -Puis accéder à chronograf : . Donnez un nom à votre -configuration, puis cliquez sur *Add*. Les paramètres préremplis dans le -formulaire sont corrects. - -Vous devriez obtenir l'écran suivant (notez la partie `Status: Online, v1.0.0`) : - -![Chronograf configuré](chronograf_setup.png) - - -## Autorestart - -L'avantage de détruire le conteneur à la mort du père, est que s'il s'agit de -notre processus principal et qu'il est seul (par exemple `nginx` pour un -conteneur qui délivre des pages web), il va être possible de redémarrer le -conteneur automatiquement grâce à la *restart policy* que l'on peut définir au -moment du `docker run` : - -
-```shell -docker run -d -p 80:80 --restart=on-failure nginx -``` -
- -Il existe trois règles de redémarrage différentes : - -- **`no` :** il s'agit de la règle par défaut. Lorsque l'exécution du conteneur - se termine, il n'est pas redémarré. -- **`on-failure[:max-retries]` :** redémarre uniquement si le code de sortie du - conteneur n'est pas 0. Il est possible de préciser pour cette option le - nombre maximum de redémarrage qui sera tenté. -- **`always` :** redémarre le conteneur dans tous les cas, quelque soit son - code de sortie et indéfiniment. - -Le script d'init que vous avez réalisé ne tient sans doute pas compte de -cela. Mais plein de gens ont cette problématique et l'application `supervisor` -répond parfaitement à notre problématique ! - - -## `supervisor` - -Première étape : installer `supervisor`, le paquet se trouve dans les dépôts. - -L'étape suivante consiste à remplir puis copier le fichier de configuration -dans le conteneur. Vous allez devoir écraser dans votre conteneur le fichier -`/etc/supervisord.conf` pour démarrer à la fois `chronograf` et `influxdb`. - -Vous pouvez vous aider de la documentation disponible à : - - - -La même procédure de test que précédemment peut être suivie. - - -## Rendu - -Nous ne toucherons plus à cette image, placez-la dans un dossier -`mymonitoring`.