Exercice 2 — Préparer sa VM et lancer un premier conteneur¶
Durée : ~45 min · Individuel · Théorie associée : Docker : images et conteneurs
Objectif¶
Vous avez construit votre propre VM Docker sur votre serveur, et vous y avez lancé votre premier conteneur en sachant ce que fait chaque étape.
Prérequis¶
- Votre serveur Proxmox de la semaine 2, accessible à
https://10.70.44.#:8006. Le#est votre numéro de serveur dans le tableau de la semaine 2. - Le nœud a accès à Internet depuis son Shell.
Vous travaillez seul, sur votre propre serveur. Dans tout l'exercice, remplacez # par votre numéro de serveur.
| VM ID | Nom | Adresse |
|---|---|---|
731 |
docker |
10.70.#.31/16 |
Exemple : sur le serveur S04, la VM prend l'adresse 10.70.4.31. Les captures montrent ce serveur.
Les étapes 1 à 10 reprennent le template de l'exercice 2 de la semaine 4. La différence : la VM n'est pas convertie en template, et son snippet installe Docker.
Étape 1 — Autoriser les snippets sur le stockage local¶
Allez dans Datacenter > Storage, sélectionnez local et cliquez sur Edit. Dans la liste Content, ajoutez Snippets sans retirer les autres types. Si Snippets est déjà sélectionné, cliquez sur Cancel.
Étape 2 — Télécharger l'image cloud¶
Ouvrez le Shell du nœud.
Le fichier fait environ 330 Mo. Si wget a créé un second fichier debian-13-genericcloud-amd64.qcow2.1, l'image était déjà là : supprimez la copie avec rm debian-13-genericcloud-amd64.qcow2.1.
Étape 3 — Écrire le snippet Docker¶
Écrivez exactement ceci :
#cloud-config
packages:
- qemu-guest-agent
- docker.io
- curl
runcmd:
- systemctl enable --now qemu-guest-agent
- systemctl enable --now docker
- usermod -aG docker etudiant
C'est le snippet de la semaine 4, avec deux paquets de plus : docker.io installe Docker, et la dernière ligne ajoute le compte etudiant au groupe docker. Vous verrez à l'étape 12 à quoi sert ce groupe.
Étape 4 — Créer la VM vide¶
qm create 731 --name docker --memory 2048 --cores 2 --cpu x86-64-v2-AES --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single --ostype l26
La VM 731 apparaît dans l'arborescence, sans disque.
Étape 5 — Importer l'image comme disque¶
qm set 731 --scsi0 local-lvm:0,import-from=/var/lib/vz/template/iso/debian-13-genericcloud-amd64.qcow2
Proxmox crée le volume vm-731-disk-0 et y recopie l'image. Le système est déjà dedans : il n'y a rien à installer. La copie prend de une à plusieurs minutes. Attendez la ligne successfully created disk et le retour de l'invite.
Étape 6 — Agrandir le disque¶
Les images Docker prennent vite de la place. Cloud-init agrandira le système de fichiers au premier démarrage.
Étape 7 — Ajouter le lecteur Cloud-Init¶
C'est le lecteur dans lequel Proxmox dépose le compte, l'adresse et le snippet de la VM.
Étape 8 — Régler le démarrage et la console¶
Ce sont les mêmes réglages qu'à la semaine 4. Le port série rend possible la console xterm.js de l'étape 11.
Étape 9 — Rattacher le snippet¶
La forme vendor= ajoute le snippet à ce que Proxmox génère. Les champs du panneau Cloud-Init de l'étape suivante restent donc utilisés.
Étape 10 — Remplir le panneau Cloud-Init¶
Sélectionnez la VM 731 dans l'arborescence et ouvrez son panneau Cloud-Init. Remplissez quatre lignes avec le bouton Edit.
| Ligne | Valeur |
|---|---|
| User | etudiant |
| Password | Motdepasse123! |
| DNS servers | 9.9.9.9 |
| IP Config (net0) | IPv4 Static, 10.70.#.31/16, passerelle 10.70.0.1 |
Étape 11 — Démarrer la VM et s'y connecter¶
Cliquez sur Start. Attendez deux ou trois minutes : au premier démarrage, cloud-init télécharge et installe Docker.
Ouvrez ensuite la console avec la flèche à côté de Console, puis xterm.js. Cette console accepte le copier-coller, ce qui vous évitera de retaper les commandes. Connectez-vous avec etudiant / Motdepasse123!.
Étape 12 — Vérifier que vous avez le droit de parler à Docker¶
Cherchez docker à la fin de la ligne. Les membres du groupe docker peuvent utiliser Docker sans taper sudo devant chaque commande. C'est la dernière ligne du snippet de l'étape 3 qui vous y a ajouté.
Si docker n'apparaît pas, c'est que cloud-init vous a ajouté au groupe après votre connexion. Tapez exit, puis reconnectez-vous : le groupe est lu à chaque connexion.
Le groupe docker vaut le compte root
Un membre du groupe docker peut lancer un conteneur qui lit et modifie n'importe quel fichier de la VM. Sur un vrai serveur, on n'y met que les administrateurs.
Étape 13 — Vérifier le client et le démon¶
Client:
Version: 26.1.5+dfsg1
API version: 1.45
...
Server:
Engine:
Version: 26.1.5+dfsg1
API version: 1.45 (minimum version 1.24)
...
Repérez les deux parties. Client est la commande docker que vous venez de taper. Server est la réponse du démon dockerd, qui tourne en permanence dans la VM. Les deux répondent : tout est en place.
Étape 14 — Lancer votre premier conteneur¶
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
4f55086f7dd0: Pull complete
Digest: sha256:...
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
...
Chaque partie de la sortie correspond à une étape :
| Ligne | Ce qui s'est passé |
|---|---|
Unable to find image 'hello-world:latest' locally |
Le démon a cherché l'image sur le disque de la VM, sans la trouver. Vous n'avez pas écrit d'étiquette : il a pris latest. |
Pulling from library/hello-world |
Il la télécharge depuis Docker Hub. library/ désigne les images officielles. |
Status: Downloaded newer image |
L'image est maintenant sur le disque. |
Hello from Docker! et la suite |
Ce texte n'est pas écrit par Docker, mais par le programme du conteneur. Docker vous le transmet. |
Les quatre étapes numérotées du message correspondent à celles de la section 9 de la note.
Étape 15 — Le relancer¶
Le même message s'affiche, mais les quatre premières lignes ont disparu, et la réponse est instantanée. L'image était déjà sur le disque : il n'y avait rien à télécharger.
Étape 16 — Compter les images et les conteneurs¶
Une image, qui pèse 10 ko. Elle ne contient qu'un petit programme qui affiche un texte.
La liste est vide : aucun conteneur ne tourne. Le programme de hello-world a affiché son texte, puis s'est terminé, et le conteneur s'est arrêté avec lui.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
873946e066ff hello-world "/hello" 19 seconds ago Exited (0) 18 seconds ago great_sutherland
3ae65f46247c hello-world "/hello" 35 seconds ago Exited (0) 34 seconds ago agitated_lederberg
Avec -a, les conteneurs arrêtés apparaissent : il y en a deux, un par docker run. Une image, deux conteneurs, chacun avec sa propre couche inscriptible. Vos identifiants et vos noms seront différents, puisque Docker les choisit au hasard.
Lisez la colonne STATUS : Exited (0) veut dire que le programme s'est terminé normalement.
Étape 17 — Faire le ménage¶
Supprimez les deux conteneurs, en utilisant les noms affichés dans votre colonne NAMES :
Vérifiez avec docker ps -a : la liste est vide. Puis docker images : l'image hello-world est toujours là. Supprimer un conteneur ne supprime pas son image.
Vérification finale¶
-
docker versionaffiche les partiesClientetServer, sanssudo -
docker imagesaffiche l'imagehello-world -
docker ps -an'affiche plus aucun conteneur
Question 1¶
Au premier docker run hello-world, Docker a téléchargé l'image. Au deuxième, non. Pourquoi ?
Voir la réponse
Au premier lancement, l'image n'était pas sur le disque de la VM : le démon l'a téléchargée depuis Docker Hub, puis il l'a gardée. Au deuxième, il l'a trouvée sur le disque et a directement créé le conteneur. C'est pourquoi un `docker run` est lent la première fois, et presque instantané ensuite.Question 2¶
Après vos deux docker run, docker ps n'affiche rien, mais docker ps -a affiche deux lignes. Qu'est-ce que ça veut dire ?
Voir la réponse
Les deux conteneurs existent encore, mais ils sont arrêtés. `docker ps` ne montre que les conteneurs en marche. `docker ps -a` montre aussi les conteneurs arrêtés. Ils sont arrêtés parce que leur programme, `/hello`, s'est terminé après avoir affiché son texte. Un conteneur vit aussi longtemps que son programme principal.En cas de problème¶
| Symptôme | Cause probable | Correction |
|---|---|---|
permission denied while trying to connect to the Docker daemon socket |
Votre session a commencé avant votre ajout au groupe docker |
exit, puis se reconnecter. Vérifier avec groups |
docker: command not found |
cloud-init n'a pas fini d'installer Docker | Attendre une minute. cloud-init status doit répondre status: done |
La VM refuse de démarrer : volume 'local:snippets/docker.yaml' does not exist |
Le snippet n'est pas au bon endroit, ou Snippets n'est pas autorisé sur local |
Refaire les étapes 1 et 3 |
qm create répond VM 731 already exists |
Une VM porte déjà ce numéro sur votre serveur | Supprimer l'ancienne VM si elle vous appartient. Sinon, prévenir l'enseignant : le serveur est partagé avec l'autre groupe |
Cannot connect to the Docker daemon |
Le démon ne tourne pas | sudo systemctl status docker, puis sudo systemctl start docker |
dial tcp: lookup registry-1.docker.io ... no such host |
La VM n'a pas accès à Internet ou au DNS | ping -c 2 10.70.0.1, puis ping -c 2 9.9.9.9. Vérifier l'adresse et la passerelle dans le panneau Cloud-Init (étape 10) |
toomanyrequests: You have reached your pull rate limit |
Docker Hub limite le nombre de téléchargements par adresse IP, et toute la classe sort par la même | Prévenir l'enseignant |
Des lignes comme [ 228.734113] docker0: port 1(veth5dfe819) entered blocking state s'intercalent dans les sorties |
La console xterm.js est la console série de la VM, où le noyau écrit aussi ses messages | sudo dmesg -n 1, valable jusqu'au prochain redémarrage |
| Une commande longue se réécrit par-dessus elle-même sur la même ligne | La console série annonce 80 colonnes, alors que la fenêtre est plus large | stty cols 150 rows 40, à refaire à chaque connexion |











