diff --git a/slides/1-docker's basis.odp b/slides/1-docker's basis.odp index 840e935..e243e91 100644 Binary files a/slides/1-docker's basis.odp and b/slides/1-docker's basis.odp differ diff --git a/tutorial/1/Makefile b/tutorial/1/Makefile index 099227c..657c127 100644 --- a/tutorial/1/Makefile +++ b/tutorial/1/Makefile @@ -1,18 +1,53 @@ include ../pandoc-opts.mk SOURCES = tutorial.md \ + ../containers/overview.md \ ../docker-basis/discover.md ../docker-basis/installation.md ../docker-basis/what.md ../docker-basis/first.md ../docker-basis/cleaning.md ../docker-basis/ex-flask.md \ ../docker-basis/volumes.md \ - ../docker-basis/linking.md ../docker-basis/linking-ex-fic.md ../docker-basis/linking-ex-help.md \ - ../docker-advanced/what.md ../docker-advanced/setup.md ../docker-advanced/manual.md ../docker-advanced/compose.md \ - ../docker-advanced/security.md \ + ../docker-basis/ex-flask-volume.md \ + ../docker-basis/linking.md \ + +SOURCES_COURSE = tutorial.md \ + ../containers/overview.md \ + ../docker-basis/discover.md ../docker-basis/installation.md ../docker-basis/what.md ../docker-basis/first.md ../docker-basis/cleaning.md \ + ../docker-basis/volumes.md \ + ../docker-basis/linking.md \ + +SOURCES_TUTO = tutorial.md \ + ../header-tp.md \ + ../docker-basis/ex-flask.md \ + ../docker-basis/ex-flask-volume.md \ + see-fun-for-more.md \ + ../new-page.md \ + ex2.md \ + ../docker-basis/ex-owncloud.md ../docker-basis/linking-ex-help.md \ + +SOURCES_TUTOFUN = tutorial.md \ + ../header-tp-fun.md \ + note-tp-fun.md \ + ../docker-basis/ex-flask.md \ + ../docker-basis/ex-flask-volume.md \ + ../docker-basis/ex-flask-s3.md \ + ../docker-basis/linking-ex-help.md \ + +SOURCES_PROJECT = tutorial.md \ + ../docker-advanced/what.md ../docker-advanced/setup.md ../docker-advanced/manual.md ../new-page.md ../docker-advanced/compose.md \ rendu.md -all: tutorial.pdf +all: course.pdf tutorial.pdf tutorial-fun.pdf project.pdf -tutorial.pdf: ${SOURCES} +course.pdf: ${SOURCES_COURSE} + pandoc ${PANDOCOPTS} -o $@ $+ + +tutorial.pdf: ${SOURCES_TUTO} + pandoc ${PANDOCOPTS} -o $@ $+ + +tutorial-fun.pdf: ${SOURCES_TUTOFUN} + pandoc ${PANDOCOPTS} -o $@ $+ + +project.pdf: ${SOURCES_PROJECT} pandoc ${PANDOCOPTS} -o $@ $+ clean:: - rm tutorial.pdf + rm -f course.pdf tutorial.pdf tutorial-fun.pdf project.pdf diff --git a/tutorial/1/ex2.md b/tutorial/1/ex2.md new file mode 100644 index 0000000..3fecc93 --- /dev/null +++ b/tutorial/1/ex2.md @@ -0,0 +1,2 @@ +Mise en pratique des notions +---------------------------- diff --git a/tutorial/1/note-tp-fun.md b/tutorial/1/note-tp-fun.md new file mode 100644 index 0000000..79cd2b2 --- /dev/null +++ b/tutorial/1/note-tp-fun.md @@ -0,0 +1,4 @@ +Il s'agit d'une version du TP qui va un peu plus loin que le cours. + +Si vous connaissez déjà bien Docker, vous pouvez pimenter encore davantage le +sujet en apprenant les subtilités de Podman, en l'utilisant la place de Docker. diff --git a/tutorial/1/rendu.md b/tutorial/1/rendu.md index 75be296..b9586cd 100644 --- a/tutorial/1/rendu.md +++ b/tutorial/1/rendu.md @@ -11,140 +11,41 @@ monitoring, d'un simple :
``` -42sh$ docker-compose up +42sh$ docker compose up ```
-Vous intégrerez les trois images (`influxdb`, `chronograf` et `telegraf`), +Vous intégrerez les trois images (`influxdb`, `chronograf`[^onlyv1] et `telegraf`), mettrez en place les *volumes* et *networks* nécessaires au bon fonctionnement de la stack. +[^onlyv1]: N'ajoutez pas chronograf dans votre `docker-compose.yml` si vous + avez opté pour la version 2 d'InfluxDB. + Le résultat final attendu doit permettre d'afficher dans `chronograf` l'hôte auto-monitoré par la stack, sans plus de configuration. Vous aurez pour cela -éventuellement besoin de placer des fichiers de configuration à côté de votre +besoin de placer des fichiers de configuration à côté de votre `docker-compose.yml`, afin de pouvoir inclure ces configurations dans les conteneurs, sans avoir besoin de reconstruire ces conteneurs. -Modalités de rendu ------------------- - -En tant que personnes sensibilisées à la sécurité des échanges électroniques, -vous devrez m'envoyer vos rendus signés avec votre clef PGP. - -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é et/ou reçu après la correction ne -sera pas pris en compte. - -En cas de doute, [une interface](https://virli.nemunai.re/rendus/) et une API -sont disponibles pour consulter l'état de votre rendu. - -Par ailleurs, n'oubliez pas de répondre à -[l'évaluation du cours](https://virli.nemunai.re/quiz/11). - - -Tarball +Arborescence attendue ------- -Tous les fichiers identifiés comme étant à rendre pour ce TP sont à -placer dans une tarball (pas d'archive ZIP, RAR, ...). +Tous les fichiers identifiés comme étant à rendre sont à placer dans un dépôt +Git privé, que vous partagerez avec [votre +professeur](https://gitlab.cri.epita.fr/nemunaire/). -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/ -login_x-TP1/ficadmin-run.sh -login_x-TP1/docker-compose.yml -login_x-TP1/... +./ +./docker-compose.yml +./... # Pour les fichiers de configuration ```
- -## Signature du rendu - -Deux méthodes sont utilisables pour signer votre rendu : - -* signature du courriel ; -* signature de la tarball. - -Dans les deux cas, si vous n'en avez pas déjà une, vous devrez créer une clef -PGP à **votre nom et prénom**. - -Pour valider la signature, il est nécessaire d'avoir reçu la clef publique -**séparément**. Vous avez le choix de l'uploader sur un serveur de clefs, soit -de me fournir votre clef en main propre, soit l'envoyer dans un courriel -distinct. - -### Signature du courriel - -Une version récente de [Thunderbird](https://www.thunderbird.net/fr/) vous -permettra d'envoyer des courriels signés. Si vous n'avez qu'une version -ancienne, l'extension [Enigmail](https://enigmail.net) est très bien réputée -pour signer ses mails depuis Thunderbird. Bien entendu, de nombreuses autres -solutions sont disponibles. - -Utilisez le service automatique pour savoir si votre -courriel est correctement signé et que je suis en mesure de vérifier la -signature. - - -### Astuces - -#### No public key - -Si vous recevez un rapport avec l'erreur suivante : - -
-``` -[FAIL] Bad signature. Here is the gnupg output: - -gpg: Signature made Tue Jan 01 16:42:23 2014 CET -gpg: using RSA key 842807A84573CC96 -gpg: requesting key E2CCD99DD37BD32E from hkp server keys.openpgp.org -gpg: Can't check signature: No public key -``` -
- -C'est que votre clef publique n'est pas dans mon trousseau et que les -méthodes de récupération automatique n'ont pas permis de la -trouver. Uploadez votre clef sur [un serveur de -clefs](https://keys.openpgp.org/) ou envoyez un courriel au service -avec votre clef publique en pièce jointe, avant de retenter votre -rendu. - - -#### Not explicit username - -Si vous recevez un rapport avec l'erreur suivante : - -
-``` -[FAIL] The username of your key is not explicit, I can't find you. -``` -
- -Votre clef ne contient sans doute pas vos noms et prénoms ou l'adresse -électronique associée à la clef n'est pas celle que j'ai dans ma base de -données. - - -#### I've decided to skip your e-mail - -Si vous recevez un rapport concluant ainsi : - -
-``` -After analyzing your e-mail, I've decided to SKIP it. -``` -
- -Cela signifie que la lecture de votre courriel qui a été préférée n'est pas -celle d'un rendu. Vérifiez que vous n'envoyez pas votre clef publique avec -votre rendu. +Votre rendu sera pris en compte en faisant un [tag **signé par votre clef +PGP**](https://lessons.nemunai.re/keys). Consultez les détails du rendu (nom du +tag, ...) sur la page dédiée au projet sur la plateforme de rendu. diff --git a/tutorial/1/see-fun-for-more.md b/tutorial/1/see-fun-for-more.md new file mode 100644 index 0000000..f40d5dc --- /dev/null +++ b/tutorial/1/see-fun-for-more.md @@ -0,0 +1,2 @@ +Pour continuer à travailler sur youp0m, vous pouvez passer sur le TP fun. Il y +a encore bien d'autres méthodes pour gérer les fichiers, si ça vous intéresse. diff --git a/tutorial/1/tutorial.md b/tutorial/1/tutorial.md index 3badd7b..9ad1902 100644 --- a/tutorial/1/tutorial.md +++ b/tutorial/1/tutorial.md @@ -3,22 +3,8 @@ title: Virtualisation légère -- TP n^o^ 1 subtitle: Les bases de Docker author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps} institute: EPITA -date: Jeudi 16 septembre 2021 +date: Mercredi 7 septembre 2022 abstract: | Durant ce premier TP, nous allons apprendre à utiliser Docker, puis nous apprendrons à déployer un groupe de conteneurs ! - - \vspace{1em} - - Le TP se termine par un petit projet à rendre à au - plus tard le **mercredi 22 septembre 2021 à 23 h 42**. Consultez la - dernière section de chaque partie pour plus d'informations sur les - éléments à rendre. Et n'oubliez pas de répondre aux [questions de - cours](https://virli.nemunai.re/quiz/11). - - En tant que personnes sensibilisées à la sécurité des échanges électroniques, - vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à - [me](https://keys.openpgp.org/search?q=nemunaire%40nemunai.re) faire signer - votre clef et n'hésitez pas à [faire signer la - vôtre](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/). ... diff --git a/tutorial/containers/layers.md b/tutorial/containers/layers.md new file mode 100644 index 0000000..6662eb1 --- /dev/null +++ b/tutorial/containers/layers.md @@ -0,0 +1,15 @@ + +### Les conteneurs Docker + +Alors que les images constituent la partie immuable de Docker, les conteneurs +sont sa partie vivante. Chaque conteneur est créé à partir d'une image : à +chaque fois que nous lançons un conteneur, une couche lecture/écriture est +ajoutée au-dessus de l'image. Cette couche est propre au conteneur et +temporaire : l'image n'est pas modifiée par l'exécution d'un conteneur. + +![Couches d'un conteneur](layers-multi-container.png "Couches d'un conteneur"){ width=70% } + +Chaque conteneur s'exécute dans un environnement restreint et distinct de +l'environnement principal (où vous avez votre bureau). Par exemple, dans cet +environnement, vous ne pouvez pas voir les processus qui sont situés en dehors, +ni accéder aux fichiers extérieurs. diff --git a/tutorial/containers/overview.md b/tutorial/containers/overview.md new file mode 100644 index 0000000..7de7f6c --- /dev/null +++ b/tutorial/containers/overview.md @@ -0,0 +1,95 @@ +L'écosystème des conteneurs +=========================== + +Pour entrer dans le monde des conteneurs, il faut bien saisir un certain nombre +de concepts qui ont vu le jour progressivement, au fil des tentatives faites +pour standardiser tout cet écosystème. Ce sont des notions importantes, car la +plupart des outils utilisent d'une manière ou d'une autre ces concepts. + + +Les images +---------- + +Une image est une méthode pour distribuer un logiciel, qui s'apparente à un +package. L'image contient les exécutables, mais aussi toutes les dépendances, +les bibliothèques systèmes, les fichiers de configuration, ... Tout ce dont +notre logiciel a besoin pour fonctionner. + +Il existe différentes typologies d'images : + +- certaines contiennent des logiciels ou des services prêts à l'emploi : le + serveur web `nginx`, ou `apache`, ou encore la base de données MySQL, ou + MongoDB, ... +- certaines contiennent un programme spécifique : on peut vouloir utiliser + `git`, le client `MySQL`, `emacs` ou bien encore le navigateur Chrome ; +- d'autes enfin servent pour développer et étendre les possibilités. Ce sont + souvent des images utilisées comme bases pour les deux types que l'on a vus : + Debian, Alpine, Windows, ... + +Il est aisé de s'échanger des images, ainsi tout le monde peut récupérer des +images de ses logiciels favoris. + + +Les registres +------------- + +Les registres sont des plateformes qui centralisent les images. Ils permettent +de récupérer les images, ils disposent généralement d'une interface permettant +de consulter leur catalogue, et ils permettent aussi d'en envoyer. + +Les registres les plus connus sont le Docker Hub ou Quay.io. Ils contiennent à +la fois : +- des images officielles (`nginx`, `postgres`, ...) issues directement de leurs + éditeurs, +- des images communautaires, maintenues par les utilisateurs d'un logiciel, + mais aussi, +- des images de tout un chacun pour ses propres besoins. + +D'autres registres existent en dehors de ces grands noms publics. Certaines +forges telles que GitHub, GitLab ou Gitea proposent un service de registre que +leurs utilisateurs peuvent utiliser pour publier les images liées à un +projet. Cela permet aux utilisateurs de retrouver tous les produits de +compilation au même endroit. + +Enfin, chacun peut déployer son propre registre, qui peut alors avoir des +droits d'accès restreint. Une entreprise peut vouloir déployer un registre +privé lorsqu'elle utilise des conteneurs dans son infrastructure, mais qu'il +n'est pas souhaitable que ses images soient diffusées. + + +Les conteneurs +-------------- + +On parle d'un conteneur pour désigner une instance en cours d'exécution. + +Lorsqu'on lance un conteneur, une copie de l'image est créée sur le disque, +puis le système crée une isolation, pour contenir et restreindre l'exécution +aux seules données de l'image. + +Les conteneurs sont par nature **immuables** : on exécute le contenu d'une +image déjà construite, on n'y change pas le code qui est exécuté et on n'y fait +pas de changements qui pourrait altérer son fonctionnement. L'idée directrice dans +le design des conteneurs est de toujours être en mesure de pouvoir relancer un +conteneur ailleurs et s'attendre exactement au même comportement. + +Cela signifie que l'on ne fait par exemple pas de mise à jour dans un +conteneur : lorsque notre application ou le système sous-jacent a besoin d'être +mis à jour, on construit ou on télécharge une nouvelle image. + +Ce qui distingue deux exécutions de la même image, ce sont les données que l'on +donne au conteneur. + +::::: {.question} + +##### Tous les conteneurs utilisent ces principes ? {-} + +Nous avons décrit ici les concepts propres aux conteneurs applicatifs. Dans le +cas des conteneurs systèmes, leurs cycles de vie sont plus proches de l'usage que +l'on peut avoir des machines virtuelles classiques : chaque conteneur démarre +avec son historique (la manière dont il a été installé, les mises à jour qui +ont été appliquées, les configurations modifiées et les données qui ont été +apportées au fil du temps ...). On ne peut pas dans ces circonstances +remplacer un conteneur système par un autre, tout comme on ne peut pas +remplacer une machine virtuelle que l'on a installée et configuré à la main. + +::::: diff --git a/tutorial/docker-advanced/compose.md b/tutorial/docker-advanced/compose.md index 62bf911..248c23c 100644 --- a/tutorial/docker-advanced/compose.md +++ b/tutorial/docker-advanced/compose.md @@ -1,5 +1,3 @@ -\newpage - Composition de conteneurs ------------------------- @@ -42,7 +40,7 @@ fonctionnalités de Docker. #### `services` Cette section énumère la liste des services (ou conteneurs) qui seront gérés -par `docker-compose`. +par `docker compose`. Ils peuvent dépendre d'une image à construire localement, dans ce cas ils auront un fils `build`. Ou ils peuvent utiliser une image déjà existante, dans @@ -144,9 +142,9 @@ la commande suivante et admirer le résultat :
```bash -docker-compose up +docker compose up ```
-Encore une fois, testez la bonne connexion entre chronograf (accessible sur -) et influxdb. +Encore une fois, testez la bonne connexion entre `chronograf` (accessible sur +) et `influxdb`. diff --git a/tutorial/docker-advanced/manual.md b/tutorial/docker-advanced/manual.md index 475f08f..11eadfe 100644 --- a/tutorial/docker-advanced/manual.md +++ b/tutorial/docker-advanced/manual.md @@ -1,5 +1,3 @@ -\newpage - Lier des conteneurs ------------------- @@ -16,7 +14,7 @@ Le premier conteneur qui doit être lancé est la base de données orientée sé temporelles : [InfluxDB](https://www.influxdata.com/time-series-platform/influxdb/). En effet, tous les autres conteneurs ont besoin de cette base de données pour -fonctionner correctement\ : il serait impossible à *Chronograf* d'afficher les +fonctionner correctement : il serait impossible à *Chronograf* d'afficher les données sans base de données, tout comme *Telegraf* ne pourrait écrire les métriques dans une base de données à l'arrêt. @@ -31,6 +29,16 @@ docker container run -p 8086:8086 -d --name mytsdb influxdb:1.8 ``` +::::: {.warning} + +Remarquez que nous n'utilisons pas la version 2 d'InfluxDB. Sa mise en +place est plus contraignantes pour faire de simples tests. Si vous +souhaitez tout de même utiliser la dernière version de la stack TICK, +vous pouvez consulter le `README` du conteneur sur le Docker Hub :\ + + +::::: + Comme il s'agit d'une API REST, nous pouvons vérifier le bon fonctionnement de notre base de données en appelant : @@ -59,8 +67,8 @@ le client officiel (le binaire s'appelle `influx`) : ``` 42sh$ docker container run --rm -it --link mytsdb:influxdb influxdb:1.8 \ influx -host influxdb -Connected to http://influxdb:8086 version 1.8.9 -InfluxDB shell version: 1.8.9 +Connected to http://influxdb:8086 version 1.8.10 +InfluxDB shell version: 1.8.10 > show databases name: databases name @@ -132,7 +140,7 @@ système. Pour cela, on commence par télécharger *Telegraf* :
```bash -V=1.19.2 +V=1.23.4 P=telegraf-${V}_linux_$(uname -m) curl https://dl.influxdata.com/telegraf/releases/${P}.tar.gz | \ tar xzv -C /tmp @@ -163,7 +171,7 @@ Et observons ensuite : ```bash 42sh$ docker container run --rm -it --link mytsdb:zelda influxdb:1.8 \ influx -host zelda -InfluxDB shell version: 1.8.9 +InfluxDB shell version: 1.8.10 > show databases name: databases name @@ -199,6 +207,16 @@ lancé, celui-ci va régulièrement envoyer des métriques de cette machine. À vous de jouer pour lancer le conteneur [*Chronograf*](https://store.docker.com/images/chronograf). +::::: {.question} + +#### InfluxDB v2 {-} + +Chronograf n'existe plus en tant que projet indépendant dans la version 2, si +vous êtes parti sur cette version, vous retrouverez les tableaux de bord +directement dans l'interface d'InfluxDB, sur le port 8086. + +::::: + L'interface de *Chronograf* est disponible sur le port 8888. Consultez la [documentation du conteneur](https://hub.docker.com/_/chronograf) diff --git a/tutorial/docker-advanced/setup.md b/tutorial/docker-advanced/setup.md index b70aa5a..f522390 100644 --- a/tutorial/docker-advanced/setup.md +++ b/tutorial/docker-advanced/setup.md @@ -1,5 +1,3 @@ -\newpage - Mise en place ------------- @@ -11,19 +9,7 @@ communauté, et parfois même appropriées par Docker. ### `docker-compose` -Dans cette partie, nous allons avoir besoin de `docker-compose`. - -Ce projet ne bénéficie pas d'une intégration au sein du projet Docker et doit -être téléchargé séparément, car originellement, le projet était développé par -une équipe indépendante (et en Python). Il constitue aujourd'hui une brique de -l'écosystème Docker, presque indispensable ! - -#### Par le gestionnaire de paquets - -Les distributions à jour vous proposeront un paquet `docker-compose` qui -fonctionnera avec la version de Docker qu'ils fournissent. - -#### Par la distribution binaire +Dans cette partie, nous allons avoir besoin du plugin `docker-compose`. L'équipe en charge du projet met à disposition un exécutable que nous pouvons téléchargeant depuis . @@ -31,6 +17,21 @@ téléchargeant depuis . Ajoutez l'exécutable dans le dossier des plugins : `$HOME/.docker/cli-plugins` (sans oublier de `chmod +x` !). +::::: {.more} + +Autrefois, `docker-compose` était un script tiers que l'on utilisait +indépendamment de Docker. Le projet, historiquement écrit en Python, a été +entièrement réécrit récemment afin qu'il s'intégre mieux dans l'écosystème. + +Vous trouverez encore de nombreux articles vous incitant à utiliser +`docker-compose`. Dans la plupart des cas, vous pouvez simplement remplacer par +des appels à `docker compose`. + +Il y a même un outil qui a spécialement été conçu pour migrer les lignes de +commandes :\ + + +::::: #### Vérification du fonctionnement @@ -39,8 +40,8 @@ Comme avec Docker, nous pouvons vérifier le bon fonctionnement de
``` -42sh$ docker-compose --version -docker-compose version: 1.29.2 +42sh$ docker compose version +Docker Compose version v2.10.2 ```
diff --git a/tutorial/docker-basis/discover.md b/tutorial/docker-basis/discover.md index 69494bd..1afcef6 100644 --- a/tutorial/docker-basis/discover.md +++ b/tutorial/docker-basis/discover.md @@ -3,12 +3,17 @@ Découvrons Docker ================= -Entrons sans plus attendre dans le vif du sujet : Docker. +Tous les programmes d'exécution de conteneurs (*container runtimes*) ne +fonctionnent pas de la même manière et n'apportent pas les mêmes +fonctionnalités. Dans leurs couches les plus basses, chacun de ces programmes +va certes utiliser les mêmes fonctionnalités du système d'exploitation afin de +créer les couches d'isolation, mais chacun apporte un enrobage et une manière +d'utiliser les conteneurs différents. -Ce projet, dont les sources ont été rendues libres en 2013, a tout de -suite remporté un engouement indéniable. Le projet a énormément grossi -depuis, et il s'est aussi bien stabilisé. Aujourd'hui de nombreuses -entreprises n'hésitent plus à l'utiliser en production. +Nous allons commencer sans plus attendre par découvrir Docker. Ce projet, dont +les sources ont été rendues libres en 2013, a tout de suite remporté un +engouement indéniable. Le projet a énormément grossi depuis, et il s'est aussi +bien stabilisé. Dans ce chapitre, nous allons partir à la découverte de cet outil : après l'avoir installé, nous apprendrons d'abord les concepts clefs puis diff --git a/tutorial/docker-basis/ex-flask-s3.md b/tutorial/docker-basis/ex-flask-s3.md new file mode 100644 index 0000000..a4fadd1 --- /dev/null +++ b/tutorial/docker-basis/ex-flask-s3.md @@ -0,0 +1,91 @@ +::::: {.exercice} + +Faire persister les données à l'heure du cloud +---------------------------------------------- + +Aïe, c'est un sujet épineux... On peut entendre ici et là que les conteneurs +permettent de monter en puissance facilement, mais lorsque l'on est lié à un +espace de stockage classique, on se heurte bien vite à des réalités physiques. + +Même si l'on utilise un système de fichiers partagé pour stocker nos images et +ainsi répartir la puissance de calcul entre plusieurs machines, il va vite +arriver un moment où la bande passante du disque réseau ne suivra plus. Il faut +donc passer sur une classe de stockage d'un autre type : l'Object Storage. + +L'Object Storage est une méthode de stockage des objets adaptée au monde du +Cloud Computing. Il s'agit d'une API HTTP avec laquelle on peut interagir pour +accéder, ajouter, partager ou gérer un flot d'octets, que l'on nomme *objet* dans +le jargon, mais il s'agit ni plus ni moins que d'un fichier. + +Il est de la responsabilité de l'administrateur du service (Amazon, Microsoft, +Google ...) de faire en sorte que les données soient suffisamment réparties +pour éviter les goulots d'étranglement et les SPOF. Ce n'est plus notre +problème de gérer la distribution de la bande passante, ni l'usure des disques, +ni même la capacité de notre espace de stockage. + +Toutes les applications ne sont malheureusement pas nativement compatibles avec +ce système de stockage. Mais il se trouve que youp0m le supporte ! + +Nous allons déployer le service `minio`, qui est une implémentation libre de +l'API d'Amazon S3. `minio` dispose d'une interface graphique pour gérer nos +*buckets*, c'est un volume auquel on attribue des droits particuliers, +notamment quel utilisateur y a accès. C'est au sein d'un *bucket* que l'on va +pouvoir envoyer nos fichiers. Ceux-ci seront référencés avec une *clef* +(l'équivalent du chemin) : il n'y a pas de notion d'arborescence ou de dossier, +mais par convention, lorsque l'on place un `/` dans le nom de la clef, on +considère qu'il s'agit d'un séparateur de dossier. + +::::: {.question} + +Comme il n'y a pas de notion de dossier, il n'y a pas besoin de créer +l'arborescence avant d'écrire un objet. Chaque objet est référencé par sa clef, +sans qu'il ne soit question d'arborescence ou de dossier. + +À partir d'un *bucket* vide, vous pouvez donc directement ajouter le fichier : +`images/next/racoon.jpg`, sans vous préoccuper de l'existence ou non des +dossiers `images` et `next`, la séparation n'est qu'une convention, l'objet +n'est pas enregistré comme étant le fichier `racoon.jpg` du dossier `next`, +mais bien comme `images/next/racoon.jpg`. + +::::: + +Au sein de l'interface minio, vous devrez donc créer un bucket (par exemple +`youp0m` puisque ce sera un *bucket* dédié à cette application). Ainsi qu'un +compte de service (sous *Identity* > *Service Accounts*). Cela vous permettra +de récupérer une *Access Key* ainsi que sa *Secret Key* associée. Ce sont des +informations qui permettront au conteneur `youp0m` de s'identifier auprès de +l'API. + + +Il faudra ensuite lancer un conteneur youp0m avec les +options suivantes : + +
+``` +S3_ENDPOINT=http://NOM_DU_CONTENEUR_MINIO:9000 +S3_BUCKET=NOM_DU_BUCKET +S3_ACCESS_KEY=ACCESS_KEY_GENEREE +S3_SECRET_KEY=SECRET_KEY_CORRESPONDANTE +S3_PATH_STYLE=true +``` +
+ +::::: {.more} + +La dernière option `S3_PATH_STYLE` est importante lorsque l'on utilise minio, +car il y a une subtile différence entre l'API d'Amazon et celle de minio +lorsque l'on ne le configure pas davantage. + +Un *bucket* pour Amazon S3 correspond à un sous-domaine (par exemple +`youp0m.nemunai.re.s3.amazonaws.com.` pour le bucket +`youp0m.nemunai.re`). Cependant, dans notre installation de minio, nous n'avons +pas de nom de domaine à proprement parler. L'option est donc là pour indiquer +que le nom du *bucket* est attendu comme premier paramètre de l'URL et non pas +comme sous-domaine. + +::::: + +Votre instance de `youp0m` est désormais réellement prête pour passer en +production. Bravo ! + +::::: diff --git a/tutorial/docker-basis/ex-flask-volume.md b/tutorial/docker-basis/ex-flask-volume.md new file mode 100644 index 0000000..a64d22a --- /dev/null +++ b/tutorial/docker-basis/ex-flask-volume.md @@ -0,0 +1,47 @@ +::::: {.exercice} + +Faire persister les données : niveau 1 +-------------------------------------- + +Le service `youp0m` que nous avons déployé fonctionne comme on pourrait s'y +attendre, mais vous imaginez bien que ce n'est pas très pratique de devoir +réimporter les données à chaque fois que l'on met à jour le conteneur ou sa +configuration. + +Maintenant que nous savons utiliser les volumes nous allons les utiliser pour +rendre notre service plus pérenne. + +Le service stocke par défaut les images dans le dossier `/images` du +conteneur. Pour les sauvegarder hors du conteneur, nous devons donc créer un +volume vers ce dossier : + +
+``` +42sh$ docker volume create youp0m_images +42sh$ docker run -v youp0m-image:/images -p 8080:8080 registry.nemunai.re/youp0m +``` +
+ +Ajoutons quelques images puis arrêtons et supprimons le conteneur. Relançons +ensuite un nouveau conteneur avec les mêmes options : + +
+``` +42sh$ docker run -v youp0m-image:/images -p 8080:8080 registry.nemunai.re/youp0m +``` +
+ +::::: {.question} + +Nous ne recréons pas le volume, il est important de ne pas l'avoir supprimé +ici, puisque c'est ce volume qui assure la persistance des images. + +::::: + +Nos images sont bien persistantes d'une instance à l'autre de notre contenu. + +Nous voici prêt à déployer en production notre service, sans crainte de perdre +les jolies contributions. Mais... est-ce que ce sera suffisant pour répondre aux +milliers de visiteurs attendus ? + +::::: diff --git a/tutorial/docker-basis/ex-flask.md b/tutorial/docker-basis/ex-flask.md index a38210f..1ad9b13 100644 --- a/tutorial/docker-basis/ex-flask.md +++ b/tutorial/docker-basis/ex-flask.md @@ -1,5 +1,3 @@ -\newpage - Mon premier webservice ---------------------- @@ -14,7 +12,7 @@ Nous pouvons télécharger et lancer le service grâce à :
```bash -docker container run -i nemunaire/youp0m +docker container run -i registry.nemunai.re/youp0m ```
@@ -37,7 +35,7 @@ Nous pouvons rediriger le port avec l'argument `-p dst_host:s
```bash -docker container run -i -p 8080:8080 nemunaire/youp0m +docker container run -i -p 8080:8080 registry.nemunai.re/youp0m ```
@@ -75,7 +73,7 @@ On utilise l'option `-d` pour lancer le conteneur en tâche de fond :
```bash -docker container run -d -p 8080:8080 nemunaire/youp0m +docker container run -d -p 8080:8080 registry.nemunai.re/youp0m ```
@@ -98,11 +96,11 @@ absolument un clone de  ! Il s'agit du même service, mais ce ne sont pas les mêmes images. On ne peut pas utiliser le même port sur la machine hôte, mais pour le reste, -il s'agit des mêmes options\ : +il s'agit des mêmes options :
```bash -docker container run -d -p 8081:8080 nemunaire/youp0m +docker container run -d -p 8081:8080 registry.nemunai.re/youp0m ```
@@ -141,7 +139,7 @@ Pour ajouter une variable d'environnement, cela se passe dans la commande
```bash -docker container run -e YOUP0M_PASSWORD=foobar -p 8080:8080 nemunaire/youp0m +docker container run -e YOUP0M_PASSWORD=foobar -p 8080:8080 registry.nemunai.re/youp0m ```
diff --git a/tutorial/docker-basis/ex-owncloud.md b/tutorial/docker-basis/ex-owncloud.md index 1550898..3c9bdb6 100644 --- a/tutorial/docker-basis/ex-owncloud.md +++ b/tutorial/docker-basis/ex-owncloud.md @@ -16,11 +16,11 @@ pare-feu (mais cette dernière partie n'est pas demandée, gardez simplement en tête que cela doit pouvoir être fait manuellement au cas par cas : sur une machine sans pare-feu configurée, cela ne demande pas d'étape supplémentaire). -Votre script devra se limiter aux notions vues durant cette partie du TP -(ie. sans utiliser `docker-compose` ou `docker stack` que l'on verra par la -suite). Il pourra cependant faire usage des commandes `docker OBJECT inspect` -pour ne pas avoir à faire d'analyse syntaxique sur les retours des commandes -lisibles par les humains. +Votre script devra se limiter aux notions vues durant cette partie (ie. sans +utiliser `docker-compose` ou `docker stack` que l'on verra par la suite). Il +pourra cependant faire usage des commandes `docker OBJECT inspect` pour ne pas +avoir à faire d'analyse syntaxique sur les retours des commandes lisibles par +les humains. Cette instance devra utiliser une base de données MySQL (lancée par votre script dans un autre conteneur) et contenir ses données dans un ou plusieurs @@ -46,3 +46,14 @@ http://localhost:12345/
::::: + +### Au secours, ça veut pas se connecter ! + +Lorsque nous lançons pour la première fois notre conteneur MySQL ou MariaDB, un +script est chargé d'initialiser le volume attaché à `/var/lib/mysql`. Les +démarrages suivant, ou si vous réutilisez un volume déjà initialisé avec une +base de données, le script ne refait pas d'initialisation. Même si les +variables d'environnement ont changé. + +Si vous rencontrez des difficultés pour connecter votre conteneur à +`my-db`, prenez le temps de recréer un volume. diff --git a/tutorial/docker-basis/first.md b/tutorial/docker-basis/first.md index 3a9fd02..320620d 100644 --- a/tutorial/docker-basis/first.md +++ b/tutorial/docker-basis/first.md @@ -1,5 +1,3 @@ -\newpage - Mon premier conteneur --------------------- diff --git a/tutorial/docker-basis/installation.md b/tutorial/docker-basis/installation.md index c30b2e0..96264d3 100644 --- a/tutorial/docker-basis/installation.md +++ b/tutorial/docker-basis/installation.md @@ -52,13 +52,6 @@ distribution : -::::: {.question} - -**Et Kali Linux alors ?** Kali étant basée sur Debian, référez-vous à -la procédure d'installation de cette distribution. - -::::: - ### Sous Windows et macOS Bien que les fonctionnalités de contenerisation de Docker que nous utiliserons @@ -80,9 +73,9 @@ la machine virtuelle sous-jacente. ::::: {.warning} -Depuis septembre 2021, ces applications passent sous une licence payante pour -les grosses entreprises[^DockerSubscription]. Cela ne nous concerne pas, car la -licence est gratuite pour un usage éducatif ou personnel. +Depuis septembre 2021, ces applications sont passées sous une licence payante +pour les grosses entreprises[^DockerSubscription]. Cela ne vous concerne pas, +car la licence est gratuite pour un usage éducatif ou personnel. Notez que cela ne concerne pas le projet ou le binaire Docker : ceux-ci restent libres. Seules les applications Docker Desktop sont concernées. @@ -155,7 +148,7 @@ Server: #### `no such file or directory`? Si vous avez cette erreur : `dial unix /var/run/docker.sock: no such file or -directory.`, le deamon n'est sans doute pas lancé. Lancez-le : +directory.`, le daemon n'est sans doute pas lancé. Lancez-le :
```bash diff --git a/tutorial/docker-basis/linking-ex-help.md b/tutorial/docker-basis/linking-ex-help.md index 3f8fe1c..4bd9821 100644 --- a/tutorial/docker-basis/linking-ex-help.md +++ b/tutorial/docker-basis/linking-ex-help.md @@ -1,15 +1,3 @@ -### Au secours, ça veut pas se connecter ! - -Lorsque nous lançons pour la première fois notre conteneur MySQL ou MariaDB, un -script est chargé d'initialiser le volume attaché à `/var/lib/mysql`. Les -démarrages suivant, ou si vous réutilisez un volume déjà initialisé avec une -base de données, le script ne refait pas d'initialisation. Même si les -variables d'environnement ont changé. - -Si vous rencontrez des difficultés pour connecter votre conteneur à -`my-db`, prenez le temps de recréer un volume. - - ### Entrer dans un conteneur en cours d'exécution Dans certaines circonstances, les journaux ne sont pas suffisants pour déboguer diff --git a/tutorial/docker-basis/volumes.md b/tutorial/docker-basis/volumes.md index d91d1bc..9e09ca5 100644 --- a/tutorial/docker-basis/volumes.md +++ b/tutorial/docker-basis/volumes.md @@ -73,8 +73,7 @@ On pourra également faire de même avec un conteneur MySQL :
```bash docker container run --name mydb -e MYSQL_ROOT_PASSWORD=my-secret-pw \ - --mount source=prod_db,target=/var/lib/mysql\ - mysql + --mount source=prod_db,target=/var/lib/mysql mysql ```
@@ -88,7 +87,7 @@ Lorsque vous n'avez pas besoin de stocker les données et que vous ne désirez pas qu'elles persistent (des données sensibles par exemple) ou si cela peut améliorer les performances de votre conteneur, il est possible de créer des points de montages utilisant le système de fichiers `tmpfs` et donc résidant -exclusivement en RAM\ : +exclusivement en RAM :
```bash diff --git a/tutorial/docker-basis/what.md b/tutorial/docker-basis/what.md index 41df769..1c16055 100644 --- a/tutorial/docker-basis/what.md +++ b/tutorial/docker-basis/what.md @@ -1,40 +1,56 @@ -\newpage - Composition de Docker --------------------- -Docker est un écosystème d'outils de haut niveau, permettant d'utiliser des -*conteneurs*. +Docker est une suite d'outils de haut niveau, permettant d'utiliser des +*conteneurs*. Le projet en lui-même utilise de nombreuses dépendances, +originellement développées par l'entreprise Docker Inc., puis laissé dans le +domaine public lors des efforts de standardisation en 2015. -Docker est composé d'un daemon lancé au démarrage de votre machine, avec lequel -vous interagissez via un client (le programme `docker`). La communication entre -le daemon et le client s'effectuant sur une API REST généralement au travers -d'une socket. +Commençons par planter le décor, en détaillant les principes de base de Docker. -Le client peut d'ailleurs ne pas être sur la même machine qui exécutera +### Séparation des compétences + +Le projet s'article autour d'un daemon lancé au démarrage de la machine, avec +lequel on interagit via un client (le programme `docker`). La communication +entre le daemon et le client s'effectuant sur une API REST généralement au +travers d'une socket. + +::::: {.more} + +Tous les programmes d'exécution de conteneurs n'utilisent pas une architecture +avec un daemon et un client. `podman` que l'on peut généralement substituer à +Docker n'emploie pas de daemon. Chaque utilisateur de la machine peut donc +disposer de ses propres conteneurs, sans interférer avec ceux de ses voisins. + +D'un point de vue de la sécurité, le daemon Docker est exécuté en tant que +super-utilisateur. C'est sur ce daemon que repose la sécurité de la machine, ce +qui peut être beaucoup de responsabilité. Gardez en tête que le modèle +d'exécution de Docker n'est pas unique. Nous avons le choix. + +::::: + +Le processus client peut d'ailleurs ne pas être sur la même machine qui exécute effectivement les conteneurs.[^dockermachine] -C'est ce qu'il se passe lorsqu'on utilise *Docker4Windows* ou *Docker4Mac* : +C'est ce qu'il se passe lorsqu'on utilise Docker sur Windows ou macOS : une machine virtuelle Linux est lancée parallèlement au système de base et -chaque commande `docker` tapée est passée au deamon dans la machine virtuelle. +chaque commande `docker` tapée est passée au daemon dans la machine virtuelle. [^dockermachine]: Il suffit de modifier la variable d'environnement `DOCKER_HOST` ou de passer le paramètre `-H` suivi de l'URL de la socket à `docker`. Voir aussi : -Commençons par planter le décor, en détaillant les principaux mécanismes de -Docker. - ### Les images Docker -Une image Docker est un système de fichiers en lecture seule. Elle est formée -d'un ensemble de couches, agrégées selon le principe d'UnionFS. +Comme nous l'avons vu en introduction, les images sont un moyen de récupérer +facilement un environnement d'exécution complet, prêt à l'emploi. Une image +Docker donc est un système de fichiers en lecture seule. Une image peut, par exemple, contenir : * un système Ubuntu opérationnel, * le programme `busybox`, -* un serveur web et votre application web, prêts à l'emploi, +* votre site web personnel, prêt à l'emploi, * ... Les images sont utilisées comme **modèle** qui sera ensuite dupliqué à chaque @@ -43,36 +59,34 @@ fois que l'on démarrera un nouveau conteneur. Il y a deux méthodes pour obtenir des images Docker : soit les construire avec les outils fournis, soit les récupérer depuis un registre. - -### Les registres Docker (*Docker registries*) - -Les registres sont des plates-formes de stockage, publiques ou privées, -contenant des images. Ils permettent de récupérer des images, mais également -d'en envoyer. - -Le registre utilisé de base est le [Docker Hub](https://hub.docker.com/) : il -contient à la fois des images officielles (ubuntu, debian, nginx, ...), des -images créées par des utilisateurs, mais aussi des images de grands éditeurs, -payantes, à destination des entreprises. - -Des registres alternatifs existent comme celui de [quay.io](https://quay.io/search), -et les dépôts de sources tels que -[GitHub](https://github.blog/2020-09-01-introducing-github-container-registry/) -et [GitLab](https://docs.gitlab.com/ee/user/packages/container_registry/) le -proposent également. +Lorsque vous ne précisez pas l'adresse d'un registre, Docker va aller chercher +sur le [Docker Hub](https://hub.docker.com/). C'est son registre par défaut, chaque -### Les conteneurs Docker +### Les plugins Docker -Alors que les images constituent la partie immuable de Docker, les conteneurs -sont sa partie vivante. Chaque conteneur est créé à partir d'une image : à -chaque fois que nous lançons un conteneur, une couche lecture/écriture est -ajoutée au-dessus de l'image. Cette couche est propre au conteneur et -temporaire : l'image n'est pas modifiée par l'exécution d'un conteneur. +L'architecture de Docker est devenue très modulable. Le projet est parti dans +de nombreuses directions, chacun voulant tirer la couverture vers soit, et +l'équipe maintenant le projet a parfois eu du mal à arbitrer les bonnes choses +à ajouter ou non au projet. -![Couches d'un conteneur](layers-multi-container.png "Couches d'un conteneur"){ width=70% } +Afin de palier aux besoins complémentaires, parfois accessoires, parfois +salvateurs, un système de plugins a été intégré. Il permet d'appeler d'autres +programmes comme s'il s'agissait de composant de Docker. -Chaque conteneur s'exécute dans un environnement restreint et distinct de -l'environnement principal (où vous avez votre bureau). Par exemple, dans cet -environnement, vous ne pouvez pas voir les processus qui sont situés en dehors, -ni accéder aux fichiers extérieurs. +Certains plugins ajoutent des options à la ligne de commande (`docker-compose`, +`docker-scan`, `docker-buildx` ...). D'autres ajoutent des typologies de +réseaux, de gestion du stockage ou ajoutent de l'authentification. + +Pour ajouter un plugin à Docker, il suffit de l'ajouter dans un sous-dossier de +`/usr/lib/docker/cli-plugins` pour qu'il soit accessible à tous les +utilisateurs de notre machine ou dans `$HOME/.docker/` si l'on veut l'installer +seulement pour nous. + +Par exemple, les plugins ajoutant des commandes iront dans +`$HOME/.docker/cli-plugins`. Par exemple, si l'on souhaite pouvoir disposer de +la commande `docker compose`, on téléchargera le plugin vers l'emplacement : +`$HOME/.docker/cli-plugins/docker-compose`. + +Plus récemment, de nouveaux plugins ont vu le jour et se basent directement sur +des conteneurs que l'on peut télécharger depuis un registre d'images. diff --git a/tutorial/docker-orchestration/machine.md b/tutorial/docker-orchestration/machine.md index 85bc6d6..1fc4b1a 100644 --- a/tutorial/docker-orchestration/machine.md +++ b/tutorial/docker-orchestration/machine.md @@ -71,7 +71,7 @@ fichiers. ##### Utilisation avec Docker {-} -Nous avons déjà évoqué le fait que le deamon pouvait ne pas se trouver sur la +Nous avons déjà évoqué le fait que le daemon pouvait ne pas se trouver sur la même machine que le client `docker`. Eh bien avec `docker-machine` cela prend tout son sens, car vous pouvez très facilement changer de daemon/machine avec une simple commande : diff --git a/tutorial/header-tp-fun.md b/tutorial/header-tp-fun.md new file mode 100644 index 0000000..8e3f700 --- /dev/null +++ b/tutorial/header-tp-fun.md @@ -0,0 +1,2 @@ +Exercices et travaux pratiques (version fun !) +============================== diff --git a/tutorial/header-tp.md b/tutorial/header-tp.md new file mode 100644 index 0000000..e910ecb --- /dev/null +++ b/tutorial/header-tp.md @@ -0,0 +1,2 @@ +Exercices et travaux pratiques +============================== diff --git a/tutorial/new-page.md b/tutorial/new-page.md new file mode 100644 index 0000000..16dd787 --- /dev/null +++ b/tutorial/new-page.md @@ -0,0 +1 @@ +\newpage