```yaml
diff --git a/tutorial/devops/tools-drone-cmd.md b/tutorial/devops/tools-drone-cmd.md
index 26d6188..256d21d 100644
--- a/tutorial/devops/tools-drone-cmd.md
+++ b/tutorial/devops/tools-drone-cmd.md
@@ -1,26 +1,36 @@
-Voici à quoi pourrait ressembler la ligne de commande démarrant notre conteneur
-Drone :
+Tout comme Gitea, Drone tire un certain nombre de paramètres depuis son
+environnement. Nous allons donc commencer par indiquer l'identifiant et le
+secret de l'application que l'on a créé précédemment dans Gitea :
```shell
export DRONE_GITEA_CLIENT_ID=#FIXME
export DRONE_GITEA_CLIENT_SECRET=#FIXME
-export DRONE_RPC_SECRET=$(openssl rand -base64 30)
-
-docker container run --name droneci -d \
- -v /var/lib/drone:/data \
- --network gitea -p 80:80 \
- -e DRONE_GITEA_CLIENT_ID -e DRONE_GITEA_CLIENT_SECRET -e DRONE_GITEA_SERVER=http://gitea:3000 \
- -e DRONE_RPC_SECRET -e DRONE_SERVER_HOST=droneci -e DRONE_SERVER_PROTO=http \
- drone/drone:1
-
-docker network connect drone droneci
```
-La dernière commande permet à notre conteneur Drone d'être à la fois présent
-dans le réseau `gitea` et `drone`, ce qui permet de garder les deux réseaux
-distincts.
+Puis, tout comme pour Gitea, nous allons générer un secret. Ce secret est
+utilisé par les différents *worker*s pour s'authentifier :
+
+
+```shell
+docker volume create drone_data
+
+docker container run --name droneci -d -v drone_data:/data --network my_ci_net
+ -p 80:80 -e DRONE_GITEA_CLIENT_ID -e DRONE_GITEA_CLIENT_SECRET \
+ -e DRONE_GITEA_SERVER=http://gitea:3000 -e DRONE_SERVER_PROTO=http \
+ -e DRONE_RPC_SECRET -e DRONE_SERVER_HOST=droneci \
+ drone/drone:2
+```
+
Gardez la variable d'environnement `DRONE_RPC_SECRET` dans un coin, nous en
aurons encore besoin juste après.
diff --git a/tutorial/devops/tools-drone-oauth.md b/tutorial/devops/tools-drone-oauth.md
index ad4f366..945bb2c 100644
--- a/tutorial/devops/tools-drone-oauth.md
+++ b/tutorial/devops/tools-drone-oauth.md
@@ -1,15 +1,7 @@
-::::: {.question}
-
-La version 2 de Drone, encore plus pratique et sympathique est disponible en
-test. Vous pouvez tout à fait l'utiliser pour la suite du TP. Cela ne change
-pas la version des *runners* à utiliser.
-
-:::::
-
-Une fois lancé, rendez-vous sur l'interface de DroneCI :
Vous serez automatiquement redirigé vers la page d'authentification de Gitea,
puis vers l'autorisation OAuth d'accès de Drone à Gitea. Il faut bien
évidemment valider cette demande, afin que Drone ait accès à nos dépôts.
-{width=9cm}
+{width=9cm}
diff --git a/tutorial/devops/tools-drone-runner-ansible.md b/tutorial/devops/tools-drone-runner-ansible.md
index 647b1c1..dd1d239 100644
--- a/tutorial/devops/tools-drone-runner-ansible.md
+++ b/tutorial/devops/tools-drone-runner-ansible.md
@@ -1,4 +1,4 @@
-Voici à quoi pourrait ressembler le playbook Ansible démarrant notre agent Drone :
+Voici à quoi pourrait ressembler le playbook Ansible démarrant notre agent Drone :
```yaml
diff --git a/tutorial/devops/tools-drone-runner-cmd.md b/tutorial/devops/tools-drone-runner-cmd.md
index fff43aa..7e9426e 100644
--- a/tutorial/devops/tools-drone-runner-cmd.md
+++ b/tutorial/devops/tools-drone-runner-cmd.md
@@ -1,11 +1,13 @@
-Voici à quoi pourrait ressembler la ligne de commande démarrant notre agent Drone :
+\
+
+Voici La ligne de commande permettant de démarrer notre agent :
```shell
-docker container run --name droneci-runner -d \
- -v /var/run/docker.sock:/var/run/docker.sock --network drone \
- -e DRONE_RPC_PROTO=http -e DRONE_RPC_HOST=droneci -e DRONE_RPC_SECRET \
- -e DRONE_RUNNER_CAPACITY=2 -e DRONE_RUNNER_NAME=my-runner -e DRONE_RUNNER_NETWORKS=drone,gitea \
+docker container run --name droneci-runner -d --network my_ci_net \
+ -v /var/run/docker.sock:/var/run/docker.sock -e DRONE_RPC_PROTO=http
+ -e DRONE_RPC_HOST=droneci -e DRONE_RPC_SECRET -e DRONE_RUNNER_CAPACITY=2 \
+ -e DRONE_RUNNER_NAME=my-runner -e DRONE_RUNNER_NETWORKS=my_ci_net \
drone/drone-runner-docker:1
```
diff --git a/tutorial/devops/tools-drone-runner-end.md b/tutorial/devops/tools-drone-runner-end.md
new file mode 100644
index 0000000..c19602b
--- /dev/null
+++ b/tutorial/devops/tools-drone-runner-end.md
@@ -0,0 +1,9 @@
+::::: {.more}
+
+On remarquera que l'on partage notre socket Docker : l'exécution de code
+arbitraire n'aura pas lieu directement dans le conteneur, en fait il s'agit
+d'un petit orchetrateur qui lancera d'autres conteneurs en fonction des tâches
+qu'on lui demandera. Le code arbitraire sera donc toujours exécuté dans un
+conteneur moins privilégié.
+
+:::::
diff --git a/tutorial/devops/tools-drone-runner.md b/tutorial/devops/tools-drone-runner.md
index b4d8427..745f014 100644
--- a/tutorial/devops/tools-drone-runner.md
+++ b/tutorial/devops/tools-drone-runner.md
@@ -2,14 +2,13 @@
Notre conteneur `droneci` est uniquement une interface graphique qui va
centraliser d'un côté les nouveaux commits à traiter, et de l'autre les
-résultats retournés par les agents chargés d'exécuter le code.
+résultats retournés par les agents chargés d'exécuter les tâches.
Il serait impensable d'exécuter arbitrairement du code en parallèle d'une
application privilégiée (ici, notre conteneur `droneci` a accès aux dépôts
potentiellement privés de Gitea). Les agents qui sont amenés à traiter du code
-arbitraire s'exécutent à part et peuvent être de différents types. Dans le
-vocabulaire de Drone, on les appelle des ~~blade~~*runners*.
+arbitraire s'exécutent à part et peuvent être de différents types.
-Nous allons lancer un *runner* Docker : il s'agit d'un type d'agent qui va
+Nous allons lancer un *runner* Docker : il s'agit d'un type d'agent qui va
exécuter nos étapes de compilation dans des conteneurs Docker (oui, quand on
-disait que Drone était conçu autour de Docker, c'était pas pour rire !)
+disait que Drone était conçu autour de Docker, c'était pas pour rire !)
diff --git a/tutorial/devops/tools-drone.md b/tutorial/devops/tools-drone.md
index b3d8731..df0be10 100644
--- a/tutorial/devops/tools-drone.md
+++ b/tutorial/devops/tools-drone.md
@@ -8,6 +8,10 @@ Mais nous allons déployer notre propre solution, en utilisant [Drone
CI](https://drone.io/). C'est une solution d'intégration continue libre et
moderne, conçue tout autour de Docker. Idéale pour nous !
+Deux conteneurs sont à lancer : nous aurons d'un côté l'interface de contrôle
+et de l'autre un agent (*runner* dans le vocabulaire de Drone) chargé
+d'exécuter les tests. Dans un environnement de production, on aura généralement
+plusieurs agents, et ceux-ci seront situé sur des machines distinctes.
### Interface de contrôle et de dispatch des tâches
@@ -19,6 +23,8 @@ Drone va avoir besoin d'authentifier les utilisateurs afin d'accéder aux dépô
privés (avec l'autorisation des utilisateurs). Pour cela, comme l'indique la
documentation de Drone, on va utiliser OAuth2 : dans Gitea, il va falloir créer
une *application OAuth2*. Le formulaire de création se trouve dans la
-configuration du compte utilisateur, sous l'onglet *Applications*. Drone aura
-également besoin d'une URL de redirection. Dans notre cas, ce sera :
+configuration du compte utilisateur, sous l'onglet *Applications*.
+
+Drone aura également besoin d'une URL de redirection. Dans notre cas,
+ce sera :\
`http://droneci/login`.
diff --git a/tutorial/devops/tools-end.md b/tutorial/devops/tools-end.md
index 6c4e617..d870359 100644
--- a/tutorial/devops/tools-end.md
+++ b/tutorial/devops/tools-end.md
@@ -1 +1 @@
-L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets !
+L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets !
diff --git a/tutorial/devops/tools-gitea-ansible.md b/tutorial/devops/tools-gitea-ansible.md
index a72b6db..1d33700 100644
--- a/tutorial/devops/tools-gitea-ansible.md
+++ b/tutorial/devops/tools-gitea-ansible.md
@@ -1,13 +1,17 @@
-Votre playbook ressemblera à quelque chose comme ça :
+Votre playbook ressemblera à quelque chose comme ça :
```yaml
-- name: Launch gitea container
+- name: Create a volume for storing repositories
+ docker_volume:
+ name: gitea-data
+
+- name: launch gitea container
docker_container:
name: gitea
image: "gitea/gitea:{{ version }}"
volumes:
- - /var/lib/gitea:/data
+ - gitea-data:/data
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
state: started
@@ -27,3 +31,5 @@ Votre playbook ressemblera à quelque chose comme ça :
SECRET_KEY: "{{ secret_key }}"
```
+
+Plus d'infos sur cette page :
.
diff --git a/tutorial/devops/tools-gitea-cmd.md b/tutorial/devops/tools-gitea-cmd.md
index d522ecc..41b8161 100644
--- a/tutorial/devops/tools-gitea-cmd.md
+++ b/tutorial/devops/tools-gitea-cmd.md
@@ -1,13 +1,33 @@
-La ligne de commande pour lancer Gitea ressemblera à quelque chose comme ça :
+Commençons par créer un nouveau volume `gitea-data`, celui-ci contiendra
+les données de `gitea` (nos dépôts Git, mais également la configuration propre
+à `gitea`) :
+
+
+```shell
+docker volume create gitea-data
+```
+
+
+Afin de simplifier l'installation de notre conteneur, nous allons utiliser un
+maximum de paramètres par défaut. Il faudra toutefois générer une clef secrète
+propre à l'installation. Puisque c'est temporaire, on peut se contenter de ne
+pas la stocker (elle sera perdue si on ferme notre terminal) :
```shell
export SECRET_KEY=$(openssl rand -base64 30)
+```
+
-docker container run --name gitea -d \
- -v /var/lib/gitea:/data -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro \
- --network gitea -p 2222:22 -p 3000:3000 \
- -e RUN_MODE=prod -e DOMAIN=gitea -e SSH_DOMAIN=gitea -e INSTALL_LOCK=true -e SECRET_KEY \
+Pour finir, lançons notre conteneur `gitea` :
+
+
+```shell
+docker container run --name gitea --network my_ci_net -p 2222:22 -p 3000:3000 \
+ -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro \
+ -v gitea-data:/data \
+ -e RUN_MODE=prod -e DOMAIN=gitea -e SSH_DOMAIN=gitea -e INSTALL_LOCK=true \
+ -e SECRET_KEY -d \
gitea/gitea:1
```
diff --git a/tutorial/devops/tools-gitea-end.md b/tutorial/devops/tools-gitea-end.md
index 145979b..e49e266 100644
--- a/tutorial/devops/tools-gitea-end.md
+++ b/tutorial/devops/tools-gitea-end.md
@@ -1,15 +1,15 @@
-Plus d'infos sur cette page :
.
+Une fois le conteneur lancé, vous pouvez accéder à l'interface de votre
+gestionnaire de versions sur le port 3000 de votre machine (à moins que vous
+n'ayez opté pour un autre port).
+\
-Une fois le conteneur lancé, vous pouvez accéder à l'interface de gitea sur le
-port 3000 de votre machine (à moins que vous n'ayez opté pour un autre port).
-
-Vous pouvez ajouter un nouvel administrateur avec la commande suivante :
+Vous pouvez ajouter un nouvel administrateur avec la commande suivante :
```bash
-docker exec gitea gitea admin user create --username "${USER}" --random-password \
- --must-change-password=false --admin --email "${USER}@epita.fr"
+docker exec gitea gitea admin user create --username "${USER}" --admin \
+ --must-change-password=false --random-password --email "${USER}@example.com"
```
-Notez le mot de passe généré pour [vous y connecter](http://localhost:3000/user/login).
+Notez le mot de passe généré pour ensuite vous y connecter.
diff --git a/tutorial/devops/tools-gitea.md b/tutorial/devops/tools-gitea.md
index 0875f82..1bbd35a 100644
--- a/tutorial/devops/tools-gitea.md
+++ b/tutorial/devops/tools-gitea.md
@@ -21,7 +21,7 @@ que l'on peut lier avec ses dépôts. Une fonctionnalité que GitLab propose
En effet, la problématique du stockage des produits de compilation est
vaste. Si au début on peut se satisfaire d'un simple serveur web/FTP/SSH pour
les récupérer manuellement, on a vite envie de pouvoir utiliser les outils
-standards directement : `docker pull ...`, `npm install ...`, ...
+standards directement : `docker pull ...`, `npm install ...`, ...
Des programmes et services se sont spécialisés là-dedans, citons notamment
[Artifactory](https://jfrog.com/artifactory/) ou [Nexus
@@ -33,11 +33,11 @@ Dans un premier temps, nous allons nous contenter de publier un binaire associé
### Installation et configuration
-Allez c'est parti ! première chose à faire : installer et configurer
+Allez c'est parti ! première chose à faire : installer et configurer
[Gitea](https://gitea.io/) (ceux qui le souhaitent peuvent choisir
[gitlab](https://gitlab.org/) ou une autre plate-forme, mais la suite sera
moins guidée).
-Nous allons utiliser l'image :
+Nous allons utiliser l'image :
[`gitea/gitea`](https://hub.docker.com/r/gitea/gitea) (ou
[`gitlab/gitlab-ce`](https://hub.docker.com/r/gitlab/gitlab-ce)).
diff --git a/tutorial/devops/what-ansible.md b/tutorial/devops/what-ansible.md
new file mode 100644
index 0000000..9d95222
--- /dev/null
+++ b/tutorial/devops/what-ansible.md
@@ -0,0 +1,16 @@
+## Préparer le terrain
+
+Tous les déploiements sont à faire sur votre machine en utilisant des
+conteneurs Docker, qui seront regroupés au sein de réseaux
+Docker. Cela vous permettra d’utiliser la résolution de noms entre vos
+conteneurs.
+
+Dans votre playbook Ansible, vous pourrez procéder ainsi :
+
+
+```yaml
+- name: Create virli network
+ docker_network:
+ name: virli3
+```
+
diff --git a/tutorial/devops/what-cmd.md b/tutorial/devops/what-cmd.md
new file mode 100644
index 0000000..7575395
--- /dev/null
+++ b/tutorial/devops/what-cmd.md
@@ -0,0 +1,15 @@
+## Préparer le terrain
+
+Tous les déploiements sont à faire sur votre machine ; la plate-forme de CI
+utilisera massivement les conteneurs Docker, qui seront regroupés au sein de
+réseaux Docker : cela nous permettra de profiter de la résolution de noms entre
+les conteneurs.
+
+Dès à présent, nous pouvons commencer par créer un réseau, dans lequel nous
+placerons tous nos conteneurs de CI/CD :
+
+
+```shell
+docker network create my_ci_net
+```
+
diff --git a/tutorial/devops/what-gistre.md b/tutorial/devops/what-gistre.md
index 2969908..6c1a992 100644
--- a/tutorial/devops/what-gistre.md
+++ b/tutorial/devops/what-gistre.md
@@ -3,7 +3,7 @@
Électropcool
============
-Bienvenue dans la société Électropcool !
+Bienvenue dans la société Électropcool !
Électropcool est une société française spécialisée dans
l'[immotique](https://fr.wikipedia.org/wiki/Immotique), elle vend des
@@ -20,14 +20,14 @@ en combustible (liés à la météo)[^HOMEASSISTANT].
[^HOMEASSISTANT]: Si ça vous met l'eau à la bouche, jettez un œil du côté du
projet
qui fait un peu moins de
- *bullshit*, mais est bien réel !
+ *bullshit*, mais est bien réel !
La principale difficulté que rencontre Électropcool est qu'aucun bâtiment ne
dispose des mêmes références de pièces et qu'en dehors des nouveaux bâtiments
pour lesquels la société peut imposer des équipements électroniques
spécifiquement supportés et compatibles avec la plate-forme qu'elle vend, il lui
est bien souvent nécessaire de faire des développements spécifiques pour
-s'interfacer avec de l'électronique existant : c'est notamment le cas pour les
+s'interfacer avec de l'électronique existant : c'est notamment le cas pour les
chaudières et les
[VMC](https://fr.wikipedia.org/wiki/Ventilation_m%C3%A9canique_contr%C3%B4l%C3%A9e),
qui, compte tenu de leur coût de remplacement prohibitif, nécessitent souvent
@@ -74,7 +74,7 @@ retiendrez.)
\
Le projet qui vous servira de base pour vos tests sera
-[`linky2influx`](https://git.nemunai.re/nemunaire/linky2influx) : à partir d'un
+[`linky2influx`](https://git.nemunai.re/nemunaire/linky2influx) : à partir d'un
compteur [Linky](https://fr.wikipedia.org/wiki/Linky), branché sur les bornes
de [téléinformation client du
compteur](https://hallard.me/demystifier-la-teleinfo/) et [lisant le
@@ -92,36 +92,3 @@ gestionnaire de versions.
Nous testerons enfin différentes solution pour déployer notre binaire, afin
d'établir quelle est la solution adéquate.
-
-
-## Préparer le terrain
-
-Tous les déploiements sont à faire sur votre machine et la plate-forme de CI
-utilisera massivement les conteneurs Docker, qui seront regroupés au sein de
-réseaux Docker. Cela vous permettra d'utiliser la résolution de noms entre vos
-conteneurs.
-
-Vous devriez dès maintenant créer les deux réseaux suivants sur votre machines :
-
-
-```shell
-docker network create gitea
-docker network create drone
-```
-
-
-
-Étant donné que votre machine ne dispose pas de domaine sur Internet et que
-l'on va essayer de simplifier au maximum l'installation, vous devriez ajouter
-cette ligne à votre fichier `/etc/hosts` (ou
-`\Windows\System32\drivers\etc\hosts`) :
-
-
-```conf
-127.0.0.1 gitea droneci
-```
-
-
-Cette ligne va vous permettre de résoudre les noms des conteneurs. Cela
-permettra aux requêtes OAuth de se faire de manière transparente pour vous
-lorsque vous serez dans votre navigateur.
diff --git a/tutorial/devops/what-hosts.md b/tutorial/devops/what-hosts.md
new file mode 100644
index 0000000..53dc91f
--- /dev/null
+++ b/tutorial/devops/what-hosts.md
@@ -0,0 +1,14 @@
+Étant donné que votre machine ne dispose pas de domaine sur Internet et que
+l'on va essayer de simplifier au maximum l'installation, vous devriez ajouter
+cette ligne à votre fichier `/etc/hosts` (ou
+`\Windows\System32\drivers\etc\hosts`) :
+
+
+```conf
+127.0.0.1 gitea droneci
+```
+
+
+Cette ligne va vous permettre de résoudre les noms des conteneurs. Cela
+permettra aux requêtes OAuth de se faire de manière transparente pour vous
+lorsque vous serez dans votre navigateur.
diff --git a/tutorial/devops/what-srs.md b/tutorial/devops/what-srs.md
new file mode 100644
index 0000000..aa2a3db
--- /dev/null
+++ b/tutorial/devops/what-srs.md
@@ -0,0 +1,32 @@
+\newpage
+
+But du TP
+=========
+
+Nous allons nous mettre aujourd’hui dans la peau d’une équipe DevOps et
+réaliser une solution complète d’intégration/déploiement continu (le fameux
+CI/CD, pour *Continuous Integration* et *Continuous Delivery*).
+
+Le résultat attendu d’ici la fin de cette partie sera de mettre en place toutes
+les briques décrites dans la section précédente.
+\
+
+Nous allons commencer par automatiser le projet `youp0m`, plus simple, ~~puis
+la plate-forme du FIC dans son ensemble, ce qui représente un petit challenge~~
+(merci Nabih !).
+
+Il est également attendu que vous rendiez un playbook Ansible, permettant de
+retrouver un environnement similaire. Car on pourra s’en resservir par la
+suite.
+\
+
+Dans un premier temps, on voudra juste compiler notre projet, pour s’assurer
+que chaque commit poussé ne contient pas d’erreur de compilation, dans
+l’environnement défini comme étant celui de production. Ensuite, on ajoutera
+quelques tests automatiques. Puis nous publierons automatiquement le binaire
+`youp0m` comme fichier associé à un tag au sein de l’interface web du
+gestionnaire de versions.
+
+Enfin, nous mettrons en place un registre Docker qui nous permettra de publier
+automatiquement l’image Docker associée. C’est à partir de cette image Docker
+que l’on va commencer à déployer automatiquement...
diff --git a/tutorial/devops/what.md b/tutorial/devops/what.md
index 550bc66..2b8cb33 100644
--- a/tutorial/devops/what.md
+++ b/tutorial/devops/what.md
@@ -1,64 +1,25 @@
\newpage
-But du TP
-=========
+La journée DevOps
+=================
-Nous allons nous mettre aujourd'hui dans la peau d'une équipe DevOps et
+Nous allons maintenant nous mettre dans la peau d'une équipe DevOps et
réaliser une solution complète d'intégration/déploiement continu (le fameux
CI/CD, pour *Continuous Integration* et *Continuous Delivery*).
Le résultat attendu d'ici la fin de cette partie sera de mettre en place toutes
-les briques décrites dans la section précédente.
-\
-
-Nous allons commencer par automatiser le projet `youp0m`, plus simple, ~~puis
-la plate-forme du FIC dans son ensemble, ce qui représente un petit challenge~~
-(merci Nabih !).
-
-Il est également attendu que vous rendiez un playbook Ansible, permettant de
-retrouver un environnement similaire. Car on pourra s'en resservir par la suite.
+les briques décrites au chapitre précédent. Nous allons pour cela automatiser
+le projet `youp0m`, que l'on connaît déjà bien.
\
Dans un premier temps, on voudra juste compiler notre projet, pour s'assurer
-que chaque commit poussé ne contient pas d'erreur de compilation, dans
-l'environnement défini comme étant celui de production. Ensuite, on ajoutera
-quelques tests automatiques. Puis nous publierons automatiquement le binaire
-`youp0m` comme fichier associé à un tag au sein de l'interface web du
-gestionnaire de versions.
+que chaque *commmit* poussé ne contient pas d'erreur de compilation (dans
+l'environnement défini comme étant celui de production, donc avec une version
+précise des outils de compilation). Ensuite, nous ajouterons quelques tests
+automatiques, puis nous publierons automatiquement le binaire `youp0m` comme
+fichier associé à un tag au sein de l'interface web d'un gestionnaire de
+versions.
Enfin, nous mettrons en place un registre Docker qui nous permettra de publier
automatiquement l'image Docker associée. C'est à partir de cette image Docker
que l'on va commencer à déployer automatiquement...
-
-
-## Préparer le terrain
-
-Tous les déploiements sont à faire sur votre machine en utilisant des
-conteneurs Docker, qui seront regroupés au sein de réseaux Docker. Cela vous
-permettra d'utiliser la résolution de noms entre vos conteneurs.
-
-Dans votre playbook Ansible, vous pourrez procéder ainsi :
-
-
-```yaml
-- name: Create virli network
- docker_network:
- name: virli3
-```
-
-
-
-Étant donné que votre machine ne dispose pas de domaine sur Internet et que
-l'on va essayer de simplifier au maximum l'installation, vous devriez ajouter
-cette ligne à votre fichier `/etc/hosts` (ou
-`\Windows\System32\drivers\etc\hosts`) :
-
-
-```conf
-127.0.0.1 gitea droneci
-```
-
-
-Cette ligne va vous permettre de résoudre les noms des conteneurs. Cela
-permettra aux requêtes OAuth de se faire de manière transparente pour vous
-lorsque vous serez dans votre navigateur.
diff --git a/tutorial/docker-advanced/compose.md b/tutorial/docker-advanced/compose.md
index 07978d1..864af3d 100644
--- a/tutorial/docker-advanced/compose.md
+++ b/tutorial/docker-advanced/compose.md
@@ -57,7 +57,7 @@ run`.
Cette section est le pendant de la commandes `docker volume`.
On déclare les volumes simplement en leur donnant un nom et un driver comme
-suit :
+suit :
```yaml
@@ -68,7 +68,7 @@ volumes:
Pour les utiliser avec un conteneur, on référence le nom ainsi que
-l'emplacement à partager :
+l'emplacement à partager :
```yaml
@@ -87,10 +87,10 @@ Cette section est le pendant de la commandes `docker network`.
Par défaut, Docker relie tous les conteneurs sur un bridge et fait du NAT pour
que les conteneurs puissent accéder à l'Internet. Mais ce n'est pas le seul
-mode possible !
+mode possible !
De la même manière que pour les `volumes`, cette section déclare les réseaux
-qui pourront être utilisés par les `services`. On pourrait donc avoir :
+qui pourront être utilisés par les `services`. On pourrait donc avoir :
```yaml
@@ -133,12 +133,14 @@ lié, même après que l'on ait démarré. La résolution se fera dynamiquement.
#### Utiliser le `docker-compose.yml`
-Consultez
-[la documentation](https://docs.docker.com/compose/compose-file/) pour
-une liste exhaustive des options que nous pouvons utiliser.
+Consultez la documentation[^COMPOSEDOC] pour une liste exhaustive des options
+que nous pouvons utiliser.
+
+[^COMPOSEDOC]: La documentation des `docker-compose.yml` :
+
Une fois que notre `docker-compose.yml` est prêt, nous pouvons lancer
-la commande suivante et admirer le résultat :
+la commande suivante et admirer le résultat :
```bash
diff --git a/tutorial/docker-advanced/manual.md b/tutorial/docker-advanced/manual.md
index 771c665..b5db30c 100644
--- a/tutorial/docker-advanced/manual.md
+++ b/tutorial/docker-advanced/manual.md
@@ -6,9 +6,8 @@ Lier des conteneurs
Avant de voir des méthodes plus automatiques pour déployer toute notre pile
logicielle TICK, nous allons commencer par mettre en place et lier les
conteneurs manuellement, de la même manière que nous avons pu le faire avec
-l'interface d'administration du FIC et MySQL. Cela nous permettra de voir les
-subtilités de chaque image, ce qui nous fera gagner du temps pour ensuite
-en faire la description.
+MySQL. Cela nous permettra de voir les subtilités de chaque image, ce qui nous
+fera gagner du temps pour ensuite en faire la description.
### Conteneur central : la base de données
@@ -58,7 +57,8 @@ le client officiel (le binaire s'appelle `influx`) :
```
-42sh$ docker container run --rm -it --link mytsdb:influxdb influxdb:1.8 influx -host influxdb
+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
> show databases
@@ -69,10 +69,10 @@ _internal
```
-Si vous aussi vous voyez la table `_internal`, bravo ! vous pouvez passer à la
+Si vous aussi vous voyez la table `_internal`, bravo ! vous pouvez passer à la
suite.
-#### Mais quelle était cette commande magique ? {-}
+#### Mais quelle était cette commande magique ? {-}
Oui, prenons quelques minutes pour l'analyser ...
@@ -132,7 +132,9 @@ système. Pour cela, on commence par télécharger *Telegraf* :
```bash
-curl https://dl.influxdata.com/telegraf/releases/telegraf-1.19.2_linux_amd64.tar.gz | \
+V=1.19.2
+P=telegraf-${V}_linux_$(uname -m)
+curl https://dl.influxdata.com/telegraf/releases/${P}.tar.gz | \
tar xzv -C /tmp
```
@@ -157,7 +159,8 @@ Et observons ensuite :
```bash
-42sh$ docker container run --rm -it --link mytsdb:zelda influxdb:1.8 influx -host zelda
+42sh$ docker container run --rm -it --link mytsdb:zelda influxdb:1.8 \
+ influx -host zelda
InfluxDB shell version: 1.8.9
> show databases
name: databases
@@ -205,6 +208,6 @@ si besoin.
la page d'accueil est vide au démarrage, pour savoir si vous avez réussi,
rendez-vous sous l'onglet *Hosts*, le nom de votre machine devrait y
apparaître. En cliquant dessus, vous obtiendrez des graphiques similaires à
-ceux ci-dessous :
+ceux ci-après :

diff --git a/tutorial/docker-advanced/rendu.md b/tutorial/docker-advanced/rendu.md
index da25c27..f41d796 100644
--- a/tutorial/docker-advanced/rendu.md
+++ b/tutorial/docker-advanced/rendu.md
@@ -7,7 +7,7 @@ Projet
------
Réalisez le `docker-compose.yml` permettant de lancer toute notre stack de
-monitoring, d'un simple :
+monitoring, d'un simple :
```
@@ -49,10 +49,10 @@ Tarball
-------
Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
-placer dans une tarball (pas d'archive ZIP, RAR, ...).
+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) :
+cela dépendra de votre avancée dans le projet) :
```
@@ -66,7 +66,7 @@ login_x-TP1/...
## Signature du rendu
-Deux méthodes sont utilisables pour signer votre rendu :
+Deux méthodes sont utilisables pour signer votre rendu :
* signature du courriel ;
* signature de la tarball.
@@ -93,7 +93,7 @@ signature.
#### No public key
-Si vous recevez un rapport avec l'erreur suivante :
+Si vous recevez un rapport avec l'erreur suivante :
```
@@ -116,7 +116,7 @@ rendu.
#### Not explicit username
-Si vous recevez un rapport avec l'erreur suivante :
+Si vous recevez un rapport avec l'erreur suivante :
```
@@ -131,7 +131,7 @@ données.
#### I've decided to skip your e-mail
-Si vous recevez un rapport concluant ainsi :
+Si vous recevez un rapport concluant ainsi :
```
diff --git a/tutorial/docker-advanced/security.md b/tutorial/docker-advanced/security.md
index 0f7326a..31cecfe 100644
--- a/tutorial/docker-advanced/security.md
+++ b/tutorial/docker-advanced/security.md
@@ -5,7 +5,7 @@ Contenir les applications pour éviter les fuites
Lorsque l'on gère un environnement de production, on souhaite bien
évidemment éviter tout déni de service. Ou parfois, contenir un
-programme métier avec une fuite mémoire, dans certaines limites : il
+programme métier avec une fuite mémoire, dans certaines limites : il
vaut parfois mieux le tuer et le relancer automatiquement, plutôt que
d'attendre que potentiellement un autre processus se fasse tuer à sa
place.
@@ -44,7 +44,7 @@ l'ordonnanceur privilégiant alors les autres processus du système.
Par défaut, le taux maximal (1024 = 100%) d'utilisation CPU est donné
aux nouveaux conteneurs, on peut le réduire en utilisant l'option
-`-c`/`--cpu-shares` : 512 = 50%, par exemple.
+`-c`/`--cpu-shares` : 512 = 50%, par exemple.
## Sécuriser l'exécution
@@ -76,14 +76,14 @@ du noyau, seccomp est un filtre que l'on peut définir pour chaque
appel système. Liste blanche, liste noire, tout est possible.
Docker filtre notamment tous les appels systèmes qui pourraient
-déborder à l'extérieur du conteneur : il n'est par exemple pas
+déborder à l'extérieur du conteneur : il n'est par exemple pas
possible de changer l'heure dans un conteneur, car il n'y a
aujourd'hui aucun mécanisme pour isoler les visions des dates d'un
conteneur à l'autre.
Voici par exemple un fichier de profil seccomp, interdisant
l'utilisation de l'appel système `nanosleep(2)` (utilisé notamment par
-`sleep(1)`) :
+`sleep(1)`) :
```js
@@ -105,11 +105,11 @@ l'utilisation de l'appel système `nanosleep(2)` (utilisé notamment par
```
-On peut ensuite l'appliquer à un conteneur Docker :
+On peut ensuite l'appliquer à un conteneur Docker :
```
-42sh$ docker container run -it --security-opt seccomp=nanosleep.json ubuntu /bin/bash
+42sh$ docker run -it --security-opt seccomp=nanosleep.json ubuntu /bin/bash
(cntnr)$ sleep 42
sleep: cannot read realtime clock: Operation not permitted
```
diff --git a/tutorial/docker-advanced/setup.md b/tutorial/docker-advanced/setup.md
index 188f46c..b70aa5a 100644
--- a/tutorial/docker-advanced/setup.md
+++ b/tutorial/docker-advanced/setup.md
@@ -3,11 +3,10 @@
Mise en place
-------------
-Dans la première partie du TP, nous avons installé l'environnement Docker
-principal, qui inclut le client, le daemon et toute sa machinerie. Mais le
-projet Docker propose de nombreuses autres ressources, souvent directement
-trouvées dans les usages de la communauté, et parfois même appropriées par
-Docker.
+Jusqu'ici, nous avons utilisé l'environnement Docker principal, qui inclut le
+client, le daemon et toute sa machinerie. Mais le projet Docker propose de
+nombreuses extensions, souvent directement trouvées dans les usages de la
+communauté, et parfois même appropriées par Docker.
### `docker-compose`
@@ -16,8 +15,8 @@ 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. Il constitue aujourd'hui une brique de l'écosystème
-Docker, presque indispensable !
+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
@@ -26,28 +25,17 @@ fonctionnera avec la version de Docker qu'ils fournissent.
#### Par la distribution binaire
-L'équipe en charge de Docker compose met à disposition un exécutable contenant
-tous les scripts. Nous pouvons l'installer en suivant la procédure suivante :
+L'équipe en charge du projet met à disposition un exécutable que nous pouvons
+téléchargeant depuis
.
-
-```bash
-curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64 \
- > /usr/bin/docker-compose
-chmod +x /usr/bin/docker-compose
-```
-
-
-#### `pip`
-
-Le projet étant écrit en Python, il est également disponible via `pip`, si vous
-préférez cette méthode. N'oubliez pas de préciser une version compatible avec
-votre version de Docker.
+Ajoutez l'exécutable dans le dossier des plugins : `$HOME/.docker/cli-plugins`
+(sans oublier de `chmod +x` !).
#### Vérification du fonctionnement
Comme avec Docker, nous pouvons vérifier le bon fonctionnement de
-`docker-compose` en exécutant la commande :
+`docker-compose` en exécutant la commande :
```
@@ -56,13 +44,13 @@ docker-compose version: 1.29.2
```
-Si vous obtenez une réponse similaire, c'est que vous êtes prêt à commencer le
-TP ! Alors n'attendons pas, partons à l'aventure !
+Si vous obtenez une réponse similaire, c'est que vous êtes prêt à continuer !
+Alors n'attendons pas, partons à l'aventure !
### Play With Docker
Tout comme pour la partie précédente, si vous avez des difficultés pour
-réaliser les exercices sur vos machines, vous pouvez utiliser le projet [Play
+réaliser les exercices sur votre machine, vous pouvez utiliser le projet [Play
With Docker](https://play-with-docker.com/) qui vous donnera accès à un bac à
-sable avec lequel vous pourrez réaliser tous les exercices de ce TP.
+sable avec lequel vous pourrez réaliser tous les exercices.
diff --git a/tutorial/docker-advanced/tutorial.md b/tutorial/docker-advanced/tutorial.md
index 9ae5026..4e49a12 100644
--- a/tutorial/docker-advanced/tutorial.md
+++ b/tutorial/docker-advanced/tutorial.md
@@ -6,7 +6,7 @@ institute: EPITA
date: Mercredi 2 octobre 2019
abstract: |
Dans cette deuxième partie du TP, nous allons apprendre à déployer
- un groupe de conteneurs !
+ un groupe de conteneurs !
\vspace{1em}
diff --git a/tutorial/docker-advanced/what.md b/tutorial/docker-advanced/what.md
index 380051d..c577fd0 100644
--- a/tutorial/docker-advanced/what.md
+++ b/tutorial/docker-advanced/what.md
@@ -6,9 +6,9 @@ Orchestrer un groupe de conteneurs
Maintenant que nous savons démarrer individuellement des conteneurs et les lier
entre-eux, nous allons voir une première manière d'automatiser cela.
-Plutôt que de lancer les commandes `docker` comme nous l'avons fait jusque là :
+Plutôt que de lancer les commandes `docker` comme nous l'avons fait jusque là :
soit directement dans un terminal, soit via un script, nous allons décrire
-l'état que nous souhaitons atteindre : quels images lancer, quels volumes
+l'état que nous souhaitons atteindre : quels images lancer, quels volumes
créer, quels réseaux, etc. Cette description peut s'utiliser pour lancer un
conteneur seul, mais elle prend tout son sens lorsqu'il faut démarrer tout un
groupe de conteneurs qui fonctionnent de concert, parfois avec des dépendances
@@ -16,7 +16,7 @@ groupe de conteneurs qui fonctionnent de concert, parfois avec des dépendances
démarrer).
On parle d'orchestration, car nous allons utiliser Docker comme un chef
-d'orchestre : il va ordonner les créations des différents objets (volumes,
+d'orchestre : il va ordonner les créations des différents objets (volumes,
réseaux, conteneurs, ...) afin d'arriver au résultat attendu, puis il va faire
en sorte de maintenir ce résultat selon les événements qui pourront survenir.
diff --git a/tutorial/docker-basis/Makefile b/tutorial/docker-basis/Makefile
index 9f71daa..8e23792 100644
--- a/tutorial/docker-basis/Makefile
+++ b/tutorial/docker-basis/Makefile
@@ -1,6 +1,6 @@
include ../pandoc-opts.mk
-SOURCES = tutorial.md installation.md what.md first.md cleaning.md ex-flask.md volumes.md linking.md
+SOURCES = tutorial.md installation.md what.md first.md cleaning.md ex-flask.md volumes.md linking.md linking-ex-fic.md linking-ex-help.md
all: tutorial.pdf
diff --git a/tutorial/docker-basis/cleaning.md b/tutorial/docker-basis/cleaning.md
index fb4d76f..ae6c2c2 100644
--- a/tutorial/docker-basis/cleaning.md
+++ b/tutorial/docker-basis/cleaning.md
@@ -17,19 +17,19 @@ l'option `--rm`.
### Conteneurs
Nous pouvons afficher l'ensemble des conteneurs, quel que soit leur état (en
-cours d'exécution, arrêtés,\ ...) avec la commande suivante :
+cours d'exécution, arrêtés, ...) avec la commande suivante :
```
42sh$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
-552d71619723 hello-world "/hello" 4 days ago Exited (0) 4 days ago dreamy_gates
-0e8bbff6d500 debian "/bin/bash" 2 weeks ago Exited (0) 2 weeks ago cranky_jones
+552d71619723 hello-world "/hello" 4 days ago Exited (0) 4 days ago dreamy_g
+0e8bbff6d500 debian "/bin/bash" 2 weeks ago Exited (0) 2 weeks ago cranky_j
```
Il y a de fortes chances pour que vous n'ayez plus besoin de ces vieux
-conteneurs. Pour les supprimer, utilisez la commande :
+conteneurs. Pour les supprimer, utilisez la commande :
```bash
@@ -37,7 +37,7 @@ docker container rm 0e8bbff6d500 552d71619723
```
-ou encore :
+ou encore :
```bash
@@ -57,7 +57,7 @@ de la même manière que les conteneurs, avec les sous-commandes `docker image`.
### `prune`
Dans la plupart des menus permettant de gérer les objets Docker, vous trouverez
-une commande `prune` qui supprimera les objets inutilisés :
+une commande `prune` qui supprimera les objets inutilisés :
```bash
@@ -65,7 +65,7 @@ docker container prune
```
-On aura tendance à vouloir supprimer tous les objets inutiles d'un seul coup, via :
+On aura tendance à vouloir supprimer tous les objets inutiles d'un seul coup, via :
```bash
diff --git a/tutorial/docker-basis/discover.md b/tutorial/docker-basis/discover.md
index d779590..69494bd 100644
--- a/tutorial/docker-basis/discover.md
+++ b/tutorial/docker-basis/discover.md
@@ -2,3 +2,15 @@
Découvrons Docker
=================
+
+Entrons sans plus attendre dans le vif du sujet : 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é. Aujourd'hui de nombreuses
+entreprises n'hésitent plus à l'utiliser en production.
+
+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
+nous lancerons notre premier conteneur et nous irons jusqu'à déployer
+un premier service web avec lequel nous pourrons interagir.
diff --git a/tutorial/docker-basis/ex-flask.md b/tutorial/docker-basis/ex-flask.md
index 8e80950..da34f12 100644
--- a/tutorial/docker-basis/ex-flask.md
+++ b/tutorial/docker-basis/ex-flask.md
@@ -3,13 +3,13 @@
Mon premier webservice
----------------------
-C'est parti, nous allons déployer notre premier service !
+C'est parti, nous allons déployer notre premier service !
Il s'agit d'un service montrant une image aléatoire à chaque chargement de
-page :
.
+page :
.
-Nous pouvons télécharger et lancer le service grâce à :
+Nous pouvons télécharger et lancer le service grâce à :
```bash
@@ -17,22 +17,22 @@ docker container run -i nemunaire/youp0m
```
-Cette fois-ci, ce n'est pas un shell que nous obtenons[^defaultcmd] : il semblerait que le
-service soit lancé et écoute sur le port 8080. Est-ce le cas ?
+Cette fois-ci, ce n'est pas un shell que nous obtenons[^defaultcmd] : il semblerait que le
+service soit lancé et écoute sur le port 8080. Est-ce le cas ?
-[^defaultcmd]: Chaque conteneur dispose d'une commande par défaut : les images
+[^defaultcmd]: Chaque conteneur dispose d'une commande par défaut : les images
de base telles que les distributions vont lancer un shell, tandis que les
conteneurs de service vont lancer leur service directement.
-Non ! Car le service est contenerisé ! Il s'exécute dans son coin, sans
+Non ! Car le service est contenerisé ! Il s'exécute dans son coin, sans
interférer avec son hôte.
### Redirection de ports
-Nous pouvons rediriger le port avec l'argument `-p dst_host:src_cntr` :
+Nous pouvons rediriger le port avec l'argument `-p dst_host:src_cntr` :
```bash
@@ -43,7 +43,7 @@ docker container run -i -p 8080:8080 nemunaire/youp0m
Cette fois, nous pouvons accéder au service.
Pour le moment, le service ne dispose d'aucune image à afficher, vous pouvez
-utiliser cette syntaxe pour ajouter une image :
+utiliser cette syntaxe pour ajouter une image :
```bash
@@ -51,7 +51,7 @@ base64 monimage.jpg | curl --data @- http://localhost:8080/api/images/monimage
```
-Si vous n'êtes pas particulièrement inspiré, vous pouvez ajouter ces images :
+Si vous n'êtes pas particulièrement inspiré, vous pouvez ajouter ces images :
```bash
@@ -63,13 +63,13 @@ done
-### Prêt pour la production ?
+### Prêt pour la production ?
Avec l'option `-i`, nous pouvons encore transmettre les signaux de terminaison
au conteneur. C'est pratique lorsque l'on développe, mais en production, notre
-service ne s'exécutera pas dans notre terminal !
+service ne s'exécutera pas dans notre terminal !
-On utilise l'option `-d` pour lancer le conteneur en tâche de fond :
+On utilise l'option `-d` pour lancer le conteneur en tâche de fond :
```bash
@@ -79,7 +79,7 @@ docker container run -d -p 8080:8080 nemunaire/youp0m
À partir de l'identifiant renvoyé par cette commande (que l'on peut également
obtenir avec un `docker container ls`), nous pouvons consulter les logs du
-service (en fait, les sorties standard et d'erreur) :
+service (en fait, les sorties standard et d'erreur) :
```bash
@@ -88,15 +88,15 @@ docker container logs 0123456789abcdef
-### Une autre instance ?
+### Une autre instance ?
Maintenant que nous avons un clone de
, nous voulons
-absolument un clone de
!
+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
@@ -104,10 +104,10 @@ docker container run -d -p 8081:8080 nemunaire/youp0m
```
-Voyons le résultat :
+Voyons le résultat :
Nous avons réussi à lancer deux conteneurs à partir de la même image, et on
-voit bien que ceux-ci ne partagent pas leur système de fichiers : notre
+voit bien que ceux-ci ne partagent pas leur système de fichiers : notre
nouvelle instance est encore immaculée.
@@ -123,18 +123,19 @@ Outre les arguments que l'on peut passer au premier processus du conteneur, la
plupart des images peuvent adapter leur comportement en fonction de variables
d'environnement que l'on passe en paramètre.
-Cette bonne pratique est recommandée par , qui détaille
-les raisons qui devraient pousser les développeurs à privilégier les variables
-d'environnements aux arguments sur la ligne de commande.
+Cette bonne pratique est recommandée par
+[`12factor.net`](https://12factor.net/), qui détaille les raisons qui devraient
+pousser les développeurs à privilégier les variables d'environnements aux
+arguments sur la ligne de commande.
Il se trouve que les conteneurs `youp0m` peuvent créer le fichier `htpasswd`,
-s'ils sont démarrés avec les variables d'environnement :
+s'ils sont démarrés avec les variables d'environnement :
- - `YOUP0M_USERNAME` : nom d'utilisateur pour l'administrateur (par défaut admin) ;
- - `YOUP0M_PASSWORD` : mot de passe de l'utilisateur.
+ - `YOUP0M_USERNAME` : nom d'utilisateur pour l'administrateur (par défaut admin) ;
+ - `YOUP0M_PASSWORD` : mot de passe de l'utilisateur.
Pour ajouter une variable d'environnement, cela se passe dans la commande
-`run`, en ajoutant une ou plusieurs options `-e` :
+`run`, en ajoutant une ou plusieurs options `-e` :
```bash
@@ -143,13 +144,14 @@ docker container run -e YOUP0M_PASSWORD=foobar -p 8080:8080 nemunaire/youp0m
Une fois lancé, ce conteneur exposera une interface d'administration à cette
-adresse : .
+adresse :\
+.
### Arrêt des conteneurs et persistance des données
Lorsque l'on souhaite stopper un conteneur lancé en tâche de fond, on utilise
-son identifiant dans la commande suivante :
+son identifiant dans la commande suivante :
```bash
diff --git a/tutorial/docker-basis/ex-owncloud.md b/tutorial/docker-basis/ex-owncloud.md
index ebaee74..4f33bf4 100644
--- a/tutorial/docker-basis/ex-owncloud.md
+++ b/tutorial/docker-basis/ex-owncloud.md
@@ -1,7 +1,5 @@
-\newpage
-
-Exercice
-========
+Exercice {-}
+--------
Pour mettre en pratiques toutes les notions que l'on a vu jusque là, écrivez un
script `mycloud-run.sh` pour automatiser le lancement de votre instance
@@ -16,25 +14,26 @@ pour se rendre sur la page de connexion. Une autre machine de votre réseau
local devrait également pouvoir accéder à la plate-forme, simplement en
renseignant l'IP de votre machine et en ajoutant éventuellement des règles de
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
+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 dans la
-seconde partie). 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.
+(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 vos soins
-dans un autre conteneur) et contenir ses données dans un ou plusieurs volumes
-(afin qu'elles persistent à une mise à jour des conteneurs par exemple).
+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
+volumes (afin qu'elles persistent à une mise à jour des conteneurs par
+exemple).
L'exécution doit être la plus sécurisée possible (pas de port MySQL exposé sur
l'hôte par exemple, etc.) et la plus respectueuse des bonnes pratiques que l'on
-a pu voir durant ce premier cours.
+a pu voir jusque là.
-### Exemple d'exécution
+### Exemple d'exécution {-}
```bash
diff --git a/tutorial/docker-basis/first.md b/tutorial/docker-basis/first.md
index 1ae0d08..b415962 100644
--- a/tutorial/docker-basis/first.md
+++ b/tutorial/docker-basis/first.md
@@ -4,7 +4,7 @@ Mon premier conteneur
---------------------
Afin de tester la bonne marche de notre installation, lançons notre premier
-conteneur avec la commande\ :
+conteneur avec la commande :
```bash
@@ -13,7 +13,7 @@ docker container run hello-world
Cette commande va automatiquement exécuter une série d'actions pour nous,
-comme indiqué dans le message affiché en retour :
+comme indiqué dans le message affiché en retour :
D'abord, le daemon va rechercher s'il possède localement l'image
*hello-world*. Si ce n'est pas le cas, il va aller récupérer les différentes
@@ -23,7 +23,7 @@ conteneur. Enfin, il lance la commande par défaut, telle que définie dans les
métadonnées de l'image.
Nous pouvons directement utiliser le client pour rechercher une image sur le
-registre, en utilisant la commande `search` :
+registre, en utilisant la commande `search` :
```bash
@@ -32,7 +32,7 @@ docker search mariadb
Il est possible de mettre à jour les images locales, ou télécharger les couches
-d'images qui nous intéressent, en utilisant la commande `pull` :
+d'images qui nous intéressent, en utilisant la commande `pull` :
```bash
@@ -41,40 +41,42 @@ docker image pull ubuntu
-#### Attention {-}
+::::: {.warning}
Les registres publics tels quel le Docker Hub mettent à disposition des images
-officielles, mais aussi des images créés par la communauté. Chaque utilisateur
-est libre d'envoyer une image qu'il a lui-même créée : soit car l'éditeur ne
+officielles, mais aussi des images créées par la communauté. Chaque utilisateur
+est libre d'envoyer une image qu'il a lui-même créé : soit car l'éditeur ne
proposait pas d'image et que quelqu'un s'est dévoué pour la faire, soit parce
qu'il avait des besoins plus spécifiques qui n'étaient pas couvert par l'image
originale. Il est important de garder en tête que vous téléchargez des
exécutables, et bien qu'ils s'exécutent dans un environnement isolé, ils
-peuvent contenir du code malveillant. **De la même manière que vous devez être
-attentif aux binaires que vous exécutez sur votre machine et au contexte de
-leurs téléchargements, ici assurez-vous d'avoir confiance dans la personne
-affiliée à l'image.**
+peuvent contenir du code malveillant.
+**De la même manière que vous devez être attentif aux binaires que vous
+exécutez sur votre machine et au contexte de leurs téléchargements, ici
+assurez-vous d'avoir confiance dans la personne affiliée à l'image.**
+
+:::::
### Arguments de la ligne de commande
-Remarquez comment on interagit avec chaque *objet Docker* : dans la ligne de
+Remarquez comment on interagit avec chaque *objet Docker* : dans la ligne de
commande, le premier mot clef est le type d'objet (`container`, `image`,
-`service`, `network`, `volume`, ...) ; ensuite, vient l'action que l'on
+`service`, `network`, `volume`, ...) ; ensuite, vient l'action que l'on
souhaite faire dans ce cadre.[^oldcall]
[^oldcall]: cela n'a pas toujours été aussi simple, cette syntaxe n'existe que
depuis la version 1.13 (janvier 2017). C'est pourquoi, lorsque vous ferez
des recherches sur internet, vous trouverez de nombreux articles utilisant
- l'ancienne syntaxe, sans le type d'objets : `docker images` au lieu de
- `docker image ls`, `docker run` au lieu de `docker container run`, ...
+ l'ancienne syntaxe, sans le type d'objets : `docker images` au lieu de
+ `docker image ls`, `docker run` au lieu de `docker container run`, ...
L'ancienne syntaxe est dépréciée, mais il reste actuellement possible de
l'utiliser.
Par exemple, pour consulter la liste des images dont nous disposons localement
(soit parce qu'on les a téléchargées, soit parce que nous les avons créées
-nous-même), on utilise la commande `ls` sous le type d'objets `image` :
+nous-même), on utilise la commande `ls` sous le type d'objets `image` :
```bash
@@ -85,24 +87,26 @@ docker image ls
### *Image ID*, nom, tag
-Chaque image est identifiable par son *Image ID* : il s'agit d'un long
+Chaque image est identifiable par son *Image ID* : il s'agit d'un long
identifiant unique. Chaque modification qui est apportée à l'image
générera un *Image ID* différent. Un peu comme un identifiant de
commit dans Git.
-Pour s'y retrouver, on utilise habituellement les noms des images :
+Pour s'y retrouver, on utilise habituellement les noms des images :
`hello-world` est ainsi le nom de l'image
`1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792`.
-Lorsque, comme dans le cas d'Ubuntu, il y a plusieurs *versions*
-disponibles, il est possible de préciser la version au moyen d'un
-*tag*. En consultant [la
-documentation](https://hub.docker.com/_/ubuntu) qui accompagne chaque
-conteneur, nous pouvons constater la présence de plusieurs versions
-d'Ubuntu : `trusty`, `xenial`, `focal` ou `bionic`.
+Lorsque, comme dans le cas d'Ubuntu, il y a plusieurs *versions* disponibles,
+il est possible de préciser la version au moyen d'un *tag*. En consultant la
+documentation[^hubDocUbuntu] qui accompagne chaque conteneur, nous pouvons
+constater la présence de plusieurs versions d'Ubuntu : `trusty`, `xenial`,
+`focal` ou `bionic`.
+
+[^hubDocUbuntu]: Pour voir la documentation des images d'Ubuntu, consultez
+
Par convention, lorsque l'on souhaite désigner un tag en particulier,
-on utilise la syntaxe suivante :
+on utilise la syntaxe suivante :
```
@@ -110,7 +114,7 @@ ubuntu:focal
```
-Par exemple, pour lancer un conteneur Ubuntu Focal, on utilisera :
+Par exemple, pour lancer un conteneur Ubuntu Focal, on utilisera :
```
@@ -119,7 +123,7 @@ docker container run ubuntu:focal
-Chaque nom d'image possède au moins un tag associé par défaut : *latest*. C'est
+Chaque nom d'image possède au moins un tag associé par défaut : *latest*. C'est
le tag qui est automatiquement recherché lorsque l'on ne le précise pas en
lançant l'image.
@@ -127,11 +131,11 @@ lançant l'image.
### Exécuter un programme dans un conteneur
Maintenant que nous avons à notre disposition l'image d'un conteneur Ubuntu,
-nous allons pouvoir jouer avec !
+nous allons pouvoir jouer avec !
La commande `run` de Docker prend comme derniers arguments le programme à
lancer dans le conteneur ainsi que ses éventuels arguments. Essayons d'afficher
-un Hello World :
+un Hello World :
```bash
@@ -146,7 +150,7 @@ transféré dans le conteneur.
Pour nous en convaincre, nous pouvons tenter d'exécuter un programme qui n'est
pas présent sur notre machine, mais bien uniquement dans le conteneur. Si vous
n'utilisez pas [Alpine Linux](https://www.alpinelinux.org), vous pourriez
-tenter d'utiliser son gestionnaire de paquet `apk`, via :
+tenter d'utiliser son gestionnaire de paquet `apk`, via :
```bash
@@ -184,7 +188,7 @@ programme à exécuter par défaut si l'on ne le précise pas dans la ligne de
commande.
C'est grâce à cela que vous n'avez pas eu besoin de préciser de programme
-lorsque vous avez lancé l'image `hello-world` :
+lorsque vous avez lancé l'image `hello-world` :
```bash
@@ -193,7 +197,7 @@ docker container run hello-world
Il est commun que le programme le plus attendu/approprié soit lancé par défaut,
-il est donc tout naturel que pour l'image `hello-world`, ce soit `/hello` :
+il est donc tout naturel que pour l'image `hello-world`, ce soit `/hello` :
```bash
@@ -201,20 +205,21 @@ docker container run hello-world /hello
```
-L'image ne contenant que ce programme, vous ne pourrez pas y lancer de shell :
+L'image ne contenant que ce programme, vous ne pourrez pas y lancer de shell :
-```bash
+```
42sh$ docker container run hello-world /bin/sh
-docker: Error response from daemon: OCI runtime create failed: container_linux.go:349:
- starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown.
+docker: Error response from daemon: OCI runtime create failed:
+ container_linux.go:349: starting container process caused
+ "exec: \"/bin/sh\": stat /bin/sh: no such file or directory"
```
Pour les images `alpine` et `ubuntu`, le programme par défaut est un shell
(`/bin/ash` pour `alpine` et `/bin/bash` pour `ubuntu`), mais il y a une
-subtilité : il faut ajouter les options `--interactive` et `--tty` pour ne pas
-que `docker` nous rende la main tout de suite :
+subtilité : il faut ajouter les options `--interactive` et `--tty` pour ne pas
+que `docker` nous rende la main tout de suite :
```bash
@@ -239,7 +244,7 @@ s'assure que l'entrée standard ne sera pas fermée (`close(2)`). Nous demandons
interractif[^bashnointer].
[^bashnointer]: Mais il sera possible de l'utiliser sans allouer de TTY, comme
- dans cet exemple :
+ dans cet exemple :
```
@@ -253,7 +258,7 @@ interractif[^bashnointer].
L'option `-i` reste néanmoins nécessaire pour que l'entrée standard soit
transmise au conteneur.
-Rassurez-vous, on peut les abbréger en `-i` et `-t` :
+Rassurez-vous, on peut les abréger en `-i` et `-t` :
```bash
@@ -265,22 +270,22 @@ Rassurez-vous, on peut les abbréger en `-i` et `-t` :
### Les paramètres
-Vous avez remarqué le placement des options `--tty` et `--interactive` ? Avant
+Vous avez remarqué le placement des options `--tty` et `--interactive` ? Avant
le nom de l'image, elles sont utilisées par Docker pour modifier le comportement
du `run`. En fait, tout comme `git(1)` et ses sous-commandes, chaque niveau de
-commande peut prendre des paramètres :
+commande peut prendre des paramètres :
```bash
-docker DOCKER_PARAMS container run RUN_OPTS image IMAGE_CMD IMAGE_ARGS ...
+docker DOCKER_PARAMS container run RUN_OPTS image IMAGE_CMD IMAGE_ARGS …
```
-Par exemple :
+Par exemple :
```bash
-docker -H unix:///var/run/docker.sock container run -it alpine /bin/ash -c "echo foo"
+docker -H unix:///run/docker.sock container run -it alpine /bin/ash -c "echo foo"
```
@@ -295,13 +300,13 @@ conteneur.
Avant de quitter notre conteneur, regardons, à l'aide d'un autre terminal,
l'état de notre conteneur. La commande suivante permet d'obtenir la liste des
-conteneurs en cours d'exécution :
+conteneurs en cours d'exécution :
```
42sh$ docker container ls
-CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
-4c39fc049cd1 ubuntu "/bin/bash" 6 minutes ago Up 5 minutes suspicious_galileo
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+4c39fc049cd1 ubuntu "/bin/bash" 6 minutes ago Up 5 minutes bold_gates
```
diff --git a/tutorial/docker-basis/installation.md b/tutorial/docker-basis/installation.md
index fd67c35..707cdaf 100644
--- a/tutorial/docker-basis/installation.md
+++ b/tutorial/docker-basis/installation.md
@@ -1,24 +1,16 @@
-\newpage
-
Installation
------------
-Avant de voir de quoi il s'agit, afin de gagner du temps, nous allons commencer
-par installer Docker.
-
-### Prérequis
-
-Docker repose sur plusieurs techniques implémentées dans les récents noyaux
-Linux (et plus marginalement, Windows). Nous consacrerons les prochains cours à
-comprendre leur fonctionnement. Ces techniques, contrairement aux instructions
-de virtualisation qui rendent les hyperviseurs attractifs, ne sont pas limitées
-à une architecture de microprocesseur spécifique ; cependant la communauté
-autour de Docker utilise principalement l'architecture `amd64`, c'est sur cette
-dernière que Docker pourra être exploité à son plein potentiel, suivi de près
-par l'architecture `arm64`.
+Docker repose sur plusieurs techniques implémentées dans les noyaux Linux
+récents (et plus marginalement, Windows). Ces techniques, contrairement aux
+instructions de virtualisation qui rendent les hyperviseurs attractifs, ne sont
+pas limitées à une architecture de microprocesseur spécifique ; cependant la
+communauté autour de Docker utilise principalement l'architecture `amd64`,
+c'est sur cette dernière que Docker pourra être exploité à son plein potentiel,
+suivi de près par l'architecture `arm64`.
Avant de continuer, assurez-vous que votre machine a bien démarré sur un noyau
-64 bits. Le retour de la commande `uname -m` doit vous indiquer :
+64 bits. Le retour de la commande `uname -m` doit vous indiquer :
```
@@ -26,7 +18,7 @@ x86_64
```
-Ou si vous êtes intrépide :
+Ou si vous êtes intrépide :
```
@@ -34,7 +26,7 @@ aarch64
```
-Assurez-vous également d'avoir un noyau récent, avec la commande `uname -r` :
+Assurez-vous également d'avoir un noyau récent, avec la commande `uname -r` :
```
@@ -46,53 +38,66 @@ Rassurez-vous, même si vous n'avez pas compilé le dernier noyau disponible sur
[`kernel.org`](https://www.kernel.org/), Docker s'utilise à partir de Linux 3.10.
-### Par le gestionnaire de paquets
+### Sous Linux, par le gestionnaire de paquets
En général, votre distribution mettra à votre disposition une version de Docker
-plus ou moins récente. Sous Debian et ses dérivés (Ubuntu, Mint, ...) le paquet
+plus ou moins récente. Sous Debian et ses dérivés (Ubuntu, Mint, ...) le paquet
a été nommé [`docker.io`](https://packages.debian.org/sid/docker.io).
Si dans un environnement de production, on préférera sans doute utiliser une
-version déjà bien éprouvée (comme celle des dépôts de sa distribution), pour ce
-cours, nous allons avoir besoin de la **dernière version
+version déjà bien éprouvée (comme celle des dépôts de sa distribution), pour
+bien suivre les exemples, nous allons avoir besoin de la **dernière version
disponible**. Référez-vous à la documentation officielle correspondant à votre
-distribution :
+distribution :
-**Et Kali Linux alors ?** Kali étant basée sur Debian, référez-vous à
+::::: {.question}
+
+**Et Kali Linux alors ?** Kali étant basée sur Debian, référez-vous à
la procédure d'installation de cette distribution.
+:::::
-### Windows et macOS
+### Sous Windows et macOS
Bien que les fonctionnalités de contenerisation de Docker que nous utiliserons
ne soient disponibles que sous Linux, il est possible d'utiliser Docker de
-manière déportée : le daemon Docker tournera dans une VM Linux, mais vous
-pourrez interagir avec lui via votre ligne de commande habituelle.
+manière déportée : le daemon Docker tournera dans une machine virtuelle Linux,
+mais vous pourrez interagir avec lui via votre ligne de commande habituelle.
-Téléchargez la version correspondante à votre système d'exploitation :
+Téléchargez la version correspondant à votre système d'exploitation :
-* [Docker Desktop for Mac](https://hub.docker.com/editions/community/docker-ce-desktop-mac)
-* [Docker Desktop for Windows](https://hub.docker.com/editions/community/docker-ce-desktop-windows)
+* Docker Desktop for Mac :\
+
-Une fois l'installation terminée, lancez l'application : elle ajoutera une
+* Docker Desktop for Windows :\
+
+
+Une fois l'installation terminée, lancez l'application : elle ajoutera une
icône dans la zone de notification, vous permettant de contrôler l'exécution de
la machine virtuelle sous-jacente.
-Notez que 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. Notez que ce n'est pas le binaire Docker qui change de licence, elle
-reste libre, mais seulement les applications Docker Desktop.
+::::: {.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.
+
+Notez que cela ne concerne pas le projet ou le binaire Docker : ceux-ci restent
+libres. Seules les applications Docker Desktop sont concernées.
+
+:::::
[^DockerSubscription]:
### Évaluation en ligne
-Si vous rencontrez des difficultés pour vous lancer, le projet
-[Play With Docker](https://labs.play-with-docker.com/) vous donne accès à
-un bac à sable dans lequel vous pourrez commencer à faire ce TP.
+Si vous rencontrez des difficultés pour vous lancer, le projet Play With
+Docker[^PlayWithDocker] vous donne accès à un bac à sable
+dans lequel vous pourrez commencer à faire les exercices à suivre.
+
+[^PlayWithDocker]: Play With Docker est accessible à cette addresse :
Il vous faudra disposer [d'un compte
Docker](https://hub.docker.com/signup). Une fois identifié, vous pourrez créer
@@ -101,7 +106,7 @@ une nouvelle instance, et vous connecter dessus via SSH.
### Vérifier la bonne marche de l'installation
-Vous devriez maintenant être capable de lancer la commande suivante :
+Vous devriez maintenant être capable de lancer la commande suivante :
```bash
@@ -109,7 +114,7 @@ docker version
```
-Une sortie similaire au bloc suivant devrait apparaître sur votre écran :
+Une sortie similaire au bloc suivant devrait apparaître sur votre écran :
```
@@ -149,8 +154,8 @@ 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 :
+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 :
```bash
@@ -161,9 +166,9 @@ sudo service docker restart
#### `permission denied`?
-Si vous avez cette erreur : `dial unix /var/run/docker.sock: permission
+Si vous avez cette erreur : `dial unix /var/run/docker.sock: permission
denied.`, ajoutez votre utilisateur au groupe `docker` et **relancez votre
-session** :
+session** :
```bash
@@ -171,5 +176,10 @@ sudo gpasswd -a $USER docker
```
-**Attention :** cette action n'est pas anodine d'un point de vue sécurité :
+::::: {.warning}
+
+Cette action n'est pas anodine d'un point de vue de la sécurité :
+
+
+:::::
diff --git a/tutorial/docker-basis/linking-ex-fic.md b/tutorial/docker-basis/linking-ex-fic.md
new file mode 100644
index 0000000..8b3585e
--- /dev/null
+++ b/tutorial/docker-basis/linking-ex-fic.md
@@ -0,0 +1,44 @@
+## Exercice {-}
+
+À vous maintenant de connecter une instance de `nemunaire/fic-admin` à sa base
+de données.
+
+Ne vous embêtez pas avec les mots de passes des services, initialisez la base
+de données avec le nom d'utilisateur et le mot de passe par défaut. Vous les
+obtiendrez en lisant la documentation de l'image fic-admin :
+
+
+
+```bash
+docker run --rm -e MYSQL_HOST=mysql_cntr_name nemunaire/fic-admin -help
+```
+
+
+Notez la définition de la variable d'environnement `MYSQL_HOST`, celle-ci
+indique le nom du serveur vers lequel le service doit se connecter.
+
+Vous aurez besoin de créer :
+- un volume pour stocker la base de données,
+- un réseau, dans lequel vous connecterez la base de données et le conteneur applicatif.
+
+Une fois le service `fic-admin` lancé, vous pouvez exposer le port 8081, sur
+lequel vous devriez voir l'interface d'admin : .
+
+Placez les différentes commandes (volumes, réseau, `run`, ...) dans un
+script `ficadmin-run.sh`. Vous devriez pouvoir appeler ce script
+plusieurs fois, sans que les données ne soient perdues, entre deux
+arrêts.
+
+
+### Exemple d'exécution
+
+
+```bash
+42sh$ ./ficadmin-run.sh
+http://localhost:12345/
+42sh$ #docker kill db ficadmin
+42sh$ ./ficadmin-run.sh # le script relancera une base de données,
+ # sans avoir perdu les données
+http://localhost:12345/
+```
+
diff --git a/tutorial/docker-basis/linking-ex-help.md b/tutorial/docker-basis/linking-ex-help.md
new file mode 100644
index 0000000..b2978bf
--- /dev/null
+++ b/tutorial/docker-basis/linking-ex-help.md
@@ -0,0 +1,34 @@
+### 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'initialisé le volume attaché à `/var/lib/mysql`. Les
+démarrage 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ées.
+
+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
+correctement l'exécution d'un conteneur.
+
+En réalisant l'exercice, vous serez sans doute confronté à des comportements
+étranges, que vous ne pourriez comprendre qu'en ayant la main sur le conteneur,
+via un shell.
+
+Lorsqu'un conteneur est actif, vous pouvez y lancer un nouveau processus,
+notamment un shell par exemple.
+
+
+```bash
+docker container exec -it mycloud /bin/bash
+(inctnr)$ ping mysql_cntr_name
+```
+
+
+Notez qu'il n'est pas possible d'`exec` dans un conteneur éteint, et que si la
+commande initiale du conteneur se termine, tous les `exec` seront instantanément
+tués.
diff --git a/tutorial/docker-basis/linking.md b/tutorial/docker-basis/linking.md
index d2e9d78..80fbf83 100644
--- a/tutorial/docker-basis/linking.md
+++ b/tutorial/docker-basis/linking.md
@@ -12,14 +12,14 @@ ses données, mais la plupart des applications réclament un serveur de base de
données.
Les bonnes pratiques nous dictent de ne pas placer plus d'un service par
-conteneur : en effet, on peut vouloir mettre à jour l'applicatif sans pour
+conteneur : en effet, on peut vouloir mettre à jour l'applicatif sans pour
autant redémarrer sa base de données, etc. Nous allons donc voir dans cette
partie comment lier deux conteneurs.
## Mise en place du webservice
-Nous allons utiliser l'interface d'administration des serveurs du FIC :
+Nous allons utiliser l'interface d'administration des serveurs du FIC :
[`nemunaire/fic-admin`](https://hub.docker.com/r/nemunaire/fic-admin).
En lançant le conteneur avec les mêmes options que `youp0m`, les journaux
@@ -30,17 +30,17 @@ MariaDB](https://hub.docker.com/_/mariadb).
## Les pilotes réseau
-Docker propose de base trois pilotes (*drivers*) pour « gérer » cela :
+Docker propose de base trois pilotes (*drivers*) pour « gérer » cela :
-- `none` : pour limiter les interfaces réseau du conteneur à l'interface de
+- `none` : pour limiter les interfaces réseau du conteneur à l'interface de
loopback `lo` ;
-- `host` : pour partager la pile réseau avec l'hôte ;
-- `bridge` : pour créer une nouvelle pile réseau par conteneur et rejoindre un
+- `host` : pour partager la pile réseau avec l'hôte ;
+- `bridge` : pour créer une nouvelle pile réseau par conteneur et rejoindre un
pont réseau dédié.
Ces trois *drivers* sont instanciés de base dans Docker avec le même nom que
-leur pilote. Pour consulter la liste de réseaux utilisables, lancez :
+leur pilote. Pour consulter la liste de réseaux utilisables, lancez :
```
@@ -52,7 +52,7 @@ d5d907add6e2 host host local
```
-Par défaut, c'est le réseau `bridge` (de type `bridge`) qui est employé : ce
+Par défaut, c'est le réseau `bridge` (de type `bridge`) qui est employé : ce
réseau utilise le pont `docker0` que vous pouvez voir dans vos interfaces
réseau via `ip link`. C'est via ce pont que les conteneurs peuvent avoir accès
à Internet, au travers d'une couche de NAT.
@@ -76,7 +76,7 @@ Afin de contrôler quels échanges peuvent être réalisés entre les conteneurs
est recommandé de créer des réseaux utilisateur.
La création d'un réseau se fait tout simplement au travers des sous-commandes
-relatives aux objets Docker `network` :
+relatives aux objets Docker `network` :
```bash
@@ -86,7 +86,7 @@ docker network create --driver bridge my_fic
C'est ensuite ce nom de réseau que vous passerez à l'option `--network` de vos
`run`, ou vous pouvez également faire rejoindre un conteneur déjà lancé à un
-réseau :
+réseau :
```bash
@@ -97,84 +97,3 @@ docker network connect NETWORK CONTAINER
Lorsque plusieurs conteneurs ont rejoint un réseau utilisateur, ils peuvent
mutuellement se découvrir grâce à un système de résolution de nom basé sur leur
nom de conteneur.
-
-
-## Exercice {-}
-
-À vous maintenant de connecter une instance de `nemunaire/fic-admin` à sa base
-de données.
-
-Ne vous embêtez pas avec les mots de passes des services, initialisez la base
-de données avec le nom d'utilisateur et le mot de passe par défaut. Vous les
-obtiendrez en lisant la [documentation de l'image
-fic-admin](https://hub.docker.com/r/nemunaire/fic-admin/) :
-
-
-```bash
-docker container run --rm -e MYSQL_HOST=mysql_cntr_name nemunaire/fic-admin -help
-```
-
-
-Notez la définition de la variable d'environnement `MYSQL_HOST`, celle-ci
-indique le nom du serveur vers lequel le service doit se connecter.
-
-Vous aurez besoin de créer un volume pour stocker la base de données, un réseau
-dans lequel vous connecterez la base de données et le conteneur applicatif.
-
-Une fois le service `fic-admin` lancé, vous pouvez exposer le port 8081, sur
-lequel vous devriez voir l'interface d'admin :
.
-
-Placez les différentes commandes (volumes, réseau, `run`, ...) dans un
-script `ficadmin-run.sh`, que vous rendrez à la fin du TP. Vous
-devriez pouvoir appeler ce script plusieurs fois, sans que les données
-ne soient perdues, entre deux arrêts.
-
-
-### Exemple d'exécution
-
-
-```bash
-42sh$ ./ficadmin-run.sh
-http://localhost:12345/
-42sh$ #docker kill db ficadmin
-42sh$ ./ficadmin-run.sh # le script relancera une base de données,
- # sans avoir perdu les données
-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'initialisé le volume attaché à `/var/lib/mysql`. Les
-démarrage 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ées.
-
-Si vous rencontrez des difficultés pour connecter votre conteneur `fic-admin` à
-`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
-correctement l'exécution d'un conteneur.
-
-En réalisant l'exercice, vous serez sans doute confronté à des comportements
-étranges, que vous ne pourriez comprendre qu'en ayant la main sur le conteneur,
-via un shell.
-
-Lorsqu'un conteneur est actif, vous pouvez y lancer un nouveau processus,
-notamment un shell par exemple.
-
-
-```bash
-docker container exec -it ficadmin /bin/bash
-(inctnr)$ ping mysql_cntr_name
-```
-
-
-Notez qu'il n'est pas possible d'`exec` dans un conteneur éteint, et que si la
-commande initiale du conteneur se termine, tous les `exec` seront également
-tués.
diff --git a/tutorial/docker-basis/rendu.md b/tutorial/docker-basis/rendu.md
index defc191..027ea05 100644
--- a/tutorial/docker-basis/rendu.md
+++ b/tutorial/docker-basis/rendu.md
@@ -17,7 +17,7 @@ pour se rendre sur la page de connexion. Une autre machine de votre réseau
local devrait également pouvoir accéder à la plate-forme, simplement en
renseignant l'IP de votre machine et en ajoutant éventuellement des règles de
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
+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 ce TP (ie. sans utiliser
@@ -67,7 +67,7 @@ Par ailleurs, n'oubliez pas de répondre à
## Tarball
Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
-placer dans une tarball (pas d'archive ZIP, RAR, ...).
+placer dans une tarball (pas d'archive ZIP, RAR, ...).
Voici une arborescence type:
@@ -80,7 +80,7 @@ login_x-TP1/mycloud-run.sh
## Signature du rendu
-Deux méthodes sont utilisables pour signer votre rendu :
+Deux méthodes sont utilisables pour signer votre rendu :
* signature du courriel ;
* signature de la tarball.
@@ -106,7 +106,7 @@ signature.
#### No public key
-Si vous recevez un rapport avec l'erreur suivante :
+Si vous recevez un rapport avec l'erreur suivante :
```
@@ -129,7 +129,7 @@ rendu.
#### Not explicit username
-Si vous recevez un rapport avec l'erreur suivante :
+Si vous recevez un rapport avec l'erreur suivante :
```
@@ -144,7 +144,7 @@ données.
#### I've decided to skip your e-mail
-Si vous recevez un rapport concluant ainsi :
+Si vous recevez un rapport concluant ainsi :
```
diff --git a/tutorial/docker-basis/volumes.md b/tutorial/docker-basis/volumes.md
index 2736a39..b8ec036 100644
--- a/tutorial/docker-basis/volumes.md
+++ b/tutorial/docker-basis/volumes.md
@@ -3,7 +3,7 @@
Stockage de données applicatives
================================
-Le concept principal de Docker est de concevoir des conteneurs applicatifs : on
+Le concept principal de Docker est de concevoir des conteneurs applicatifs : on
va préférer assigner un unique rôle à un conteneur (donc généralement on ne va
lancer qu'une seule application par conteneur) et concevoir un service complet
en créant un groupe de conteneurs, partageant des données entre eux par des
@@ -25,21 +25,21 @@ Il est possible de monter un répertoire de la machine hôte dans un
conteneur. L'intérêt reste plutôt limité à des fins de facilité ou de test, par
exemple si vous voulez partager des fichiers avec votre voisin, en passant par
le protocole HTTP, mais sans se casser la tête à installer et configurer un
-serveur web :
+serveur web :
```bash
-docker container run --rm -p 80:80 -v ~/Downloads:/usr/share/nginx/html:ro -d nginx
+docker run --rm -p 80:80 -v ~/Downloads:/usr/share/nginx/html:ro -d nginx
```
Une fois cette commande lancée, votre voisin pourra accéder à votre dossier
-Downloads en renseignant l'IP de votre machine dans son navigateur favori !
+Downloads en renseignant l'IP de votre machine dans son navigateur favori !
Par défaut, `nginx` ne va pas permettre de lister le contenu du répertoire (et
va afficher une page 404, car il cherche un fichier `index.html` dans votre
répertoire). Vous pouvez par contre accéder à un fichier directement, par
-exemple :
+exemple :
## Les volumes
@@ -50,7 +50,7 @@ soucier de leur réel emplacement.
Comme il s'agit d'un objet, la première chose à faire va être de créer notre
-volume :
+volume :
```bash
@@ -59,7 +59,7 @@ docker volume create prod_foodp0m
```
-Ensuite, nous pouvons démarrer un conteneur utilisant, par exemple :
+Ensuite, nous pouvons démarrer un conteneur utilisant, par exemple :
```bash
@@ -67,7 +67,7 @@ docker container run --mount source=prod_youp0m,target=/images nemunaire/youp0m
```
-On pourra également faire de même avec un conteneur MySQL :
+On pourra également faire de même avec un conteneur MySQL :
```bash
@@ -86,7 +86,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
@@ -106,12 +106,15 @@ pour mettre à jour ou relancer un conteneur, sans perdre les données. Un autre
intérêt est de pouvoir partager des fichiers entre plusieurs conteneurs.
Il est ainsi parfaitement possible de lancer deux conteneurs qui partagent le
-même volume :
+même volume :
```bash
-docker container run -d --mount source=prod_youp0m,target=/images -p 8080:8080 nemunaire/youp0m
-docker container run -d --mount source=prod_youp0m,target=/images -p 8081:8080 nemunaire/youp0m
+docker container run -d --mount source=prod_youp0m,target=/images \
+ -p 8080:8080 nemunaire/youp0m
+
+docker container run -d --mount source=prod_youp0m,target=/images \
+ -p 8081:8080 nemunaire/youp0m
```
@@ -119,7 +122,7 @@ Dans cet exemple, l'ajout d'une image dans un conteneur l'ajoutera également
dans le second.
Un exemple plus intéressant serait sur une architecture de micro-services
-traitant des fichiers de grande taille : plutôt que de faire passer les
+traitant des fichiers de grande taille : plutôt que de faire passer les
fichiers par un système de message/socket, on peut partager un volume pour
épargner les coûts de transferts inutiles, lorsqu'ils ne changent pas de
machine.
diff --git a/tutorial/docker-basis/what.md b/tutorial/docker-basis/what.md
index 5d854a3..3923447 100644
--- a/tutorial/docker-basis/what.md
+++ b/tutorial/docker-basis/what.md
@@ -13,13 +13,13 @@ d'une socket.
Le client peut d'ailleurs ne pas être sur la même machine qui exécutera
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 *Docker4Windows* ou *Docker4Mac* :
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.
[^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 :
+ `docker`. Voir aussi :
Commençons par planter le décor, en détaillant les principaux mécanismes de
Docker.
@@ -30,17 +30,17 @@ 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.
-Une image peut, par exemple, contenir :
+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,
-* ...
+* ...
Les images sont utilisées comme **modèle** qui sera ensuite dupliqué à chaque
fois que l'on démarrera un nouveau conteneur.
-Il y a deux méthodes pour obtenir des images Docker : soit les construire avec
+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.
@@ -50,8 +50,8 @@ 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
+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.
@@ -65,10 +65,10 @@ proposent également.
### 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 : à
+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.
+temporaire : l'image n'est pas modifiée par l'exécution d'un conteneur.
{ width=70% }
diff --git a/tutorial/docker-internals/clair.md b/tutorial/docker-internals/clair.md
index c0f3cc2..317b355 100644
--- a/tutorial/docker-internals/clair.md
+++ b/tutorial/docker-internals/clair.md
@@ -113,10 +113,13 @@ Puis on lui demande la génération d'un rapport `html` :
```bash
-paclair --conf conf.yml Docker nemunaire/fic-admin analyse --output-format html --output-report file
+paclair --conf conf.yml Docker nemunaire/fic-admin analyse \
+ --output-format html --output-report file
```
+
+
Si l'on souhaite uniquement avoir des statistiques dans la console :
diff --git a/tutorial/docker-internals/linuxkit-content.md b/tutorial/docker-internals/linuxkit-content.md
index 68b8b7c..821000c 100644
--- a/tutorial/docker-internals/linuxkit-content.md
+++ b/tutorial/docker-internals/linuxkit-content.md
@@ -4,7 +4,7 @@ Si vous n'avez pas déjà le binaire `linuxkit`, vous pouvez télécharger ici
.
Notez qu'étant donné qu'il est écrit en Go, aucune dépendance n'est nécessaire
-en plus du binaire[^lollibc] ;-)
+en plus du binaire[^lollibc] ;-)
[^lollibc]: à condition tout de même que vous utilisiez une libc habituelle.
@@ -17,17 +17,17 @@ Le fichier utilisé pour construire notre image se décompose en plusieurs
parties :
- `kernel` : il est attendu ici une image OCI contenant le nécessaire pour
- pouvoir utiliser un noyau : l'image du noyau, ses modules et un initramfs ;
+ pouvoir utiliser un noyau : l'image du noyau, ses modules et un initramfs ;
- `init` : l'ensemble des images OCI de cette liste seront fusionnés pour
donner naissance au *rootfs* de la machine. On n'y place normalement qu'un
gestionnaire de conteneur, qui sera chargé de lancer chaque conteneur au bon
- moment ;
+ moment ;
- `onboot`, `onshutdown` et `services` : il s'agit de conteneurs qui seront
lancés par le système disponible dans l'`init`, au bon moment. Les conteneurs
indiqués dans `onboot` seront lancés **séquentiellement** au démarrage de la
machine, ceux dans `onshutdown` seront lancés lors de l'arrêt de la
machine. Les conteneurs dans `services` seront lancés simultanément une fois
- que le dernier conteneur de `onboot` aura rendu la main ;
+ que le dernier conteneur de `onboot` aura rendu la main ;
- `files` : des fichiers supplémentaires à placer dans le rootfs.
Le format est documenté
@@ -63,7 +63,7 @@ trust:
L'image `getty` est très pratique pour déboguer, car elle permet d'avoir un
-shell sur la machine !
+shell sur la machine !
On notera cependant que, positionné dans `services`, le shell que nous
obtiendrons sera lui-même exécuté dans un conteneur, nous n'aurons donc pas un
@@ -143,7 +143,7 @@ réutiliser plus tard ce chemin, en remplacement du mot clef `new` :
Toute la puissance de `linuxkit` repose dans son système de construction et
surtout de lancement. En effet, il peut construire des images pour un grand
nombre de plate-forme, mais il est également possible d'utiliser les API de ces
-plates-formes pour aller y lancer des instances de cette image !
+plates-formes pour aller y lancer des instances de cette image !
Pour construire l'image faite précédemment :
@@ -154,7 +154,7 @@ linuxkit build hello.yml
Cela va générer plusieurs fichiers dont un noyau (extrait de l'image de la
-partie `kernel`) ainsi qu'une image. Exactement ce qu'attend QEMU ! Pour
+partie `kernel`) ainsi qu'une image. Exactement ce qu'attend QEMU ! Pour
tester, n'attendons pas davantage pour lancer :
@@ -227,7 +227,7 @@ choix](https://www.vaultproject.io/docs/configuration/storage/index.html)
Au démarrage, Vault devra déjà être configuré pour parler à sa base de données,
qui devra se trouver dans un conteneur isolé et non accessible d'internet. Il
-faudra donc établir un lien `virtual ethernet` entre les deux conteneurs ; et
+faudra donc établir un lien `virtual ethernet` entre les deux conteneurs ; et
ne pas oublier de le configurer (automatiquement au *runtime*, grâce à un
[`poststart`
*hook*](https://github.com/opencontainers/runtime-spec/blob/master/config.md#posix-platform-hooks)
diff --git a/tutorial/docker-internals/linuxkit.md b/tutorial/docker-internals/linuxkit.md
index 0a7ba70..aeb4ba6 100644
--- a/tutorial/docker-internals/linuxkit.md
+++ b/tutorial/docker-internals/linuxkit.md
@@ -8,8 +8,8 @@ tirant parti des conteneurs. Il se positionne comme un système de construction
de machine. En effet, grâce à lui, nous allons pouvoir générer des systèmes
complets, *bootable* dans QEMU, VirtualBox, VMware ou même sur des machines
physiques, qu'il s'agisse de PC ou bien même de Raspberry Pi, ou même encore
-des images pour les différents fournisseurs de cloud !
+des images pour les différents fournisseurs de cloud !
-Bien entendu, au sein de ce système, tout est fait de conteneur ! Alors quand
+Bien entendu, au sein de ce système, tout est fait de conteneur ! Alors quand
il s'agit de donner une IP publique utilisable par l'ensemble des conteneurs,
-il faut savoir jouer avec les *namespaces* pour arriver à ses fins !
+il faut savoir jouer avec les *namespaces* pour arriver à ses fins !
diff --git a/tutorial/docker-internals/oci.md b/tutorial/docker-internals/oci.md
index 9942a8b..4d4096d 100644
--- a/tutorial/docker-internals/oci.md
+++ b/tutorial/docker-internals/oci.md
@@ -9,14 +9,14 @@ fragmentation de l'écosystème.
Trois spécifications ont été écrites :
-- [`runtime-spec`](https://github.com/opencontainers/runtime-spec/blob/master/spec.md#platforms): définit les paramètres du démarrage d'un conteneur ;
-- [`image-spec`](https://github.com/opencontainers/image-spec/blob/master/spec.md): définit la construction, le transport et la préparation des images ;
+- [`runtime-spec`](https://github.com/opencontainers/runtime-spec/blob/master/spec.md#platforms): définit les paramètres du démarrage d'un conteneur ;
+- [`image-spec`](https://github.com/opencontainers/image-spec/blob/master/spec.md): définit la construction, le transport et la préparation des images ;
- [`distribution-spec`](https://github.com/opencontainers/distribution-spec/blob/master/spec.md): définit la manière dont sont partagées et récupérées les images.
## `runtime-spec`
-`runc` est l'implémentation de cette spécification ; elle a été extraite de
+`runc` est l'implémentation de cette spécification ; elle a été extraite de
`docker`, puis donnée par Docker Inc. à l'OCI.
Pour démarrer un conteneur, la spécification indique qu'il est nécessaire
@@ -82,5 +82,5 @@ effectivement nos conteneurs, c'est que l'on peut changer cette implémentation
? la réponse dans l'article :
-Et `containerd` dans l'histoire ?
+Et `containerd` dans l'histoire ?
diff --git a/tutorial/docker-internals/registry.md b/tutorial/docker-internals/registry.md
index f2c74e9..a939a5c 100644
--- a/tutorial/docker-internals/registry.md
+++ b/tutorial/docker-internals/registry.md
@@ -21,13 +21,13 @@ Hub](https://hub.docker.com/), le registre par défaut de `docker`, nous allons
devoir nous plier à leur mécanisme d'authentification : chaque requête au
registre doit être effectuée avec un jeton, que l'on obtient en s'authentifiant
auprès d'un service dédié. Ce service peut délivrer un jeton sans authentifier
-l'interlocuteur, en restant anonyme ; dans ce cas, on ne pourra accéder qu'aux
-images publiques. Ça tombe bien, c'est ce qui nous intéresse aujourd'hui !
+l'interlocuteur, en restant anonyme ; dans ce cas, on ne pourra accéder qu'aux
+images publiques. Ça tombe bien, c'est ce qui nous intéresse aujourd'hui !
-Il n'en reste pas moins que le jeton est forgé pour un service donné (dans
-notre cas `registry.docker.io`) et avec un objectif bien cerné (pour nous, on
-souhaite récupérer le contenu du dépôt[^quiddepot] `hello-world` :
-`repository:hello-world:pull`). Ce qui nous donne :
+Il n'en reste pas moins que le jeton est forgé pour un service donné (ici
+`registry.docker.io`) et avec un objectif bien cerné (pour nous, on souhaite
+récupérer le contenu du dépôt[^quiddepot] `hello-world` : `repository:hello-world:pull`). Ce qui nous donne :
[^quiddepot]: Dans un registre, les fichiers qui composent l'image forment un
dépôt (*repository*).
@@ -58,7 +58,11 @@ Avec `jq`, on peut l'extraire grâce à :
```
-**Attention :** le token expire ! Pensez à le renouveler régulièrement.
+::::: {.warning}
+
+Le token expire ! Pensez à le renouveler régulièrement.
+
+:::::
En cas d'erreur inexplicable, vous pouvez ajouter un `-v` à la ligne de
commande `curl`, afin d'afficher les en-têtes. Prêtez une attention toute
@@ -94,12 +98,12 @@ système d'exploitation :
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: ${MEDIATYPE}" \
- "https://registry-1.docker.io/v2/library/hello-world/manifests/${MANIFEST_DIGEST}" | jq .
+ "https://registry-1.docker.io/v2/library/hello-world/manifests/${MNFST_DGST}"
```
Nous voici donc maintenant avec le manifest de notre image. Nous pouvons
-constater qu'il n'a bien qu'une seule couche, ouf !
+constater qu'il n'a bien qu'une seule couche, ouf !
## Récupération de la configuration et de la première couche
@@ -115,7 +119,7 @@ Pour récupérer la configuration de l'image :
```bash
curl -s --location \
-H "Authorization: Bearer ${TOKEN}" \
- "https://registry-1.docker.io/v2/library/hello-world/blobs/${CONFIG_DIGEST}" | jq .
+ "https://registry-1.docker.io/v2/library/hello-world/blobs/${CONFIG_DIGEST}"
```
@@ -132,9 +136,11 @@ wget --header "Authorization: Bearer ${TOKEN}" \
## Extraction
-Le type indiqué par le manifest pour cette couche était
-`application/vnd.docker.image.rootfs.diff.tar.gzip`, il s'agit donc d'une
-tarball compressée au format gzip :
+Le type indiqué par le manifest pour cette couche était :
+
+ application/vnd.docker.image.rootfs.diff.tar.gzip
+
+Il s'agit donc d'une tarball compressée au format gzip :
```bash
@@ -179,7 +185,7 @@ Pensez également à tester avec d'autres images, comme par exemple
`nemunaire/youp0m`. Il vous faudra alors extraire plusieurs couches.
Pour gérer les différentes couches, vous pouvez utiliser une stratégie
-similaire au driver `vfs` : en extrayant chaque tarball l'une au dessus de
+similaire au driver `vfs` : en extrayant chaque tarball l'une au dessus de
l'autre, en essayant de gérer les *whiteout files*. Ou bien en suivant le
driver `overlayfs`, en montant un système de fichier à chaque couche (dans ce
cas, votre script devra être lancé en `root`).
diff --git a/tutorial/docker-internals/runc.md b/tutorial/docker-internals/runc.md
index 9ab7007..2942782 100644
--- a/tutorial/docker-internals/runc.md
+++ b/tutorial/docker-internals/runc.md
@@ -22,13 +22,13 @@ essayer de lancer un shell `alpine` avec un volume dans notre home.
Vous devriez avoir le binaire `runc` ou `docker-runc`. Si ce n'est pas le cas,
vous pouvez télécharger la dernière version :
-
. La 1.0.0-rc92 est Ok.
+.
## Extraction du rootfs
-À l'aide du script d'extraction de registre réalisé dans le TP 3, extrayons le
-rootfs d'alpine : `library/alpine` dans le registre Docker.
+À l'aide du script d'extraction de registre déjà réalisé, extrayons le
+*rootfs* d'alpine : `library/alpine` dans le registre Docker.
Si vous n'avez pas eu le temps de terminer le script d'extraction, vous pouvez
utiliser :
@@ -55,9 +55,7 @@ runc spec
Pour savoir à quoi correspondent tous ces éléments, vous pouvez consulter :
-Nous verrons dans les prochains TP, plus en détails tout ce qui porte sur les
-*namespaces*, rassurez-vous, il n'y a que très peu de champs à modifier
-aujourd'hui.
+Rassurez-vous, il n'y a que très peu de champs à modifier.
## Test brut
@@ -143,8 +141,8 @@ stocker les photos (dossier `/srv/images`)[^chmod].
simple pour l'instant serait d'attribuer les permissions `0777` à la
source, temporairement.
-Pour ce TP, considérez que vous avez réussi si vous voyez s'afficher :
+Pour cette étape, Considérez que vous avez réussi si vous voyez s'afficher :
> `Ready, listening on :8080`
-Il faudra attendre les TP suivants pour avoir du réseau dans notre conteneur.
+On ne pourra pas tester davantage sans avoir du réseau dans notre conteneur.
diff --git a/tutorial/docker-internals/vulnerability-scan.md b/tutorial/docker-internals/vulnerability-scan.md
index eb71eff..facd8fa 100644
--- a/tutorial/docker-internals/vulnerability-scan.md
+++ b/tutorial/docker-internals/vulnerability-scan.md
@@ -10,10 +10,10 @@ machine hébergeant des conteneurs, car cela lui apporte des garanties quant à
l'effort de cloisonnement mis en place.
Mais doit-on pour autant s'arrêter là et considérer que nous avons réglé
-l'ensemble des problématiques de sécurité liées aux conteneurs ?
+l'ensemble des problématiques de sécurité liées aux conteneurs ?
Évidemment, non : une fois nos services lancés dans des conteneurs, il ne sont
-pas moins exposés aux bugs et autres failles applicatives ; qu'elles soient
+pas moins exposés aux bugs et autres failles applicatives ; qu'elles soient
dans notre code ou celui d'une bibliothèque, accessible par rebond, ...
Il est donc primordial de ne pas laisser ses conteneurs à l'abandon une fois
@@ -23,7 +23,7 @@ image telle que Debian, Ubuntu ou Redhat n'apparaît que pour cela) ou bien
lorsqu'un des programmes ou l'une des bibliothèques que l'on a installés
ensuite est mise à jour.
-Convaincu ? Cela sonne encore comme des bonnes pratiques difficiles à mettre en
+Convaincu ? Cela sonne encore comme des bonnes pratiques difficiles à mettre en
œuvre, pouvant mettre en péril tout un système d'information. Pour s'en
protéger, nous allons avoir besoin de réaliser à intervalles réguliers une
analyse statique de nos conteneurs.
@@ -42,9 +42,9 @@ automatiquement) les images que l'on publie sur un registre public, sans
oublier de mettre à jour l'image de base.
D'ailleurs, avez-vous vérifié qu'une mise à jour de l'image `nemunaire/youp0m`
-n'était pas disponible depuis que vous avez commencé à l'utiliser ? Docker ne
+n'était pas disponible depuis que vous avez commencé à l'utiliser ? Docker ne
vérifie jamais si une mise à jour des images que vous avez précédemment
-téléchargées. Pensez donc régulièrement à appeler :
+téléchargées. Pensez donc régulièrement à appeler :
```
@@ -65,10 +65,11 @@ si vous n'en avez pas, nous verrons dans la section suivante `trivy` qui permet
de réaliser ses scans directement sur notre machine, sans passer par un
intermédiaire.
-#### Attention {-}
+::::: {.warning}
Par cette méthode, vous êtes limité à 10 scans par mois.
+:::::
### Installation du plugin
@@ -82,13 +83,14 @@ préalablement connecté à votre compte Docker avec la commande `docker login`.
Comme `docker scan` est un plugin, suivant la méthode d'installation que vous
avez suivie, il n'a pas forcément été installé. Si vous obtenez un message
d'erreur en lançant la commande, [voici comment récupérer le plugin et
-l'installer manuellement :](https://github.com/docker/scan-cli-plugin#on-linux)
+l'installer manuellement :](https://github.com/docker/scan-cli-plugin#on-linux)
```
mkdir -p ~/.docker/cli-plugins
-curl https://github.com/docker/scan-cli-plugin/releases/latest/download/docker-scan_linux_amd64 \
- -L -s -S -o ~/.docker/cli-plugins/docker-scan
+curl -L -s -S -o ~/.docker/cli-plugins/docker-scan \
+ https://github.com/docker/scan-cli-plugin/releases/\
+ latest/download/docker-scan_linux_amd64
chmod +x ~/.docker/cli-plugins/docker-scan
```
@@ -96,7 +98,7 @@ chmod +x ~/.docker/cli-plugins/docker-scan
### Utilisation
Une fois le plugin installé et la licence du service acceptée, nous pouvons
-commencer notre analyse :
+commencer notre analyse :
```
@@ -112,7 +114,8 @@ Base image: alpine:3.14.2
✓ Tested 16 dependencies for known vulnerabilities, no vulnerable paths found.
-According to our scan, you are currently using the most secure version of the selected base image
+According to our scan, you are currently using the most secure version of
+the selected base image
```
@@ -128,10 +131,10 @@ Testing mysql...
✗ High severity vulnerability found in gcc-8/libstdc++6
Description: Insufficient Entropy
Info: https://snyk.io/vuln/SNYK-DEBIAN10-GCC8-469413
- Introduced through: apt@1.8.2.3, mysql-community/mysql-community-client@8.0.26-1debian10, mysql-community/mysql-community-server-core@8.0.26-1debian10, mecab-ipadic@2.7.0-20070801+main-2.1, meta-common-packages@meta
+ Introduced through: apt@1.8.2.3, mysql-community/mysql-community-client@[...]
From: apt@1.8.2.3 > gcc-8/libstdc++6@8.3.0-6
- From: mysql-community/mysql-community-client@8.0.26-1debian10 > gcc-8/libstdc++6@8.3.0-6
- From: mysql-community/mysql-community-server-core@8.0.26-1debian10 > gcc-8/libstdc++6@8.3.0-6
+ From: mysql-community/mysql-community-client@8.0.26-1debian10 > gcc-8[...]
+ From: mysql-community/mysql-community-server-core@8.0.26-1debian10 > gcc-8[...]
and 7 more...
Image layer: Introduced by your base image (mysql:8.0.26)
@@ -143,11 +146,12 @@ Base image: mysql:8.0.26
Tested 135 dependencies for known vulnerabilities, found 79 vulnerabilities.
-According to our scan, you are currently using the most secure version of the selected base image
+According to our scan, you are currently using the most secure version of
+the selected base image
```
-Ce dernier exemple est sans appel : `mysql` est une image officielle, et sa
+Ce dernier exemple est sans appel : `mysql` est une image officielle, et sa
dernière version à l'écriture de ses lignes contient pas moins de 79
vulnérabilités dont 11 *high*.
@@ -168,7 +172,7 @@ un certain nombre d'arguments, notamment le nom de l'image à analyser.
### Utilisation
-Tentons à nouveau d'analyser l'image `mysql` :
+Tentons à nouveau d'analyser l'image `mysql` :
```
@@ -189,7 +193,7 @@ Les résultats sont un peu différents qu'avec `docker scan`, mais on constate
que l'image `mysql` contient vraiment de nombreuses vulnérabilités. Même si
elles ne sont heureusement pas forcément exploitable directement.
-Voyons maintenant s'il y a des différentes avec l'image `nemunaire/fic-admin` :
+Voyons maintenant s'il y a des différentes avec l'image `nemunaire/fic-admin` :
```
@@ -217,7 +221,7 @@ vulnérabilités de l'image, a aussi fait une analyse des dépendances du binair
`/srv/admin`.
Trivy est en effet capable de rechercher des vulnérabilités par rapport aux
-dépendances connues de certains langages : Python, PHP, Node.js, .NET, Java,
+dépendances connues de certains langages : Python, PHP, Node.js, .NET, Java,
Go, ...
@@ -225,7 +229,7 @@ Go, ...
Pour éviter de surcharger les serveurs de distributions de la base de données
de vulnérabilités, nous devrions utiliser un cache pour faire nos
-analyses. Préférez lancer `trivy` avec les options suivantes :
+analyses. Préférez lancer `trivy` avec les options suivantes :
```
@@ -242,7 +246,7 @@ pouvoir l'exporter pour l'afficher dans un navigateur (par exemple pour le
mettre à disposition des développeurs, lors d'une analyse automatique).
Pour ce faire, on peut ajouter les options suivantes à la ligne de commande de
-notre conteneur :
+notre conteneur :
```bash
@@ -253,8 +257,6 @@ notre conteneur :
En redirigeant la sortie standard vers un fichier, vous pourrez l'ouvrir dans
votre navigateur favori.
----
-
-{ width=90% }
+{ width=80% }
## Clair
diff --git a/tutorial/docker-orchestration/machine.md b/tutorial/docker-orchestration/machine.md
index fb62cc8..85bc6d6 100644
--- a/tutorial/docker-orchestration/machine.md
+++ b/tutorial/docker-orchestration/machine.md
@@ -1,23 +1,21 @@
\newpage
Création du cluster
-===================
+-------------------
-## Le provisionnement de machine
-
-Pour travailler sur un cluster, il faut avoir plusieurs machines ... au moins
-plus d'une !
+Pour travailler sur un cluster, il faut avoir plusieurs machines ... au moins
+plus d'une !
Mais qui dit plusieurs machines, dit généralement de nombreuses installations à
faire, de nombreuses configurations à partager, etc. Tout ce qu'un
-administrateur système redoute : du travail !
+administrateur système redoute : du travail !
Évidemment, de nombreuses solutions existent pour travailler moins, tout en
-déployant plus et de manière plus fiable ! On peut parler
+déployant plus et de manière plus fiable ! On peut parler
d'[`ansible`](https://www.ansible.com/), de
[`chef`](https://docs.chef.io/provisioning.html), ou encore de
-[`puppet`](https://puppet.com/products/capabilities/automated-provisioning),
-... Toutes ces solutions permettent d'obtenir des configurations finement
+[`puppet`](https://puppet.com/products/capabilities/automated-provisioning), ...
+Toutes ces solutions permettent d'obtenir des configurations finement
personnalisées, mais nécessitent une phase d'apprentissage plutôt lourde.
Comme nous voulons lancer des conteneurs, les machines à provisionner n'ont pas
@@ -25,9 +23,7 @@ besoin de configuration bien particulière et les seuls paquets importants sont
une version récente de `docker` et ses dépendances.
-## Provisionner des machines ...
-
-### Automagiquement
+### Provisionner des machines ...
La solution magique consiste à passer par `docker-machine` pour créer des
machines virtuelles automatiquement provisionnées avec Docker.
@@ -38,21 +34,20 @@ virtuelles. Si votre machine Linux est en fait une machine virtuelle hébergée
par VirtualBox sous Windows, vous allez sans doute préférer la deuxième
solution, que d'utiliser PowerShell et Docker4Windows[^amazon].
-[^amazon]: Vous pouvez aussi vous inscrire sur
- [Amazon Web Services](https://aws.amazon.com/), `docker-machine` est
- capable, à partir de vos
- [clefs d'API](https://docs.docker.com/machine/examples/aws/), de créer et
- lancer des machines dans le cloud ! Et ce n'est pas le seul service de
- [cloud supporté](https://docs.docker.com/machine/drivers/) !
+[^amazon]: Vous pouvez aussi vous inscrire sur [Amazon Web
+ Services](https://aws.amazon.com/)
,
+ `docker-machine` est capable, à partir de vos clefs d'API, de créer et
+ lancer des machines dans le cloud ! Et ce n'est pas le seul service de
+ cloud supporté !
-#### Créer une machine
+##### Créer une machine {-}
Pour créer une nouvelle machine, nous allons utiliser la commande
`docker-machine create`, en prenant soin de préciser le pilote à utiliser, les
éventuelles options que prend ce pilote, ainsi que le nom que vous souhaitez
donner à cette machine (les machines ne sont pas considérées comme jetables,
-leur nom vous permettra par exemple de relancer une machine plus tard) :
+leur nom vous permettra par exemple de relancer une machine plus tard) :
```bash
@@ -61,34 +56,37 @@ docker-machine create --driver virtualbox echinoidea
Consultez la section suivante, réservée aux gens qui ne peuvent pas passer par
-`docker-machine` si vous souhaitez avoir plus d'information sur ce que fait
+`docker-machine`, si vous souhaitez avoir plus d'information sur ce que fait
cette commande.
-#### Commandes usuelles de `docker-machine`
+##### Commandes usuelles de `docker-machine` {-}
De la même manière que `docker`, vous pouvez lister les machines connues
-(`ls`), changer leur état d'exécution (`start`/`stop`/`kill`/`restart`) ou encore supprimer la machine (`rm`)
+(`ls`), changer leur état d'exécution (`start`/`stop`/`kill`/`restart`) ou
+encore supprimer une machine (`rm`).
-Si vous avez besoin d'obtenir un shell : `docker-machine ssh $NAME` et
+Si vous avez besoin d'obtenir un shell : `docker-machine ssh $NAME` et
évidemment la commande `scp` s'utilise de la même manière, pour transférer des
fichiers.
-#### Utilisation avec Docker
+##### Utilisation avec Docker {-}
-Rappelez-vous, au cours précédent, nous avions évoqué le fait que le deamon
-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 daamon/machine avec une simple commande :
+Nous avons déjà évoqué le fait que le deamon 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 :
```
-42sh$ docker container ls
-CONTAINER ID IMAGE COMMAND CREATED STATUS
-42sh$ eval $(docker-machine env echinoidea)
42sh$ docker container ls -a
-CONTAINER ID IMAGE COMMAND CREATED STATUS
-a814293b9f45 armbuild/busybox "/bin/sh" 18 seconds ago Up 10 minutes
-0caddeed5037 armbuild/alpine "/bin/sh" 2 weeks ago Created
+CONTAINER ID IMAGE COMMAND CREATED STATUS
+
+42sh$ eval $(docker-machine env echinoidea)
+
+42sh$ docker container ls -a
+CONTAINER ID IMAGE COMMAND CREATED STATUS
+a814293b9f45 armbuild/busybox "/bin/sh" 18 seconds ago Up 10 minutes
+0caddeed5037 armbuild/alpine "/bin/sh" 2 weeks ago Created
```
@@ -102,43 +100,44 @@ supprimer manuellement les variables qui ont été ajoutées par l'évaluation,
soit lancer `eval $(docker machine env -u)`.
-### Automanuellement
+#### Derrière Docker Machine...
Si votre environnement ne vous permet pas d'utiliser `docker-machine`, vous
-pouvez vous contenter aujourd'hui de démarrer une ou deux autres machines
-virtuelles sur le même réseau que votre machine actuelle.
+pouvez vous contenter de démarrer une ou deux autres machines virtuelles sur le
+même réseau que votre machine virtuelle.
Rassurez-vous, vous n'allez pas avoir besoin de refaire toute la phase
-d'installation. Des contributeurs maintiennent une petite ISO ne contenant que
-le strict nécessaire pour utiliser Docker. C'est d'ailleurs cette ISO qui est
-utilisé par `docker-machine` pour démarrer et configurer en un rien de temps
-ses machines virtuelles.
+d'installation. Des contributeurs ont conçu une petite image de CD ne contenant
+que le strict nécessaire pour utiliser Docker. C'est d'ailleurs cette ISO qui
+est utilisée par `docker-machine` pour démarrer et configurer en un rien de
+temps ses machines virtuelles.
-1. Dans un premier temps, commençons par
- [télécharger la dernière ISO de `boot2docker.iso`](https://github.com/boot2docker/boot2docker/releases/latest).
+1. Dans un premier temps, commençons par télécharger la dernière ISO de
+ `boot2docker.iso` :\
+
1. Ensuite, dans notre hyperviseur, créons deux nouvelles machines, avec
suffisamment de ressources pour pouvoir lancer des conteneurs. Ce n'est pas
- parce que l'images que l'on va démarrer est petite, que l'on ne va pas
+ parce que l'image que l'on va démarrer est petite que l'on ne va pas
pouvoir allouer beaucoup d'espace disque ou de RAM.
1. Lançons ensuite nos deux images, configurées pour démarrer sur l'image ISO
que l'on a téléchargée précédemment.
1. Faisons un `ip a` pour connaître l'IP de la machine, nous devrions pouvoir
- s'y connecter en SSH avec l'utilisateur `docker` dont le mot de passe est
+ nous y connecter en SSH avec l'utilisateur `docker` dont le mot de passe est
`tcuser`.
Vous constaterez que le daemon `dockerd` est déjà lancé. `docker` est déjà
-pleinement utilisable dans cette machine !
+pleinement utilisable dans cette machine !
#### (Optionnel) Déporter le client Docker
-Dans le suite de ce TP, nous n'allons taper que quelques commandes dans nos
+Dans la suite, nous n'allons taper que quelques commandes dans nos
machines virtuelles, il n'est donc pas primordial d'avoir configuré son
environnement pour utiliser localement les daemons Docker des machines
virtuelles. Néanmoins, cela ne coûte rien de voir les procédures mise en œuvre.
Commençons par voir sur quel port le daemon `dockerd` de notre machine
-virtuelle écoute :
+virtuelle écoute :
```bash
@@ -148,26 +147,25 @@ tcp 0 0 :::2376 :::* 980/dockerd
```
-Essayons de renseigner simplement cette configuration à notre client Docker :
+Essayons de renseigner simplement cette configuration à notre client Docker :
```bash
(main) 42sh$ docker -H tcp://$VM1_IP:2376/ info
-Get http://$VM1_IP:2376/v1.32/info: net/http: HTTP/1.x transport connection broken: malformed HTTP response "\x15\x03\x01\x00\x02\x02".
+Get http://$VM1_IP:2376/v1.32/info: net/http: transport connection broken
* Are you trying to connect to a TLS-enabled daemon without TLS?
```
-En effet, Docker met tout en œuvre pour rendre compliqué l'utilisation
+En effet, Docker met tout en œuvre pour rendre compliquée l'utilisation
non-sécurisée de la plate-forme. Mais ils font également en sorte que la
sécurité soit la plus transparente et la moins contraignante possible pour
l'utilisateur, sans pour autant être faible.
Afin de contacter un daemon Docker distant, il est nécessaire présenter un
-certificat client TLS approuvé par ce daemon (comme lorsque vous vous connectez
-sur [Epitaf](https://www.epitaf.fr/moodle)). Il est également nécessaire de
+certificat client TLS approuvé par ce daemon. Il est seulement nécessaire de
vérifier le certificat présenté par le daemon, comme dans le cadre d'une
-connexion TLS classique.
+connexion SSH classique.
Tout le nécessaire est déjà configuré au sein de `boot2docker`, pour nos tests,
nous n'avons qu'à recopier la clef et les certificats en place.
@@ -182,12 +180,12 @@ key.pem
```
-Tentons maintenant de nous connecter au daemon distant en utilisant ces éléments :
+Tentons maintenant de nous connecter au daemon distant utilisant ces éléments :
```bash
-42sh$ DOCKER_CERT_PATH=remote/virt1/ docker -H tcp://$VM1_IP:2376/ --tlsverify info
+DOCKER_CERT_PATH=remote/vir1/ docker -H tcp://$VM1_IP:2376/ --tlsverify info
```
-Vous pouvez effectuer la même opération pour la seconde VM.
+Nous pouvons effectuer la même opération pour la seconde machine virtuelle.
diff --git a/tutorial/docker-orchestration/rendu.md b/tutorial/docker-orchestration/rendu.md
index e1653d1..b104770 100644
--- a/tutorial/docker-orchestration/rendu.md
+++ b/tutorial/docker-orchestration/rendu.md
@@ -34,7 +34,7 @@ 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) :
+cela dépendra de votre avancée dans le projet) :
```
diff --git a/tutorial/docker-orchestration/setup.md b/tutorial/docker-orchestration/setup.md
index 3bfa7e6..88708d7 100644
--- a/tutorial/docker-orchestration/setup.md
+++ b/tutorial/docker-orchestration/setup.md
@@ -1,42 +1,35 @@
-\newpage
-
Mise en place
-=============
+-------------
+Pour cette partie, nous allons avoir besoin de `docker-machine`, installons-le sur
+notre machine hôte, même si ce n'est pas un Linux : le but va être de lancer
+plusieurs machines virtuelles dédiées à Docker pour simuler un cluster.
-## `docker-machine`
-
-Pour ce TP, nous allons avoir besoin de `docker-machine`, installez-le sur
-votre machine hôte, même si ce n'est pas un Linux : le but va être de lancer
-plusieurs machines virtuelles Docker pour simuler un cluster.
-
-Ce programme permet de simplifier la gestion du multiples environnements
-Docker, comme par exemple lorsque l'on souhaite gérer un cluster de machines
+Ce programme permet de simplifier la gestion de multiples environnements
+Docker, comme par exmple lorsque l'on souhaite gérer un cluster de machines
pour un projet.
Ainsi, il est possible de provisionner et gérer des machines hôtes sur les
plates-formes de cloud habituelles. C'est également ce projet qui est à la base
-de *Docker for Mac* et *Docker for Windows*, en permettant de lancer via,
-respectivement, VirtualBox et Hyper-V, un environnement Linux prêt à être
-utilisé avec Docker.
+de *Docker Dektop*, en permettant de lancer via, respectivement, VirtualBox ou
+Hyper-V, un environnement Linux prêt à être utilisé avec Docker.
### Par la distribution binaire
L'équipe en charge de `docker-machine` met à disposition un exécutable compilé
-pour bon nombres d'environnements. Nous pouvons l'installer en suivant la
-procédure suivante :
+pour bon nombre d'environnements. Nous pouvons l'installer en suivant la
+procédure suivante :
```bash
-curl -L https://github.com/docker/machine/releases/download/v0.15.0/docker-machine-Linux-x86_64 \
+V=0.16.2
+P=docker-machine-`uname -s`-`uname -m`
+curl -L https://github.com/docker/machine/releases/download/v${V}/${P} \
> /usr/bin/docker-machine
chmod +x /usr/bin/docker-machine
```
-Si vous êtes dans un environnement différent, jetez un œil à
-[la documentation d'installation](https://docs.docker.com/machine/install-machine/).
-
### Support de KVM
@@ -46,28 +39,30 @@ plug-ins.
Si vous utilisez KVM comme hyperviseur, vous allez avoir besoin d'installer le
plugins
-[`docker-machine-kvm`](https://github.com/dhiltgen/docker-machine-kvm). Vous
-n'aurez qu'à suivre les instructions du
-[`README`](https://github.com/dhiltgen/docker-machine-kvm/blob/master/README.md)
-!
+[`docker-machine-kvm`](https://github.com/machine-drivers/docker-machine-kvm). Vous
+n'aurez qu'à suivre les instructions du `README` :\
+
+Les autres plugins sont disponibles au sein de l'organisation Machine-Driver
+sur GitHub :\
+
### Vérification du fonctionnement
Comme avec Docker, nous pouvons vérifier le bon fonctionnement de
-`docker-machine` en exécutant la commande :
+`docker-machine` en exécutant la commande :
```
42sh$ docker-machine version
-docker-machine version 0.12.2, build 9371605
+docker-machine version 0.16.2, build 9371605
```
-## Play With Docker
+### Play With Docker
-Tout comme pour le TP précédent, si vous avez des difficultés pour réaliser les
-exercices sur vos machines, vous pouvez utiliser le projet
-[Play With Docker](https://play-with-docker.com/) qui vous donnera accès à un
-bac à sable avec lequel vous pourrez réaliser tous les exercices de ce TP.
+Si vous avez des difficultés pour réaliser les exercices sur votre machine,
+vous pouvez utiliser le projet [Play With
+Docker](https://play-with-docker.com/) qui vous donnera accès à un bac à sable
+avec lequel vous pourrez réaliser tous les exercices de cette partie.
diff --git a/tutorial/docker-orchestration/stack.md b/tutorial/docker-orchestration/stack.md
index 79e9433..8be67ff 100644
--- a/tutorial/docker-orchestration/stack.md
+++ b/tutorial/docker-orchestration/stack.md
@@ -1,15 +1,15 @@
\newpage
Déploiement de services
-=======================
+-----------------------
-## Services ?
+### Services ?
Une petite minute terminologie avant de continuer, car lorsque l'on passe sur
-les clusters de Docker, cela change un peu :
+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 ;
+ *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.
@@ -18,13 +18,13 @@ la haute-disponibilité ou pour répartir la charge.
-### Hello world, again?
+#### 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 :
+Précédemment, nous lancions notre serveur web favori avec :
```bash
@@ -33,7 +33,7 @@ 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 :
+*workers*, est :
```bash
@@ -41,7 +41,7 @@ docker service create --name myWebS nginx
```
-Allons-y, essayons !
+Allons-y, essayons !
On peut consulter l'état du service avec, comme d'habitude `ls` :
@@ -59,7 +59,7 @@ 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 :
+d'ajouter une redirection de port :
```bash
@@ -71,13 +71,13 @@ docker service update --publish-add 80 myWebS
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
+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
+##### 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
@@ -88,25 +88,26 @@ 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.
+mécanisme qu'il est possible de faire de la répartition de charge très
+simplement.
\vspace{1.5em}
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/).
+sans doute la plus intuitive. Si vous souhaitez en apprendre plus, vous devriez
+consulter la documentation à ce sujet :\
+
-### Mise à l'échelle et placement
+#### 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
+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.
+physiques différentes.
-Ce qui se fait souvent avec beaucoup de douleur hors de Docker, se résume ici à
-:
+Ce qui se fait souvent avec beaucoup de douleur hors de Docker, se résume ici
+à :
```bash
@@ -122,21 +123,21 @@ docker service ps myWebS
```
-nous montre bien, a priori 3 tâches en cours d'exécution pour ce service !
+nous montre bien, a priori 3 tâches en cours d'exécution pour ce service !
-Enfin, vous avez compris le principe !
+Enfin, vous avez compris le principe !
-## Stack ?
+### Stack ?
-Refermons cette longue parenthèse et revenons-en au sujet du jour : la
+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, ...
+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` :
+la lancer grâce à notre `docker-compose.yml` :
```bash
@@ -144,7 +145,7 @@ docker stack deploy --compose-file docker-compose.yml tic
```
-### Règle de déploiement
+#### 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.
diff --git a/tutorial/docker-orchestration/swarm.md b/tutorial/docker-orchestration/swarm.md
index 0d6cbc3..a7b95b4 100644
--- a/tutorial/docker-orchestration/swarm.md
+++ b/tutorial/docker-orchestration/swarm.md
@@ -1,61 +1,13 @@
\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](https://kubernetes.io),
-[Hashicorp Nomad](https://www.nomadproject.io/) ou encore
-[Apache Mesos](https://mesos.apache.org/), ...
-
-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é[^dockerconEU2017].
-
-[^dockerconEU2017]: À 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.
-
-
-### 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
+Certain nœuds 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.
@@ -66,15 +18,16 @@ 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.
+En termes de cluster, des tâches sont l'équivalent des conteneurs, hors de
+Swarm.
-## Création du cluster Swarm
+### Création du cluster Swarm
-### Initialisation du cluster
+#### 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 :
+La première chose à faire est d'initialiser un cluster Swarm. Pour se faire,
+ce n'est pas plus compliqué que de faire :
```bash
@@ -88,14 +41,14 @@ cluster, afin de pouvoir lancer des tâches ... au moins sur lui-même en
attendant d'autres nœuds.
-### Rejoindre le cluster
+#### Rejoindre un 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
+La commande pour rejoindre un cluster et contenant le jeton est iniquée
lorsque vous initialisez le cluster. Si vous avez raté la sortie de la
-commande, vous pouvez retrouver le jeton avec :
+commande, vous pouvez retrouver le jeton avec :
```bash
@@ -106,17 +59,11 @@ 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
- *Swarm*[^avertVM]). Et soyez fair-play, attendez un peu avant de lancer
- l'image `embano1/cpuburn` ;)
-
[^avertVM]: 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 !
+ des redirections de ports, mais le résultat n'est pas garanti !
```bash
@@ -125,11 +72,12 @@ 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 :
+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
@@ -138,21 +86,21 @@ ovgh6r32kgcbswb2we48br1 * wales Ready Active Leader
-### Rejoindre en tant que manager
+#### 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
+Nous n'allons pas faire rejoindre de manager supplémentaire à ce stade, 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.
+de toujours avoir un nombre impair de managers : Docker en recommande 3
+ou 5. La pire configuration est avec deux managers, car si l'un des deux 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 procalmer leader) ou si c'est l'autre 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.
diff --git a/tutorial/docker-orchestration/tutorial.md b/tutorial/docker-orchestration/tutorial.md
index 6833810..0301d04 100644
--- a/tutorial/docker-orchestration/tutorial.md
+++ b/tutorial/docker-orchestration/tutorial.md
@@ -6,7 +6,7 @@ institute: EPITA
date: Jeudi 18 octobre 2018
abstract: |
Dans la troisième partie de ce TP, nous allons orchestrer nos
- conteneurs !
+ conteneurs !
\vspace{1em}
@@ -21,4 +21,4 @@ abstract: |
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96)
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/dockerfiles/dockerfile.md b/tutorial/dockerfiles/dockerfile.md
index 312738b..9b2f87e 100644
--- a/tutorial/dockerfiles/dockerfile.md
+++ b/tutorial/dockerfiles/dockerfile.md
@@ -1,6 +1,6 @@
\newpage
-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
@@ -22,7 +22,7 @@ l'intitulé d'une instruction (que l'on écrit généralement en majuscule), ell
est suivie de ses arguments.
Dans notre exemple, nous utilisons `FROM`{.dockerfile} qui indique une image de
-départ à utiliser ; `RUN`{.dockerfile} est une commande qui sera exécutée dans
+départ à utiliser ; `RUN`{.dockerfile} 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éons un nouveau dossier ne
@@ -136,9 +136,9 @@ Rendez-vous ensuite dans votre navigateur sur
.
#### À vous de jouer {-}
Utilisez l'instruction `COPY`{.dockerfile} pour afficher votre propre
-`index.html` remplaçant celui installé de base par `nginx`. Si vous manquez
+`index.html` remplaçant celui installé de base par `nginx`.
### Les caches
@@ -177,9 +177,10 @@ images), en haut du `Dockerfile`.
L'instruction `LABEL`{.dockerfile} 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/stable/debian/Dockerfile#L8)
-est d'indiquer le nom du mainteneur de l'image :
+Une métadonnée courante[^MAINTAINER] est d'indiquer le nom du
+mainteneur de l'image :
+
+[^MAINTAINER]: Voir par exemple :
```dockerfile
@@ -221,15 +222,15 @@ 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 ?
+### 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 ?
+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
+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
@@ -300,7 +301,7 @@ 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 ?
+### D'autres instructions ?
Consultez pour la liste
complète des instructions reconnues.
@@ -310,12 +311,12 @@ complète des instructions reconnues.
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.
+déjà utilisé précédemment.
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ôt de sources de `youp0m` à :
+Vous pouvez cloner le dépôt de sources de `youp0m` à :\
Pour compiler le projet, vous pouvez utiliser dans votre `Dockerfile`
diff --git a/tutorial/dockerfiles/entrypoint.md b/tutorial/dockerfiles/entrypoint.md
index aaf91c2..db591b0 100644
--- a/tutorial/dockerfiles/entrypoint.md
+++ b/tutorial/dockerfiles/entrypoint.md
@@ -37,7 +37,7 @@ Hello world
Dans ce premier cas, il n'y a pas d'argument après le nom de l'image, c'est
-donc le contenu de `CMD`{.dockerfile} qui est utilisé ; il est donc passé en
+donc le contenu de `CMD`{.dockerfile} qui est utilisé ; il est donc passé en
argument à l'`ENTRYPOINT`{.dockerfile}. Concrètement, la première ligne de
commande exécutée est :
diff --git a/tutorial/dockerfiles/goodpractices.md b/tutorial/dockerfiles/goodpractices.md
index e4fbf9a..a9e18a1 100644
--- a/tutorial/dockerfiles/goodpractices.md
+++ b/tutorial/dockerfiles/goodpractices.md
@@ -27,8 +27,8 @@ dépendances ont bien été enregistrée.
Ce fichier fonctionne de la même manière que le `.gitignore` : vous pouvez
utiliser du globing.
-Pour plus d'informations, vous pouvez consulter la documentation accessible à
-.
+Pour plus d'informations, vous pouvez consulter la documentation accessible à\
+
### N'installez rien de superflu
@@ -40,7 +40,7 @@ comme serveur web. Un autre conteneur pourra contenir cet éditeur de texte dans
les cas où vous avez besoin de modifier des données.
En plus, cela réduira le temps de construction et la taille des images
-produites !
+produites !
Avec `apt` par exemple, vous pouvez ajouter l'option `--no-install-recommends`
lors vous installer un paquet qui vient avec de nombreuses recommandations
@@ -64,7 +64,7 @@ place.
#### Allez à la ligne pour séparer les longues lignes de commandes complexes\
-Aérez vos `Dockerfile` !
+Aérez vos `Dockerfile` !
N'hésitez pas à commenter et séparer les blocs logiques ensemble, comme lorsque
vous codez.
@@ -176,7 +176,7 @@ CMD ["-g", "daemon", "off;"]
- Vous pouvez aussi utiliser un script qui servira à faire les initialisations
ou les configurations nécessaire au bon fonctionnement du conteneur
- (rappelez-vous, il doit être éphémère !). Par exemple, le `Dockerfile` pour
+ (rappelez-vous, il doit être éphémère !). Par exemple, le `Dockerfile` pour
l'image de PostgreSQL possède cet entrypoint :
diff --git a/tutorial/dockerfiles/interactive.md b/tutorial/dockerfiles/interactive.md
index 55feb1a..0d35352 100644
--- a/tutorial/dockerfiles/interactive.md
+++ b/tutorial/dockerfiles/interactive.md
@@ -9,8 +9,8 @@ docker container run -it ubuntu /bin/bash
```
-Nous voilà maintenant dans le conteneur ! Il est assez épuré, il n'y a rien de
-superflu : même pas d'éditeur de texte : ni vim, ni emacs, même pas `vi` !
+Nous voilà maintenant dans le conteneur ! Il est assez épuré, il n'y a rien de
+superflu : même pas d'éditeur de texte : ni vim, ni emacs, même pas `vi` !
La première chose à faire est de télécharger la liste des paquets. En effet,
afin de ne pas livrer de superflu, la liste des paquets et son cache ne sont
@@ -69,7 +69,7 @@ doit servir de modèle. `my_nano` est le nom que vous voudrez utiliser
Cette action va figer la couche la plus haute de systèmes de fichiers, qui
-était jusqu'alors en lecture-écriture pour le conteneur ; afin d'en faire la
+était jusqu'alors en lecture-écriture pour le conteneur ; afin d'en faire la
dernière couche de notre nouvelle image.

@@ -83,10 +83,10 @@ docker container run -it my_nano /bin/bash
Vous constatez cette fois que vous pouvez lancer `nano`, alors que vous ne
-pouvez toujours pas le faire dans un conteneur issu d'une image `ubuntu` !
+pouvez toujours pas le faire dans un conteneur issu d'une image `ubuntu` !
-### Scripté ?
+### Scripté ?
On peut automatiser les étapes ci-dessus avec un script qui ressemblerait à ça :
diff --git a/tutorial/dockerfiles/others.md b/tutorial/dockerfiles/others.md
index 69d25e8..9fce49d 100644
--- a/tutorial/dockerfiles/others.md
+++ b/tutorial/dockerfiles/others.md
@@ -32,9 +32,10 @@ vous pouvez l'installer comme ceci :
```
+V="v0.6.3"
mkdir -p ~/.docker/cli-plugins
-curl https://github.com/docker/buildx/releases/download/v0.6.3/buildx-v0.6.3.linux-amd64 \
- -L -s -S -o ~/.docker/cli-plugins/docker-buildx
+curl -L -s -S -o ~/.docker/cli-plugins/docker-buildx \
+ https://github.com/docker/buildx/releases/download/$V/buildx-$V.linux-amd64
chmod +x ~/.docker/cli-plugins/docker-buildx
```
@@ -52,7 +53,8 @@ docker buildx build .
Nous ne rentrerons pas plus dans les détails de cette nouvelle commande, mais
sachez qu'on la retrouve particulièrement fréquemment dans les *GitHub
-Actions* :
+Actions* :\
+
#### Changer la syntaxe de nos `Dockerfile`\
@@ -108,7 +110,7 @@ La version habituelle de la syntaxe des `Dockerfile` est la version 1.1. En
utilisant BuildKit, nous pouvons dès à présent passer à la version 1.2 (stable)
ou 1.3 (expérimentale).
-Les ajouts par rapport à la syntaxe usuelle sont répertoriés sur cette page :\
+Les ajouts par rapport à la syntaxe usuelle sont répertoriés sur cette page :\
.
diff --git a/tutorial/dockerfiles/tutorial.md b/tutorial/dockerfiles/tutorial.md
index 402ac7c..24df4db 100644
--- a/tutorial/dockerfiles/tutorial.md
+++ b/tutorial/dockerfiles/tutorial.md
@@ -6,7 +6,7 @@ institute: EPITA
date: Mercredi 16 octobre 2019
abstract: |
Durant ce deuxième TP, nous allons voir comment créer nos propres
- images !
+ images !
\vspace{1em}
diff --git a/tutorial/header.tex b/tutorial/header.tex
index 0392eae..1343528 100644
--- a/tutorial/header.tex
+++ b/tutorial/header.tex
@@ -27,6 +27,7 @@
\usepackage{tcolorbox}
\usepackage{../virli}
+\usepackage{../virli-section}
\makeatletter
\pretocmd{\subsection}{\addtocontents{toc}{\protect\addvspace{-5\p@}}}{}{}
diff --git a/tutorial/k8s/Makefile b/tutorial/k8s/Makefile
index 70a0630..ce61613 100644
--- a/tutorial/k8s/Makefile
+++ b/tutorial/k8s/Makefile
@@ -1,6 +1,6 @@
include ../pandoc-opts.mk
-SOURCES_TUTO = tutorial-el.md setup.md intro.md overview.md discover.md run.md scaling.md rendu.md
+SOURCES_TUTO = tutorial-el.md setup.md intro-srs.md intro.md overview.md discover.md run.md scaling.md rendu.md
all: tutorial.pdf
diff --git a/tutorial/k8s/discover.md b/tutorial/k8s/discover.md
index d78aedd..23fe0ef 100644
--- a/tutorial/k8s/discover.md
+++ b/tutorial/k8s/discover.md
@@ -1,22 +1,21 @@
\newpage
Découverte de `kubectl`
-=======================
+-----------------------
`kubectl`
([prononcé](https://www.reddit.com/r/kubernetes/comments/5qthoc/how_should_i_pronounce_kubectl/)
-'cube C T L', 'cube cuttle', 'kyoob cuddle', 'cube control', ...) est le principal
+'cube C T L', 'cube cuttle', 'kyoob cuddle', 'cube control', ...) est le principal
programme que l'on utilise pour interagir avec notre cluster.
Étant donné qu'il s'agit d'un programme client, qui ne fait rien de plus que
discuter avec une API REST HTTP, on peut le considérer comme un gros wrapper au
dessus de `curl`.
-Obtenir de l'aide
------------------
+### Obtenir de l'aide
Commençons par apprivoiser `kubectl` en prenant quelques
-renseignements et surtout en apprennant comment obtenir de l'aide :
+renseignements et surtout en apprennant comment obtenir de l'aide :
```bash
@@ -26,44 +25,43 @@ kubectl explain type
Les `type`s que vous pouvez découvrir sont ceux que l'on a vu à la
-sections précédentes : `node`, `pod`, ...
+sections précédentes : `node`, `pod`, ...
La commande `describe` permet d'afficher l'état tel qu'il est attendu
et tel qu'il est actuellement (cela permet de se rendre lorsque les
deux divergent).
-`get`
------
+### `get`
Une autre manière, moins verbeuse, de récupérer des informations est
-d'utiliser `get` :
+d'utiliser `get` :
```bash
kubectl get node
```
-On peut ajouter des options pour avoir plus d'infos :
+On peut ajouter des options pour avoir plus d'infos :
```bash
kubectl get nodes -o wide
```
-... ou rendre la sortie lisible par une machine :
+... ou rendre la sortie lisible par une machine :
```bash
kubectl get no -o yaml
kubectl get no -o json
```
-On aimera utiliser `jq(1)` avec la sortie `-o json` :
+On aimera utiliser `jq(1)` avec la sortie `-o json` :
```bash
kubectl get no -o json | \
jq ".items[] | {name:.metadata.name} + .status.capacity"
```
-### Services
+#### Services
```bash
kubectl get services
@@ -75,15 +73,15 @@ Pour le moment, nous n'avons qu'un seul service, il s'agit de l'API Kubernetes.
`ClusterIP` désigne l'IP d'un service accessible en interne, pour le cluster.
-### Conteneurs actifs
+#### Conteneurs actifs
-Jetons un œil aux conteneurs actifs :
+Jetons un œil aux conteneurs actifs :
```bash
kubectl get pods
```
-Regardons maintenant les `namespaces` :
+Regardons maintenant les `namespaces` :
```bash
kubectl get namespaces
@@ -91,34 +89,33 @@ kubectl get namespaces
On l'a vu, les *namespaces* ici désignent des espaces de noms qui n'ont rien à
voir avec les *namespaces* de Linux. Regardons par exemple les conteneurs d'un
-autre espace de noms :
+autre espace de noms :
```bash
kubectl -n kube-system get pods
```
-Eh oui ! De nombreux services de base pour Kubernetes tournent dans des
-conteneurs, gérés par lui-même... notamment :
+Eh oui ! De nombreux services de base pour Kubernetes tournent dans des
+conteneurs, gérés par lui-même... notamment :
-- `etcd` : notre base de données clef/valeur,
-- `kube-apiserver` : l'API REST avec qui communique `kubectl`,
+- `etcd` : notre base de données clef/valeur,
+- `kube-apiserver` : l'API REST avec qui communique `kubectl`,
- `kube-controller-manager` et `kube-scheduler`, deux autres composants
indispensables,
-- `coredns` : un composant additionnel pour gérer la résolution de noms internes
+- `coredns` : un composant additionnel pour gérer la résolution de noms internes
(pour ne pas avoir à s'embêter avec les IP),
-- `kube-proxy` : 1 par nœud, pour gérer l'ouverture des ports notamment,
-- `kindnet`, `weave` : 1 par nœud, le plugin réseau.
+- `kube-proxy` : 1 par nœud, pour gérer l'ouverture des ports notamment,
+- `kindnet`, `weave` : 1 par nœud, le plugin réseau.
-Mon premier conteneur
----------------------
+### Mon premier conteneur
-Prêt à lancer notre premier conteneur ?!
+Prêt à lancer notre premier conteneur ?!
-Pas si vite ! En fait ... Kubernetes ne permet pas de lancer de conteneur...
+Pas si vite ! En fait ... Kubernetes ne permet pas de lancer de conteneur...
Nous devons lancer un *pod* (qui ne contiendra qu'un seul conteneur).
-### Mon premier pod
+#### Mon premier pod
```bash
kubectl run pingpong --image alpine ping 1.1.1.1
@@ -127,7 +124,7 @@ kubectl run pingpong --image alpine ping 1.1.1.1
`kubectl` doit nous indiquer nous qu'un *pod* a été créé.
Si l'on affiche la liste des *pod*s, vous devriez avoir quelque chose qui
-ressemble à cela :
+ressemble à cela :
```
$ kubectl get pods
@@ -135,18 +132,18 @@ NAME READY STATUS RESTARTS AGE
pingpong 1/1 Running 0 123s
```
-#### Sortie d'un conteneur
+##### Sortie d'un conteneur \
Allons maintenant regarder si nous recevons bien nos PONG.
Pour cela, nous allons utiliser la commande `kubectl logs`. Cette commande
-s'utilise d'une manière similaire à `docker logs` :
+s'utilise d'une manière similaire à `docker logs` :
```bash
kubectl logs pingpong
```
-ou bien :
+ou bien :
```bash
kubectl logs -f pingpong
@@ -155,27 +152,27 @@ kubectl logs -f pingpong
Notez ici l'option -f qui permet de suivre les logs en direct.
-Notre premier test ayant réussi, nous pouvons arrêter de DDos Cloudflare :
+Notre premier test ayant réussi, nous pouvons arrêter de DDos Cloudflare :
```bash
kubectl delete pods pingpong
```
-### Déploiement³
+#### Déploiement³
-Bien ... maintenant que nous savons nous débrouiller avec `kubectl`, attaquons
-les choses sérieuses : en temps normal avec Kubernetes, nous ne déploierons pas
+Bien ... maintenant que nous savons nous débrouiller avec `kubectl`, attaquons
+les choses sérieuses : en temps normal avec Kubernetes, nous ne déploierons pas
de *pod* directement, car cela reviendrait à utiliser Docker. Nous allons
plutôt créer des tâches de déploiement.
-Essayons sans plus attendre de lancer nos `ping` à travers une tâche de déploiement :
+Essayons sans plus attendre de lancer nos `ping` à travers une tâche de déploiement :
```bash
kubectl create deployment pingpong --image=alpine -- ping 8.8.8.8
```
-Si l'on regarde maintenant la sortie de `kubectl get all`, on obtient :
+Si l'on regarde maintenant la sortie de `kubectl get all`, on obtient :
```
NAME READY STATUS RESTARTS AGE
@@ -191,12 +188,12 @@ NAME DESIRED CURRENT READY AGE
replicaset.apps/pingpong-98f6d5899 1 1 0 123s
```
-Oula, on a vraiment lancé tout ça ?!
+Oula, on a vraiment lancé tout ça ?!
-Pas de panique, on peut très facilement le décortiquer :
+Pas de panique, on peut très facilement le décortiquer :
Les tâches de déploiement (*deployment.apps*) sont des ressources de
-haut niveau et sont là pour s'assurer que les migrations se font en douceur :
+haut niveau et sont là pour s'assurer que les migrations se font en douceur :
elles vont permettre de basculer progressivement les *pod*s d'une version X à une
version Y (par exemple si l'on change notre ping d'alpine 3.14 vers alpine
edge), mais éventuellement de revenir sur la version X si besoin, en cours de
@@ -207,14 +204,14 @@ s'assurer que le nombre de *pod*s actuellement lancé est bien en adéquation av
le nombre de *pod*s attendu.
\
-Pour résumer : `kubectl` a créé une tâche de déploiement
+Pour résumer : `kubectl` a créé une tâche de déploiement
`deploy/pingpong`. Cette tâche de déploiement a créé elle-même un *replicatset*
`rs/pingpong-xxxx`. Ce *replicatset* a créé un *pod* `po/pingpong-yyyy`.
-### Passage à l'échelle : facile ?
+#### Pasage à l'échelle : facile ?
-Pour lancer 3 `ping`s en parallèle, modifions la tâche de déploiement comme suit :
+Pour lancer 3 `ping`s en parallèle, modifions la tâche de déploiement comme suit :
```bash
kubectl scale deploy/pingpong --replicas 3
@@ -227,7 +224,7 @@ de *pod*s en cours d'exécution, il va en lancer de nouveaux, afin de répondre
la demande.
\
-Et que se passe-t-il alors, si l'on tue un *pod* ?
+Et que se passe-t-il alors, si l'on tue un *pod* ?
```bash
kubectl delete pod pingpong-yyyy
@@ -242,14 +239,14 @@ chacun des *pod*s un par un, car de nouveaux seraient créés par le
recréera un similaire (avec de nouveaux *pod*s).
Pour arrêter nos conteneurs, il convient donc de supprimer la tâche de
-déploiement :
+déploiement :
```bash
kubectl delete deploy pingpong
```
-### Exposer son conteneur
+#### Exposer son conteneur
Exposer un conteneur revient à créer un nouveau service (une ressource
*service*). Un service est une adresse IP que l'on peut considérer comme stable
@@ -262,37 +259,37 @@ Une fois le *service* créé, le serveur DNS interne va permettre de résoudre l
nom du *pod* depuis les autres conteneurs.
-#### Types de services
+##### Types de services\
-Il y a différents types de services :
+Il y a différents types de services :
-- `ClusterIP` (par défaut) : une adresse IP virtuelle est allouée pour le
+- `ClusterIP` (par défaut) : une adresse IP virtuelle est allouée pour le
service, elle n'est accessible que depuis le réseau interne (par les *pod*s et
les nœuds). Il n'y a pas de translation de port à effectuer.
-- `NodePort` : un port est alloué pour le service, sur tous les nœuds le
+- `NodePort` : un port est alloué pour le service, sur tous les nœuds le
cluster et n'importe qui peut alors s'y connecter. Le port est choisi
aléatoirement.
-- `LoadBalancer` : lorsque l'infrastructure sous-jacente fournit un
- load-balancer (typiquement AWS, GCE, Azure, ...), un service `NodePort` est
+- `LoadBalancer` : lorsque l'infrastructure sous-jacente fournit un
+ load-balancer (typiquement AWS, GCE, Azure, ...), un service `NodePort` est
créé pour utiliser ce load-balancer externe.
-- `ExternalName` : une entrée DNS est créée pour avoir un alias.
+- `ExternalName` : une entrée DNS est créée pour avoir un alias.
-#### Le retour de `youp0m`
+##### Le retour de `youp0m`\
-Déployons maintenant l'image `youp0m` pour voir comment utiliser les *service*s :
+Déployons maintenant l'image `youp0m` pour voir comment utiliser les *service*s :
```bash
kubectl create deployment youp0m --image=nemunaire/youp0m
```
-Commençons par créer un service `ClusterIP` :
+Commençons par créer un service `ClusterIP` :
```bash
kubectl expose deployment youp0m --port 8080
```
-Ce qui donne :
+Ce qui donne :
```
$ kubectl get service
@@ -304,15 +301,14 @@ Depuis un nœud du cluster, on peut donc venir interroger cette IP. Si l'on
essaie avec plusieurs nœuds, on voit alors que les requêtes sont balancées sur
différents nœuds.
-Si vous passez par `kind`, vous pouvez constater le bon fonctionnement grâce à :
+Si vous passez par `kind`, vous pouvez constater le bon fonctionnement grâce à :
```bash
docker exec -it kind-control-plane curl 10.102.129.233:8080
```
-Kubernetes dashboard
---------------------
+### Kubernetes dashboard
L'équipe de Kubernetes propose un tableau de bord assez pratique, qui permet de
voir toutes les *resources*, comme nous l'avons fait avec `kubectl`, mais dans
@@ -320,7 +316,7 @@ une interface web.
Ils mettent à disposition un fichier décrivant l'état d'un cluster ayant une
telle application. Nous pouvons demander à ce que notre cluster converge vers
-la configuration nécessaire :
+la configuration nécessaire :
```bash
kubectl create -f https://virli.nemunai.re/insecure-dashboard.yaml
@@ -329,13 +325,13 @@ kubectl create -f https://virli.nemunai.re/insecure-dashboard.yaml
::::: {.warning}
Notez que le dashboard, avec cette configuration, va s'exécuter sans les
-prérequis minimum de sécurité : pas de certificat TLS, ni
+prérequis minimum de sécurité : pas de certificat TLS, ni
d'authentification. Ceci est juste pour jouer avec l'interface, en production,
on n'utilisera pas cette recette.
:::::
-Regardons où nous pouvons contacter notre dashboard :
+Regardons où nous pouvons contacter notre dashboard :
```bash
$ kubectl get svc
@@ -344,7 +340,7 @@ dashboard NodePort 10.96.78.69 80:31505/TCP 3m10s
kubernetes ClusterIP 10.96.0.1 443/TCP 6m51s
```
-Regardons si cela répond :
+Regardons si cela répond :
```bash
$ docker exec -it kind-control-plane curl 10.96.78.69:80
@@ -362,7 +358,7 @@ configuration. Il va donc falloir indiquer à Kubernetes que l'on désire
utiliser un port spécifique pour exposer le tableau de bord.
Pour ce faire, éditons le fichier `insecure-dashboard.yaml`, pour ajouter, dans
-la partie `Service` un *node port* plus spécifique :
+la partie `Service` un *node port* plus spécifique :
```yaml
- port: 80
@@ -371,8 +367,8 @@ la partie `Service` un *node port* plus spécifique :
nodePort: 30002
```
-Maintenant, nous n'allons pas recréer un nouveau dashboard : nous allons
-simplement « appliquer » la nouvelle configuration :
+Maintenant, nous n'allons pas recréer un nouveau dashboard : nous allons
+simplement « appliquer » la nouvelle configuration :
```bash
kubectl apply -f my-insecure-dashboard.yaml
diff --git a/tutorial/k8s/intro-book.md b/tutorial/k8s/intro-book.md
new file mode 100644
index 0000000..2cb68c1
--- /dev/null
+++ b/tutorial/k8s/intro-book.md
@@ -0,0 +1,10 @@
+\newpage
+
+Présentation du fil rouge
+-------------------------
+
+Afin d'évaluer Kubernetes, nous allons travailler avec un mineur de
+pépites ... de chocolat !
+
+Alors, on se sert un bon thé, on prend sa boîte de gâteaux pour teniir le coup,
+et c'est parti !
diff --git a/tutorial/k8s/intro-srs.md b/tutorial/k8s/intro-srs.md
new file mode 100644
index 0000000..bfdadfe
--- /dev/null
+++ b/tutorial/k8s/intro-srs.md
@@ -0,0 +1,16 @@
+\newpage
+
+Introduction
+------------
+
+Aujourd'hui, nous allons travailler avec un mineur de pépites ... de
+chocolat !
+
+
+Comme c'est notre dernier cours ensemble, de véritables cookies sont à
+gagner pour celles et ceux qui auront amassé le plus de pépites d'ici
+la fin du TP[^cookies] ! Vous pouvez suivre votre progression sur
+[cette page](https://virli.nemunai.re/scores.html).
+
+[^cookies]: dans la limite des stocks disponibles.
diff --git a/tutorial/k8s/intro.md b/tutorial/k8s/intro.md
index dc55b24..8091fb1 100644
--- a/tutorial/k8s/intro.md
+++ b/tutorial/k8s/intro.md
@@ -1,23 +1,9 @@
-\newpage
-
-Introduction
-============
-
-Aujourd'hui, nous allons travailler avec un mineur de pépites ... de chocolat !
-
-
-Comme c'est notre dernier cours ensemble, de véritables cookies sont à
-gagner pour celles et ceux qui auront amassé le plus de pépites d'ici
-la fin du TP[^cookies] ! Vous pouvez suivre votre progression sur
-[cette page](https://virli.nemunai.re/scores.html).
-
-[^cookies]: Dans la limite des stocks disponibles.
+\

Fier de respecter le paradigme des micro-services, notre ChocoMiner fonctionne
-ainsi :
+ainsi :
* le `worker` demande à `rng` de générer un grand nombre aléatoire,
* le `worker` envoie ce grand nombre au `hasher`, qui lui retourne un hash,
@@ -31,8 +17,9 @@ Une interface graphique (`chronograf`) permet d'interroger la base de données
pour afficher des statistiques.
-Obtenir l'application
----------------------
+### Obtenir l'application
+
+Les micro-services sont regroupés sur le dépôt suivant :
```shell
@@ -41,57 +28,64 @@ git clone https://git.nemunai.re/srs/chocominer.git
-Rappels sur la découverte de services
--------------------------------------
+### Rappels sur la découverte de services
Dans Docker, nous avions vu que nous n'avions pas besoin de connaître les IP
-des conteneurs : un serveur DNS nous permettait de se connecter aux différents
+des conteneurs : un serveur DNS nous permettait de se connecter aux différents
services à partir de leurs noms.
-Dans Kubernetes, le même principe s'applique : dans aucun cas, nous ne devrions
+Dans Kubernetes, le même principe s'applique : dans aucun cas, nous ne devrions
inscrire en dur des adresses IP. Il convient d'utiliser au maximum le système
-DNS, car les IP sont susceptibles de changer !
+DNS, car les IP sont susceptibles de changer !
-Tester avec `docker-compose`
-----------------------------
+### Tester avec `docker-compose`
+
```bash
docker-compose up
```
+
-Une fois le docker-compose lancé, nous devrions pouvoir accéder à l'interface
-de chronograf pour voir l'avancement de recherche de pépites :
+Une fois le `docker-compose` lancé, nous devrions pouvoir accéder à l'interface
+de chronograf pour voir l'avancement de recherche de pépites :
-Montée en puissance
--------------------
+### Montée en puissance
+Avec `docker-compose`, on peut facilement monter en puissance. Commençons en
+augmentant doucement le nombre de `worker`, pour voir si cela a un impact :
+
+
```bash
docker-compose up -d --scale worker=2
```
+
-On remarque que le nombre de hashs calculés augmente ! Génial !
+On remarque que le nombre de hashs calculés augmente ! Génial ! Continuons
+d'augmenter alors :
+
```bash
docker-compose up -d --scale worker=10
```
+
-Mais ça atteint un palier au bout d'un moment...
+Mais l'augmentation n'est plus aussi nette, on semble atteindre un palier au
+bout d'un moment...
-Identification du goulot d'étranglement
----------------------------------------
+### Identification du goulot d'étranglement
De nombreux outils existent pour réaliser des tests de performance, essayons
`httping` sur nos différents services pour voir si un service ne serait pas
-la cause des ralentissements :
+la cause des ralentissements :
-- Testons `rng` : `httping -c 3 localhost:8001`,
-- puis testons `hasher` : `httping -c 3 localhost:8002`.
+- Testons `rng` : `httping -c 3 localhost:8001`,
+- puis testons `hasher` : `httping -c 3 localhost:8002`.
-Il semblerait que notre application `rng` nécessite d'être exécutée en parallèle
-! Mais on ne peut pas faire de répartition de charge facilement avec
-`docker-compose` !
+Il semblerait que notre application `rng` nécessite d'être exécutée en
+parallèle ! Mais on ne peut pas faire la répartition de charge facilement avec
+`docker-compose` !
diff --git a/tutorial/k8s/overview.md b/tutorial/k8s/overview.md
index 51cfc45..d97b782 100644
--- a/tutorial/k8s/overview.md
+++ b/tutorial/k8s/overview.md
@@ -1,16 +1,16 @@
-\newpage
-
Vue d'ensemble de Kubernetes
-============================
+----------------------------
-*Kubernetes* est un système open source d'orchestration et de gestion de
+*Kubernetes* (prononcé
+Ku-ber-né-tice](https://github.com/kubernetes/kubernetes/issues/44308) en grec)
+est un système open source d'orchestration et de gestion de
conteneurs. C'est-à-dire qu'il se charge de coller constamment aux
spécifications qu'on lui aura demandées.
-Ce projet est l'aboutissement de plus d'une dizaine d'années d'expérience de
-gestion de conteneurs applicatifs chez Google (rappelons que c'est eux qui ont
-poussé de nombreuses technologies dans le noyau Linux, notamment les
-*cgroups*, ...).
+Ce projet est l'aboutissement de plus d'une dizaine d'années
+d'expérience de gestion de conteneurs applicatifs chez Google
+(rappelons que c'est eux qui ont poussé de nombreuses technologies
+dans le noyau Linux, notamment les *cgroups*, ...).
Dans Kubernetes, il n'est pas question d'indiquer comment lancer ses
conteneurs, ni même quels *cgroups* utiliser. On va fournir à l'orchestrateur
@@ -18,23 +18,22 @@ des informations, des *spécifications*, qui vont altérer l'état du cluster. E
c'est en cherchant à être constamment dans l'état qu'on lui a décrit, qu'il va
s'adapter pour répondre aux besoins.
-Par exemple, on ne va pas lui expliquer comment lancer des conteneurs ou
-récupérer des images ; mais on va lui demander d'avoir 5 conteneurs `youp0m`
-lancés, de placer ces conteneurs derrière un load-balancer ; on pourra
-également lui demander d'adapter la charge pour absorber les pics de trafic
-(par exemple lors du Black Friday sur une boutique), mais également, il pourra
-gérer les mises à jour des conteneurs selon différentes méthodes, ...
+Par exemple, on ne va pas lui expliquer comment lancer des conteneurs
+ou récupérer des images ; mais on va lui demander d'avoir 5 conteneurs
+`youp0m` lancés, de placer ces conteneurs derrière un load-balancer ;
+on pourra également lui demander d'adapter la charge pour absorber les
+pics de trafic (par exemple lors du Black Friday sur une boutique),
+mais également, on pourra gérer les mises à jour des conteneurs selon
+différentes méthodes ...
-Architecture de Kubernetes
---------------------------
+### Architecture de Kubernetes

-Un cluster Kubernetes est composé d'un (ou plusieurs) nœuds *master*, et d'une
-série de *workers*.
+Un cluster Kubernetes est composé d’un (ou plusieurs) nœuds *master*, et d’une série de *workers*.
-Sur le(s) *master(s)*, on retrouve les composants suivants :
+Sur le(s) *master(s)*, on retrouve les composants suivants :
API HTTP
: On distingue plusieurs API, elles sont toutes utilisées pour communiquer avec
@@ -56,7 +55,7 @@ Le contrôleur
Chaque nœud (généralement, le nœud *master* est également *worker*) est utilisé
-via deux composants :
+via deux composants :
`kubelet`
: C'est l'agent qui va se charger de créer les conteneurs et les manager, afin
@@ -72,19 +71,18 @@ effectivement se charger de lancer les conteneurs demandés par `kubelet`.
Évidemment, chaque élément de l'architecture est malléable à souhait, c'est la
raison pour laquelle il peut être très difficile de mettre en place une
-architecture Kubernetes : avec ou sans haute-disponibilité, un nœud master
+architecture Kubernetes : avec ou sans haute-disponibilité, un nœud master
dédié au contrôle, avec un moteur de conteneur exotique (`rkt`, `ctr`, ...).
-*Resources*
------------
+### *Resources*
Avec Docker, nous avons eu l'habitude de travailler avec des objets (images,
containers, networks, volumes, secrets, ...). Au sein de Kubernetes, cela
s'appelle des *resources* et elles sont très nombreuses.
Parmi les plus courantes, citons les types (désignés *Kind* dans l'API, rien à
-voir avec le projet `kind` au début du sujet) suivants :
+voir avec le projet `kind` au début du sujet) suivants :
node
: il s'agit d'une machine de notre cluster (elle peut être physique ou
@@ -109,12 +107,11 @@ secret
: comme `docker secret`, il s'agit d'un moyen de passer des données sensibles à
un conteneur.
-Pour voir la liste complète des *resources*, on utilise : `kubectl
+Pour voir la liste complète des *resources*, on utilise : `kubectl
api-resources`.
-Modèle réseau
--------------
+### Modèle réseau
Pour Kubernetes, il n'y a qu'un seul gros réseau au sein duquel se retrouve
tous les conteneurs. Il ne doit pas y avoir de NAT, que ce soit entre les
@@ -135,8 +132,9 @@ loisir d'allouer l'adresse IP, d'ajouter les interfaces réseaux adéquates, de
configurer les routes, les règles de pare-feu, ...
-Pour aller plus loin
---------------------
+### Pour aller plus loin
-* [Kubernetes Documentation](https://kubernetes.io/docs/)
-* [A Reference Architecture for Deploying WSO2 Middleware on Kubernetes](https://medium.com/containermind/a-reference-architecture-for-deploying-wso2-middleware-on-kubernetes-d4dee7601e8e)
+* La documentation de Kubernetes :
+* A Reference Architecture for Deploying WSO2 Middleware on Kubernetes :\
+
+* Les spécifications CNI :
diff --git a/tutorial/k8s/rendu.md b/tutorial/k8s/rendu.md
index 7df82b1..116413d 100644
--- a/tutorial/k8s/rendu.md
+++ b/tutorial/k8s/rendu.md
@@ -30,7 +30,7 @@ Tarball
Tous les exercices de ce TP sont à placer dans une tarball (pas d'archive ZIP,
RAR, ...).
-Voici une arborescence type :
+Voici une arborescence type :
```
diff --git a/tutorial/k8s/run.md b/tutorial/k8s/run.md
index b66f01d..5b639cf 100644
--- a/tutorial/k8s/run.md
+++ b/tutorial/k8s/run.md
@@ -1,27 +1,26 @@
\newpage
Cookies dans Kube
-=================
+-----------------
Maintenant que nous en savons un peu plus sur Kubernetes, nous allons commencer
à déployer notre application ChocoMiner dans notre cluster. Pour cela, nous
-allons devoir :
+allons devoir :
-- lancer des déploiements de ces images ;
+- lancer des déploiements de ces images ;
- exposer avec un ClusterIP les services qui ont besoin de communiquer
- entre-eux ;
+ entre-eux ;
- exposer avec un NodePort l'interface graphique de contrôle.
-Lancement des *pod*s
---------------------
+### Lancement des *pod*s
-### Via Helm
+#### Via Helm
[Helm](https://helm.sh/) est l'équivalent d'un gestionnaire de paquets, mais
pour Kubernetes. Nous avons pu voir dans la section précédente qu'il faut
parfois écrire des fichiers de description YAML assez volumineux (et encore,
-celui du tableau de bord est tout petit !) afin de se faire comprendre de
+celui du tableau de bord est tout petit !) afin de se faire comprendre de
Kubernetes.
Helm se veut donc, notamment, être un moyen de packager une application, pour
@@ -37,14 +36,14 @@ que `kubectl`, il n'y a rien de plus à configurer.
Une fois `helm` installé, et le dépôt `influxdata` ajouté, comme précisé dans
la documentation du *chart* d'InfluxDB, nous pouvons le déployer dans notre
-cluster :
+cluster :
```bash
helm install influxdb influxdata/influxdb
```
Les valeurs de configuration indiquées dans le `README` du *chart* se modifient
-ainsi :
+ainsi :
```bash
helm upgrade -f values.yml your-influx-name influxdata/influxdb
@@ -58,18 +57,18 @@ Nous pouvons ensuite faire de même avec
mixer avec la méthode ci-dessous (en adaptant certaines valeurs).
-### Via `kubectl`
+#### Via `kubectl`
Si vous ne souhaitez pas utiliser `helm`, vous pouvez vous rabattre sur les
YAML que l'on a utilisés jusqu'à maintenant, et utiliser `kubectl`. Commençons
-par lancer `influxdb` :
+par lancer `influxdb` :
```bash
kubectl apply -f https://virli.nemunai.re/influxdb.yaml
```
Pour chronograf, la commande suivante fonctionnerait, mais prenons exemple sur
-le fichier YAML d'InfluxDB pour Chronograf :
+le fichier YAML d'InfluxDB pour Chronograf :
```bash
kubectl create deployment chronograf --image=chronograf -- chronograf \
@@ -78,7 +77,7 @@ kubectl create deployment chronograf --image=chronograf -- chronograf \
--influxdb-password=eBoo8geingie8ziejeeg8bein6Yai1a
```
-### Notre application
+#### Notre application
```bash
TAG=0.1
@@ -87,7 +86,7 @@ for SERVICE in hasher rng worker; do
done
```
-### Exposer les ports
+#### Exposer les ports
Pour trois des applications, des `ClusterIP` font l'affaire, car ils n'ont pas
besoin d'être exposés en dehors du cluster.
@@ -101,26 +100,27 @@ kubectl expose deployment hasher --port 80
Si vous avez utilisé le *chart* Helm d'InfluxDB, Un `ClusterIP` a été
automatiquement créé.
-Par contre, notre Chronograf doit être exposé, on lui alloue donc un NodePort :
+Par contre, notre Chronograf doit être exposé, on lui alloue donc un NodePort :
```bash
kubectl create service nodeport chronograf --tcp=8888 --node-port=30001
```
-À ce stade, nous devrions pouvoir accéder à l'interface de Chronograf !
+À ce stade, nous devrions pouvoir accéder à l'interface de Chronograf !
Le port 30001 est exposé par `kind` (cela faisait partie des ports redirigés par
-Docker entre le nœud *master* et votre machine !), nous devrions donc pouvoir
-nous rendre sur :
pour y voir Chronograf.
+Docker entre le nœud *master* et votre machine !), nous devrions donc pouvoir
+nous rendre sur :
pour y voir Chronograf.
-Pour afficher un graphique intéressant, on se rend dans *Explore*, on choisit
-la base `chocominer.autogen`, puis la table `hashes` et enfin on sélectionne
-l'élément `value`. Pour être tout à fait juste, il faut choisir la fonction
-`sum`, car nous voulons afficher le nombre total de condensat générés. Un
-second graphique intéressant est celui du nombre de pépites trouvées : il faut
-compter (`count`) le nombre d'éléments dans la table `chunks`.
+Pour afficher un graphique intéressant, on se rend dans la partie
+*Explore*, puis on choisit la base `chocominer.autogen`, puis la table `hashes`
+et enfin on sélectionne l'élément `value`. Pour être tout à fait juste, il faut
+choisir la fonction `summ`, car nous voulons afficher le nombre total de
+condensat générés. Un second graphique intéressant est celui du nombre de
+pépites trouvées : il faut compter (`count`) le nombre d'éléments dans la table
+`chunks`.

-Vous n'avez pas la même courbe de progression ? Continuons le TP alors, pour
-augmenter la puissance de notre *rig* !
+Vous n'avez pas la même courbe de progression ? Alors continuons pour augmenter
+la puissance de notre *rig* !
diff --git a/tutorial/k8s/scaling.md b/tutorial/k8s/scaling.md
index a284aeb..f8b6965 100644
--- a/tutorial/k8s/scaling.md
+++ b/tutorial/k8s/scaling.md
@@ -1,16 +1,15 @@
-Montée en charge
-----------------
+### Montée en charge
-Commençons facilement, en augmentant le nombre de `workers` :
+Commençons facilement, en augmentant le nombre de `workers` :
```bash
kubectl scale deploy/worker --replicas=10
```
Tout comme cela fonctionnait en partie avec `docker-compose`, on obtient ici le
-même résultat. Ouf ... c'était pas trop tôt !
+même résultat. Ouf ... c'était pas trop tôt !
-Nous pouvons profiter de regarder l'augmentation en direct, via la commande :
+Nous pouvons profiter de regarder l'augmentation en direct, via la commande :
```bash
kubectl get pods -w
@@ -20,7 +19,7 @@ Par contre, ce ne sera pas aussi simple d'augmenter le nombre de `rng`. En
effet, il nous faut répartir les services entre plusieurs machines.
-### Daemon sets
+#### Daemon sets
Une ressource *daemon sets* va s'assurer que tous les nœuds (ou une partie)
vont exécuter une instance d'un *pod*. Ainsi, si un nouveau nœud rejoint le
@@ -31,7 +30,7 @@ On s'en sert principalement pour exécuter une instance de daemon de stockage
(tel que Ceph, `glusterd`, ...) ou pour la collecte de logs (`fluentd`,
`logstash`, ...), voire du monitoring (Prometheus, `collectd`, ...)
-Pour créer un *daemon sets*, il est nécessaire d'écrire un fichier YAML :
+Pour créer un *daemon sets*, il est nécessaire d'écrire un fichier YAML :
```yaml
apiVersion: apps/v1
@@ -78,7 +77,7 @@ spec:
path: /var/lib/docker/containers
```
-Ensuite, on crée le *DaemonSet* en appliquant la nouvelle spécification :
+Ensuite, on crée le *DaemonSet* en appliquant la nouvelle spécification :
```bash
kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml
@@ -88,17 +87,17 @@ Pour plus d'informations, consultez [la
documentation](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/).
-#### *DaemonSet* `rng`
+##### *DaemonSet* `rng`
Pour réaliser le *DaemonSet* de notre *pod* `rng`, le plus simple est de partir
-d'un export de la ressource existante :
+d'un export de la ressource existante :
```bash
kubectl get deploy/rng -o yaml > rng.yml
```
La première chose que l'on peut faire, c'est changer le type décrit dans le
-champ `kind` :
+champ `kind` :
```yaml
kind: DaemonSet
@@ -111,24 +110,24 @@ Il vous faudra également retirer le champ `replicas` (qui n'a pas de sens ici,
vu que la réplication est basée sur les nœuds), les champs `strategy`,
`progressDeadlineSeconds`, ainsi que la ligne `status: {}`.
-##### Force ! {-}
+###### Force ! {-}
En fait, plutôt que de corriger ces erreurs, on aurait aussi très bien pu
-désactiver la validation comme ceci :
+désactiver la validation comme ceci :
```bash
kubectl apply -f rng.yml --validate=false
```
-#### Trop de *pods* `rng` {-}
+##### Trop de *pods* `rng` {-}
Après avoir appliqué la nouvelle spec, on constate qu'il y a beaucoup de *pod*s
`rng`. En effet, l'ancien *pod* déployé avec la ressource *deployment* est
toujours là.
-#### Bootleneck résolu ? {-}
+##### Botleneck résolu ? {-}
Admirez maintenant dans Chronograf si vous avez réussi à augmenter votre nombre
-de pépites !
+de pépites !
diff --git a/tutorial/k8s/setup.md b/tutorial/k8s/setup.md
index 628fc24..b43b948 100644
--- a/tutorial/k8s/setup.md
+++ b/tutorial/k8s/setup.md
@@ -3,11 +3,9 @@
Mise en place
=============
-La mise en place d'un cluster Kubernetes ([prononcé
-Ku-ber-né-tice](https://github.com/kubernetes/kubernetes/issues/44308) en grec)
-est une opération qui peut s'avérer très longue et complexe, car elle nécessite
-l'installation et la configuration de nombreux composants avant de pouvoir être
-utilisé sereinement.
+La mise en place d'un cluster Kuernetes est une opération qui peut s'avérer
+très longue et complexe, car elle nécessite l'installation et la configuration
+de nombreux composants avant de pouvoir être utilisé pleinement.
Cette opération n'étant pas très palpitante (c'est beaucoup de lecture de
documentations et d'heures passées à essayer de faire tomber en marche tous les
@@ -19,7 +17,7 @@ plupart des entreprises qui font le choix d'utiliser Kubernetes pour gérer leur
infrastructures, choisissent de passer par un prestataire. L'entreprise délègue
donc la gestion de son/ses cluster(s) à une autre entreprise, dont c'est le cœur de
métier. La plupart du temps, il va s'agir d'Amazon (via [Elastic Kubernetes
-Service](https://aws.amazon.com/fr/eks/)), d'Azur ([Kubernetes
+Service](https://aws.amazon.com/fr/eks/)), d'Azure [Kubernetes
Service](https://azure.microsoft.com/fr-fr/services/kubernetes-service/)) ou
Google ([Kubernetes Engine](https://cloud.google.com/kubernetes-engine/)), mais
d'autres acteurs plus petits existent aussi
@@ -28,79 +26,63 @@ d'autres acteurs plus petits existent aussi
::::: {.more}
Pour l'IoT ou l'Edge Computing, sur du matériel léger, il existe le projet
-k3s[^k3s] : il s'agit d'une distribution Kubernetes beaucoup plus simple à
+k3s[^k3s] : il s'agit d'une distribution Kubernetes beaucoup plus simple à
déployer, et parfaitement adaptée à la production sur Raspberry Pi et autres.
:::::
-[^k3s]: https://k3s.io/
+[^k3s]: Lightweight Kubernetes :
Pour jouer aujourd'hui, plusieurs solutions s'offrent à nous pour commencer à
utiliser Kubernetes facilement :
-- [Docker Desktop (for Mac ou for Windows) :](#dockerdesktop) si vous êtes sur l'un de ces
+- [Docker Desktop (for Mac ou for Windows) :](#dockerdesktop) si vous êtes sur l'un de ces
systèmes c'est la solution la plus simple,
-- [Kubernetes in Docker (kind) :](#kind) pour tenter l'aventure sur votre machine,
-- [Play With Kubernetes :](#pwk) si vous ne vous en sortez pas avec `kind`.
+- [Kubernetes in Docker (kind) :](#kind) pour tenter l'aventure sur votre machine,
+- [Play With Kubernetes :](#pwk) si vous ne vous en sortez pas avec `kind`.
\newpage
-Docker for Mac/Windows {#dockerdesktop}
-----------------------
+### Docker for Mac/Windows {#dockerdesktop}
*Docker Desktop* pour Mac ou pour Windows intégre Kubernetes directement. Il
n'est pas activé par défaut, pour cela il convient d'activer l'option dans les
-préférences de l'application :
+préférences de l'application :
-
+
Une fois l'option activée, vous pouvez passer au chapitre suivant, la commande
`kubectl` devrait marcher directement pour vous. C'est principalement grâce à
cette commande que nous interagirons avec l'API de Kubernetes.
-Une fois que tout sera opérationnel, nous devrions obtenir :
+Une fois que tout sera opérationnel, nous devrions obtenir :
```
42sh$ kubectl version
-Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"archive", BuildDate:"2021-11-18T15:50:50Z", GoVersion:"go1.17.2", Compiler:"gc", Platform:"linux/amd64"}
-Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.5+k3s2", GitCommit:"724ef700bab896ff252a75e2be996d5f4ff1b842", GitTreeState:"clean", BuildDate:"2021-10-05T19:59:14Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
+Client Version: version.Info{Major:"1", minor:"22", GitVersion:"v1.22.2", [...]
+Server Version: version.Info{Major:"1", minor:"21", GitVersion:"v1.21.5", [...]
```
-Kubernetes in Docker (kind) {#kind}
----------------------------
+### Kubernetes in Docker (kind) {#kind}
`kind` est un projet permettant de lancer un cluster Kubernetes directement via
Docker.
Pour commencer, il nous faudra télécharger le binaire (go, donc statique)
-suivant (il existe pour Linux, macOS et Windows) :
+suivant (il existe pour Linux, macOS et Windows) :
-
-```bash
-curl -Lo kind https://github.com/kubernetes-sigs/kind/releases/download/v0.11.1/kind-$(uname)-amd64
-chmod +x kind
-```
-
+
-Placez le binaire dans un endroit où il sera accessible de votre `$PATH`.
-
-::::: {.question}
-
-`uname` est à remplacer par votre système d'exploitation : `darwin` (macOS), `linux`, `windows`.
-
-Il existe également pour d'autres architectures, consultez la [page des
-versions](https://github.com/kubernetes-sigs/kind/releases/latest) pour voir
-les différents binaires existants.
-
-:::::
+Placez le binaire (`chmod +x {}`) dans un endroit où il sera accessible de
+votre `$PATH`.
-Notre prochaine étape est de décrire le cluster que l'on souhaite avoir : 1
+Notre prochaine étape est de décrire le cluster que l'on souhaite avoir : 1
master et 2 workers, ça fera l'affaire. Attention tout de même de ne pas être
-trop extravagant, car chaque nœud consomme pas mal de RAM ! Et puis nous
+trop extravagant, car chaque nœud consomme pas mal de RAM ! Et puis nous
pourrons facilement changer cette configuration plus tard.
@@ -126,25 +108,19 @@ kind create cluster --config my-cluster.yml
La création du cluster peut prendre quelques minutes.
-Profitons-en pour télécharger `kubectl` :
-
-
-```bash
-curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.22.2/bin/linux/amd64/kubectl
-chmod +x kubectl
-```
-
+Profitons-en pour télécharger `kubectl` :\
+
C'est principalement grâce à cette commande que nous interagirons avec l'API de
Kubernetes.
-Une fois que tout sera opérationnel, nous devrions obtenir :
+Une fois que tout sera opérationnel, nous devrions obtenir :
```
42sh$ kubectl version
-Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"archive", BuildDate:"2021-11-18T15:50:50Z", GoVersion:"go1.17.2", Compiler:"gc", Platform:"linux/amd64"}
-Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.5+k3s2", GitCommit:"724ef700bab896ff252a75e2be996d5f4ff1b842", GitTreeState:"clean", BuildDate:"2021-10-05T19:59:14Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
+Client Version: Version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", [...]
+Server Version: Version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.5", [...]
```
@@ -153,8 +129,7 @@ pris soin de l'exposer pour vous au moment de la création du cluster.
Passez ensuite au chapitre suivant si vous avez réussi à mettre en place `kind`.
-Play With Kubernetes {#pwk}
---------------------
+### Play With Kubernetes {#pwk}
::::: {.warning}
@@ -163,18 +138,18 @@ cluster Kubernetes selon les autres méthodes décrites.
:::::
-De la même manière que pour les TP utilisant Docker, si vous avez des
+De la même manière que pour les exercices utilisant Docker, si vous avez des
difficultés pour réaliser les exercices sur vos machines, vous pouvez utiliser
le projet [Play With K8s](https://play-with-k8s.com/) qui vous donnera accès à
-un bac à sable avec lequel vous pourrez réaliser tous les exercices de ce TP.
+un bac à sable avec lequel vous pourrez réaliser tous les exercices.
-Il nous faut créer plusieurs instances, disons 3 : parmi elles, 1 instance sera
+Il nous faut créer plusieurs instances, disons 3 : parmi elles, 1 instance sera
la master, nous l'utiliserons principalement, les deux autres ne feront
qu'exécuter des conteneurs, nous pourrons les oublier dès qu'on les aura
connectées au master.
Pour initialiser notre cluster Kubernetes, nous allons devoir créer notre
-master. Pour cela, dans notre première instance, nous allons taper :
+master. Pour cela, dans notre première instance, nous allons taper :
```bash
@@ -183,7 +158,7 @@ kubeadm init --apiserver-advertise-address $(hostname -i)
Cette action peut prendre quelques minutes et devrait se finir, si tout se
-passe bien, par :
+passe bien, par :
```
@@ -202,7 +177,7 @@ Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
You can now join any number of machines by running the following on each node
as root:
-kubeadm join --token SOMETOKEN SOMEIPADDRESS --discovery-token-ca-cert-hash SOMESHAHASH
+kubeadm join --token TOKEN IPADDRESS --discovery-token-ca-cert-hash SHAHASH
```
@@ -212,18 +187,18 @@ master.
Dernière étape pour la mise en place de notre cluster, il s'agit de définir un
profil de politique réseau, sur le master (nous n'exécuterons plus de commande
-sur les autres workers) :
+sur les autres workers) :
```bash
kubectl apply -n kube-system -f \
- "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 |tr -d '\n')"
+ "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | \
+ base64 | tr -d '\n')"
```
-Minikube, k3d, MicroK8s, ...
-----------------------------
+### Minikube, k3d, MicroK8s, ...
Si les solutions précédentes ne sont pas adaptées à votre usage, de nombreuses
autres applications permettent de mettre en place un cluster plus ou moins
@@ -239,7 +214,7 @@ Vous pouvez tenter d'utiliser
est un script similaire à `kind`, mais utilise `k3s`, une version plus légère
et compacte de Kubernetes.
-Après l'avoir installé, vous pouvez lancer
+Après l'avoir installé, vous pouvez lancer :
```bash
diff --git a/tutorial/virli-section.sty b/tutorial/virli-section.sty
new file mode 100644
index 0000000..f98cb6d
--- /dev/null
+++ b/tutorial/virli-section.sty
@@ -0,0 +1 @@
+\renewcommand\section{\@startsection{section}{1}{\z@}{\z@}{5mm}{\section@box}}
diff --git a/tutorial/virli.sty b/tutorial/virli.sty
index ea6fad8..1774046 100644
--- a/tutorial/virli.sty
+++ b/tutorial/virli.sty
@@ -4,8 +4,6 @@
boxsep=0mm,top=4mm,bottom=4mm,left=\oddsidemargin+1in,right=\oddsidemargin+1in,
spread sidewards,fuzzy halo=1mm with ForestGreen!50!black}
-\renewcommand\section{\@startsection{section}{1}{\z@}{\z@}{5mm}{\section@box}}
-
\newtcolorbox{alertbox}[1][]{breakable,enhanced,
before skip balanced=2mm,after skip balanced=3mm,
tile,left=11mm,right=2mm,top=1mm,bottom=1mm,
@@ -40,5 +38,5 @@
sharp corners,
underlay={%
\path[fill=ForestGreen!50!white,draw=none] (interior.south west) rectangle node[white]{\Huge\bfseries (} ([xshift=6mm]interior.north west);
- \path[fill=ForestGreen!50!white,draw=none] (interior.south east) rectangle node[white]{\Huge\bfseries )} ([xshift=6mm]interior.north east);
+ \path[fill=ForestGreen!50!white,draw=none] (interior.south east) rectangle node[white]{\Huge\bfseries )} ([xshift=-6mm]interior.north east);
},#1}