Exercice 3 — Images et conteneurs¶
Durée : ~35 min · Individuel · Théorie associée : Docker : images et conteneurs, Les commandes de base de Docker
Objectif¶
Vous avez vu par vous-même qu'un conteneur est un programme isolé, qu'il naît d'une image qui ne change jamais, et que chaque conteneur est indépendant des autres.
Prérequis¶
- L'exercice 2 terminé : vous êtes connecté à votre VM
docker, etdocker psrépond sanssudo.
Étape 1 — Télécharger une image sans la lancer¶
Alpine est une distribution Linux minuscule, très utilisée comme base pour les images Docker.
Using default tag: latest
latest: Pulling from library/alpine
...
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest
docker pull fait seulement la première étape de docker run : il télécharge l'image, sans créer de conteneur.
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest b92841763c5c 13 days ago 8.43MB
hello-world latest e2ac70e7319a 7 months ago 10.1kB
Un système Linux complet en 8 Mo. Votre template Debian en occupe plus de 2 Go. La différence : l'image n'a pas de noyau, pas de pilotes, pas de service de démarrage. Elle utilisera le noyau de votre VM.
Étape 2 — Lancer une seule commande dans un conteneur¶
Tout ce qui suit le nom de l'image, ici cat /etc/os-release, est la commande à lancer dans le conteneur. Elle remplace la commande prévue par l'image.
Le fichier lu est celui du conteneur : il décrit Alpine. Comparez avec celui de votre VM :
Votre VM est une Debian 13. Le conteneur a ses propres fichiers, séparés de ceux de la VM.
Étape 3 — Le conteneur n'a qu'un seul programme¶
Dans le conteneur, il n'y a qu'un seul processus : ps lui-même, avec le numéro 1. Pas de systemd, pas de sshd, pas de cron. Rien d'autre ne tourne.
Faites la même commande dans votre VM :
Votre VM compte plus d'une centaine de processus. C'est la différence entre un conteneur système (LXC ou VM), qui fait tourner un système entier, et un conteneur applicatif, qui ne fait tourner qu'un programme.
Étape 4 — Le noyau, lui, est partagé¶
Les deux commandes affichent le même numéro de version. Le conteneur n'a pas de noyau à lui : il utilise celui de la VM. C'est pourquoi il démarre en une fraction de seconde. Il n'y a rien à démarrer, à part le programme.
Étape 5 — Entrer dans un conteneur¶
L'invite change et devient / #. Vous êtes dans un shell, à l'intérieur d'un nouveau conteneur, connecté en root. Tapez ces commandes l'une après l'autre :
hostname affiche une suite de 12 caractères : c'est le début de l'identifiant du conteneur. ls / montre une arborescence Linux ordinaire, mais elle appartient au conteneur.
Étape 6 — Laisser une trace dans le conteneur¶
Toujours dans le shell du conteneur :
Puis sortez :
Vous revenez à l'invite de la VM. Le shell s'est terminé : c'était le programme principal du conteneur, qui s'est donc arrêté.
Étape 7 — Lancer un deuxième conteneur¶
Le fichier n'existe pas. Ce n'est pas le même conteneur : docker run en a créé un nouveau, à partir de l'image, qui ne contient pas votre fichier. L'image n'a pas changé quand vous avez écrit dans le premier conteneur.
Vérifiez avec hostname : l'identifiant est différent de celui de l'étape 5. Tapez exit.
Étape 8 — Retrouver le premier conteneur¶
Le premier conteneur n'a pas été supprimé, il est seulement arrêté.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23a3641c85f8 alpine "sh" 10 seconds ago Exited (0) 4 seconds ago laughing_haibt
4e144cf83c7b alpine "sh" 7 minutes ago Exited (0) 7 minutes ago relaxed_heisenberg
a8160bd07d75 alpine "uname -r" 24 minutes ago Exited (0) 24 minutes ago agitated_brahmagupta
...
Chaque docker run des étapes 2 à 7 a laissé un conteneur arrêté. Repérez celui de l'étape 5 : c'est le plus ancien des deux conteneurs dont la commande est "sh". Relancez-le, avec son nom :
docker start relance un conteneur existant. Les options -a et -i y rattachent votre terminal, comme -it le faisait au docker run. Dans le shell :
Le fichier est là : c'est bien le même conteneur. Un conteneur arrêté garde son contenu. Tapez exit.
Étape 9 — Ne plus laisser de traces¶
Les conteneurs arrêtés s'accumulent vite. Quand vous lancez un conteneur pour un test d'une seconde, ajoutez --rm :
Le message s'affiche, mais aucun nouveau conteneur n'apparaît dans la liste : Docker l'a supprimé dès son arrêt.
Étape 10 — Faire le ménage¶
Supprimez tous les conteneurs arrêtés d'un seul coup :
Docker demande une confirmation : répondez y. Il affiche la liste des conteneurs supprimés et l'espace libéré. docker ps -a est vide.
L'image alpine est toujours là (docker images) : vous allez la réutiliser.
Étape 11 — Supprimer une image¶
L'image hello-world ne vous servira plus. Lancez-la une dernière fois, puis essayez de la supprimer :
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container 27851b557f1d is using its referenced image e2ac70e7319a
Docker refuse : le conteneur que vous venez de créer est arrêté, mais il existe encore, et il dépend de l'image. Une image ne peut pas être supprimée tant qu'un conteneur, même arrêté, en dépend.
Supprimez d'abord le conteneur, avec le nom affiché par docker ps -a, puis l'image :
docker images n'affiche plus que alpine. Si vous relanciez docker run hello-world, Docker devrait la télécharger de nouveau.
Étape 12 — Le ménage des images¶
docker rmi supprime une image à la fois. Pour faire le ménage d'un coup, Docker propose :
| Commande | Supprime |
|---|---|
docker container prune |
Tous les conteneurs arrêtés |
docker image prune |
Les images sans étiquette, restes de téléchargements ou de constructions remplacés |
docker image prune -a |
Toutes les images qu'aucun conteneur n'utilise |
Répondez y. Docker ne supprime rien : vous n'avez pas d'image sans étiquette. Ne lancez pas docker image prune -a maintenant : il supprimerait alpine, qu'aucun conteneur n'utilise. Vous vous en servirez à la fin du défi de l'exercice 6.
Vérification finale¶
- Vous savez montrer qu'un conteneur Alpine utilise le même noyau que la VM
- Le fichier
/root/note.txta disparu dans le deuxième conteneur, et était toujours là audocker startdu premier -
docker rmi hello-worlda d'abord été refusé, puis a réussi après la suppression du conteneur -
docker ps -aest vide, etdocker imagesn'affiche plus quealpine
Question 1¶
À l'étape 7, le fichier /root/note.txt n'existait pas. À l'étape 8, il était là. Expliquez la différence.
Voir la réponse
À l'étape 7, `docker run` a créé un **nouveau** conteneur à partir de l'image `alpine`. L'image ne contient pas le fichier : vous l'aviez écrit dans un autre conteneur, et écrire dans un conteneur ne modifie jamais l'image. À l'étape 8, `docker start` a relancé **le même** conteneur que celui de l'étape 5, qui avait été arrêté mais pas supprimé. Il avait gardé son contenu.Question 2¶
Pourquoi le conteneur Alpine démarre-t-il en une fraction de seconde, alors que votre VM met une minute ?
Voir la réponse
Le conteneur ne démarre pas de système d'exploitation. Il n'a pas de noyau à charger (il utilise celui de la VM, comme l'a montré `uname -r`), et pas de services à lancer (l'étape 3 a montré qu'un seul processus y tourne). Démarrer un conteneur, c'est seulement lancer un programme, dans un espace isolé.En cas de problème¶
| Symptôme | Cause probable | Correction |
|---|---|---|
docker run -it alpine bash répond executable file not found |
Alpine n'a pas bash, seulement sh |
Utiliser sh |
docker start relaxed_heisenberg ne donne pas de shell |
Il manque -ai |
docker start -ai relaxed_heisenberg |
docker start répond No such container |
Le nom ne correspond pas à un de vos conteneurs | Copier le nom depuis la colonne NAMES de docker ps -a |
L'invite reste / # après une commande |
Vous êtes encore dans le conteneur | exit |










