Semaine 8 — Docker : images et conteneurs¶
Durée estimée : 60 min · Prérequis : Introduction à la virtualisation, Intro Proxmox VE
0. Plan de la séance¶
Théorie - Ce document : ce qu'est un conteneur pour le noyau Linux, la place de Docker par rapport aux VM et à LXC, puis les notions d'image, de conteneur, de processus racine, de registre et de moteur. - Les commandes de base de Docker : lancer, observer, arrêter et supprimer des conteneurs, publier un port.
Pratique - Exercice 1 — Un conteneur LXC dans Proxmox - Exercice 2 — Préparer sa VM et lancer un premier conteneur - Exercice 3 — Images et conteneurs - Exercice 4 — Un serveur web en une commande - Exercice 5 — Entrer dans un conteneur - Exercice 6 — Défi autonome
Les exercices 1 à 5 se font en classe. L'exercice 6 se termine en travail personnel s'il le faut. Les volumes et les réseaux de Docker sont traités à la semaine 10.
Objectifs d'apprentissage¶
- Décrire les trois mécanismes du noyau Linux sur lesquels reposent les conteneurs : chroot, namespaces et cgroups.
- Situer Docker par rapport aux VM et aux conteneurs LXC.
- Distinguer le besoin auquel répondent les VM (continuité des opérations) de celui auquel répondent les conteneurs (évolution et déploiement des applications).
- Expliquer comment un conteneur Docker hérite de la résilience de la VM qui l'héberge.
- Distinguer une image d'un conteneur.
- Expliquer le rôle du processus racine (PID 1) dans un conteneur Docker.
- Expliquer le rôle d'un registre et du démon
dockerd, et décrire les étapes exécutées pardocker run.
1. Point de départ¶
À la semaine 7, vous avez déployé Aria Airlines avec des commandes de cette forme :
Aucun logiciel n'a été installé dans la VM, à part Docker lui-même : le serveur web, l'interpréteur et les bibliothèques du site étaient tous contenus dans migrc/aria-web:1.0. Cette note explique ce qu'est cet objet, ce que Docker en fait, et ce que le noyau Linux fait du conteneur qui en sort.
2. Ce qu'est un conteneur pour le noyau¶
Un conteneur n'est pas une machine. Il n'y a ni matériel émulé, ni deuxième noyau. Un conteneur est un processus ordinaire de l'hôte (ou un groupe de processus), auquel le noyau applique trois restrictions :
| Mécanisme | Ce qu'il limite | Exemple |
|---|---|---|
chroot (et son successeur pivot_root) |
Les fichiers que le processus voit | / désigne l'arborescence de l'image, pas celle de l'hôte |
| namespaces | Les ressources du système que le processus voit | Ses propres processus, ses propres interfaces réseau, son propre nom d'hôte |
| cgroups | Ce que le processus consomme | 512 Mo de mémoire, 1 processeur |
Aucun des trois n'est propre à Docker : ce sont des fonctions du noyau Linux, utilisées par tous les outils de conteneurs, LXC compris.
chroot : changer la racine¶
L'appel système chroot existe depuis Unix version 7 (1979). Il change le répertoire racine d'un processus et de ses descendants : pour eux, / désigne désormais un dossier choisi, et tout ce qui se trouve au-dessus devient inaccessible. Dans un conteneur Docker, ce dossier est la pile de couches de l'image, plus la couche inscriptible du conteneur.
chroot seul ne suffit pas à isoler un processus : il ne cache ni les autres processus, ni le réseau, et un processus root peut en sortir. Docker utilise plutôt pivot_root, combiné à un namespace de montage. Le principe reste le même : le processus reçoit une racine qui n'est pas celle de l'hôte.
Les namespaces : limiter ce que le processus voit¶
Un namespace donne à un groupe de processus sa propre copie d'une ressource du système.
| Namespace | Ce qu'il isole | Effet dans un conteneur Docker |
|---|---|---|
mnt |
Les points de montage | Le conteneur a sa propre racine et ses propres montages |
pid |
Les numéros de processus | Le programme principal porte le PID 1 |
net |
Les interfaces, adresses, routes, règles de pare-feu | Une interface eth0 avec une adresse en 172.17.0.x |
uts |
Le nom d'hôte | hostname répond l'identifiant du conteneur |
ipc |
Les files de messages et la mémoire partagée | Pas de communication IPC avec les processus de l'hôte |
user |
Les numéros d'utilisateur (UID) | Non utilisé par défaut : root dans le conteneur est root sur l'hôte |
cgroup |
La vue des cgroups | Le conteneur voit son cgroup comme la racine |
Le processus reste visible depuis l'hôte. Dans la VM Docker :
docker run -d --name web nginx
docker inspect -f '{{.State.Pid}}' web # le PID de nginx vu par la VM, par exemple 4127
ps -o pid,user,cmd -p 4127
sudo lsns -p 4127
ps montre nginx comme n'importe quel processus de la VM. lsns liste les namespaces propres au conteneur. L'inverse est faux : depuis le conteneur, ps n'affiche aucun processus de la VM.
Les cgroups : limiter ce que le processus consomme¶
Les namespaces ne limitent pas les ressources. Sans autre mécanisme, un conteneur pourrait occuper toute la mémoire et tout le processeur de la VM. Les cgroups (control groups) rangent les processus dans des groupes, et appliquent à chaque groupe des limites de processeur, de mémoire, d'entrées-sorties et de nombre de processus. Ils s'exposent comme des fichiers, sous /sys/fs/cgroup.
docker run -d --name petit --memory 256m nginx
cat /sys/fs/cgroup/system.slice/docker-$(docker inspect -f '{{.Id}}' petit).scope/memory.max
L'option --memory 256m n'a fait qu'écrire 268435456 octets dans ce fichier. Si les processus du conteneur dépassent la limite, le noyau en termine un (OOM kill), et le reste de la VM n'est pas touché. Les champs Memory et Cores de Proxmox font la même chose pour un conteneur LXC.
Une conséquence : un seul noyau¶
Comme le conteneur n'est qu'un processus de l'hôte, il utilise le noyau de l'hôte :
- il n'y a pas de noyau à démarrer, d'où un démarrage en moins d'une seconde ;
- un conteneur Linux ne peut exécuter que des programmes Linux ;
- l'isolation dépend du noyau de l'hôte : une faille du noyau touche tous les conteneurs à la fois. Une VM, avec son propre noyau, isole plus fortement.
3. VM, LXC et Docker¶
Vous avez déjà utilisé des conteneurs LXC aux semaines 2 et 3. LXC et Docker utilisent les mêmes mécanismes du noyau. Ce qui les distingue, c'est ce qu'on met dedans et la façon dont on les gère.
- LXC produit un conteneur système : une distribution Linux complète, sans noyau, avec
systemdau PID 1 et ses services. Il s'administre comme un petit serveur. - Docker produit un conteneur applicatif : une seule application et ses dépendances, qui est elle-même le PID 1. On ne le met pas à jour : on le remplace.
| VM (KVM) | Conteneur système (LXC) | Conteneur applicatif (Docker) | |
|---|---|---|---|
| Contenu | Un système complet, avec son noyau | Une distribution Linux, sans noyau | Une application et ses dépendances |
| Noyau | Le sien | Celui de l'hôte | Celui de l'hôte |
| PID 1 | systemd |
systemd |
Le programme de l'application |
| Démarrage | 30 s à quelques minutes | Quelques secondes | Moins d'une seconde |
| Point de départ | ISO ou template | Template de distribution | Image tirée d'un registre |
| Gestion | Administrée comme un serveur | Administré comme un serveur | Remplacé, jamais mis à jour sur place |
Où s'exécute Docker¶
Docker n'est pas un hyperviseur : il s'installe sur un système Linux, presque toujours virtualisé. Sur Proxmox, on le rencontre dans une VM comme dans un conteneur LXC ; les deux architectures sont répandues.
- VM + Docker : les conteneurs utilisent le noyau de la VM, isolé de celui du nœud. La VM migre à chaud dans le cluster. C'est l'architecture recommandée par Proxmox, et celle de ce cours.
- LXC + Docker : plus léger, mais les conteneurs Docker utilisent le noyau du nœud, et le conteneur LXC doit autoriser les namespaces imbriqués (option Nesting). Il ne migre qu'avec redémarrage.
Ce que vous apprenez sur Docker s'applique tel quel dans l'une ou l'autre.
4. Le besoin : faire évoluer les applications¶
Ce que les VM ont réglé : la continuité des opérations¶
Les sept premières semaines ont construit une infrastructure : des VM sur un hyperviseur, des réseaux et des VLAN, des sauvegardes, des templates, un cluster avec un stockage partagé et la haute disponibilité. Le besoin auquel répond cette infrastructure est la continuité : un serveur physique tombe en panne, et les services poursuivent leurs opérations sur un autre nœud ; une VM est corrompue, et on la restaure depuis une sauvegarde.
Cette infrastructure change peu. Un cluster, un plan d'adressage ou une politique de sauvegarde se conçoivent une fois, puis s'entretiennent pendant des années.
Ce que les conteneurs règlent : le changement continu¶
Les applications qui s'exécutent sur cette infrastructure changent, elles, en permanence. Les processus d'affaires évoluent : un nouveau tarif chez Aria Airlines, un nouveau mode de paiement, une règle de réservation modifiée, un correctif de sécurité. Chaque changement donne une nouvelle version de l'application, à déployer en test, puis en production, parfois plusieurs fois par semaine, et à retirer rapidement si elle pose problème.
Avec des VM seules, chaque déploiement consiste à modifier un serveur en place : installer des paquets, changer des fichiers de configuration, redémarrer des services. L'opération est lente, difficile à reproduire à l'identique d'un serveur à l'autre, et difficile à annuler.
Les conteneurs, Docker en particulier, répondent à ce second besoin : faciliter l'évolution et le déploiement des applications. Une nouvelle version est une nouvelle image ; la déployer, c'est remplacer un conteneur par un autre ; revenir en arrière, c'est relancer l'image précédente.
| VM et cluster (semaines 1 à 7) | Conteneurs Docker (semaines 8 à 10) | |
|---|---|---|
| Besoin | Résister aux pannes, poursuivre les opérations | Faire évoluer les applications et les déployer rapidement |
| Ce qui est géré | L'infrastructure : serveurs, réseau, stockage | Les applications et leurs dépendances |
| Rythme de changement | Lent : des mois, des années | Rapide : des jours, parfois des heures |
| Réponse à un problème | Migrer, basculer, restaurer | Remplacer le conteneur, revenir à l'image précédente |
Le conteneur Docker hérite de la résilience de l'infrastructure¶
Les deux besoins ne s'opposent pas, ils s'empilent. Un conteneur Docker s'exécute dans une VM (ou un conteneur LXC), qui s'exécute sur le cluster. Il n'a pas à être résistant aux pannes lui-même : il hérite de la résilience de l'infrastructure de virtualisation qui l'héberge.
flowchart TB
A["Cluster Proxmox : quorum, stockage partagé, ha-manager"] --> B["VM ou conteneur LXC, ressource HA"]
B --> C["Service dockerd, activé au démarrage"]
C --> D["Conteneurs Docker, --restart unless-stopped"]
C'est ce que vous avez vu avec Aria Airlines à la semaine 7. Quand un nœud tombe :
ha-managerredémarre la VM sur un autre nœud ; son disque est sur le stockage partagé, rien n'est perdu ;- la VM démarre, et
systemdlance le démondockerd; dockerdrelance les conteneurs créés avec--restart unless-stopped, à partir des images déjà présentes sur le disque de la VM.
Chaque couche a son rôle. La virtualisation garantit que la machine est toujours quelque part en marche, et que ses disques sont sauvegardés. Docker garantit que l'application qu'elle héberge peut être remplacée par une nouvelle version, ou revenir à la précédente, en une commande. Un maillon manquant casse la chaîne : une VM sans HA reste éteinte avec son nœud, et un conteneur sans --restart reste arrêté dans une VM pourtant redémarrée.
Docker seul ne déplace pas les conteneurs d'une machine à l'autre : chaque démon ne gère que les conteneurs de son hôte. Répartir des conteneurs sur plusieurs machines et les relancer ailleurs en cas de panne, sans passer par la HA des VM, est le rôle des orchestrateurs (semaine 10).
Le problème technique : les dépendances¶
Une application dépend de son environnement : une version précise de son interpréteur (Python 3.12 plutôt que 3.9), de ses bibliothèques, de fichiers de configuration à des emplacements attendus, de certains réglages du système. Installée sur un serveur dont l'environnement diffère de celui du développeur, elle peut échouer, et la cause est souvent longue à trouver. C'est ce qui rend un déploiement lent et risqué.
Un conteneur LXC ne règle pas ce problème : c'est un serveur Debian, sur lequel il faut installer et configurer l'application comme sur n'importe quel serveur. Docker le règle en livrant l'application avec son environnement, dans un format unique, l'image, qui s'exécute de la même façon sur le poste du développeur, sur le serveur de test et en production.
5. L'image¶
Une image est un modèle en lecture seule qui contient :
- les fichiers nécessaires à l'application : le programme, ses bibliothèques, une arborescence Linux minimale ;
- des métadonnées : la commande à lancer au démarrage, les ports sur lesquels l'application écoute, des variables d'environnement par défaut.
Une image ne s'exécute pas et n'est jamais modifiée. Son rôle est comparable à celui du template 9000 de la semaine 4 : un modèle figé dont on tire des instances.
Une image est désignée par un nom et une étiquette (tag) :
Sans étiquette, Docker utilise latest. nginx et nginx:latest désignent donc la même image. latest n'est qu'une étiquette par défaut, déplacée par l'éditeur à chaque nouvelle version : elle ne garantit pas la stabilité.
Les couches¶
Une image est formée de couches (layers) superposées. Chaque couche ajoute ou modifie des fichiers par rapport à la précédente : une couche de base Debian, une couche avec les bibliothèques, une couche avec l'application. Les couches sont partagées : dix images construites sur la même base Debian ne stockent cette base qu'une fois sur le disque. C'est pourquoi un téléchargement affiche une ligne Pull complete par couche. Vous fabriquerez vos propres couches à la semaine 9.
6. Le conteneur¶
Un conteneur est une instance d'image en cours d'exécution. Pour le créer, Docker :
- superpose aux couches de l'image une couche inscriptible, propre à ce conteneur, qui reçoit toutes les modifications de fichiers ;
- lance la commande de démarrage prévue par l'image, dans un environnement isolé.
Plusieurs conteneurs peuvent être créés à partir de la même image. Ils partagent les couches en lecture seule, mais chacun a sa propre couche inscriptible : ce qu'un conteneur modifie n'affecte ni l'image, ni les autres conteneurs. La couche inscriptible est supprimée avec le conteneur.
Ce que Docker fait au démarrage¶
Docker utilise les mécanismes de la section 2. La pile de couches devient la racine du processus, des namespaces mnt, pid, net, uts et ipc lui sont créés, et il est placé dans un cgroup propre (/sys/fs/cgroup/system.slice/docker-<identifiant>.scope sur une VM Debian). Les options --memory et --cpus de docker run écrivent dans ce cgroup, comme le font les champs Memory et Cores de Proxmox pour un conteneur LXC.
Le processus racine (PID 1)¶
Dans un conteneur Docker, la commande de démarrage de l'image devient le processus racine du namespace pid : elle porte le PID 1, et tous les autres processus du conteneur en descendent.
Dans une VM ou un conteneur LXC, le PID 1 est systemd, qui démarre et surveille des services. Dans un conteneur Docker, aucun systemd ne joue ce rôle : l'application est à la fois le programme utile et le processus racine. Deux conséquences.
1. Le conteneur vit aussi longtemps que son PID 1. Quand le processus racine se termine, le noyau termine tous les autres processus du namespace, et Docker marque le conteneur comme arrêté.
- Le programme de l'image
hello-worldaffiche un texte, puis se termine : le conteneur s'arrête aussitôt. - Le programme de l'image
nginxest un serveur qui attend des connexions : le conteneur s'exécute jusqu'à ce qu'on l'arrête. - C'est pourquoi l'image nginx lance
nginx -g 'daemon off;': en mode démon, nginx se détacherait en arrière-plan, son processus initial se terminerait, et le conteneur s'arrêterait avec lui.
Un conteneur arrêté n'est pas supprimé : il conserve sa couche inscriptible et peut être redémarré. La note sur les commandes détaille ce cycle de vie.
2. Le PID 1 reçoit les signaux d'arrêt. docker stop envoie le signal SIGTERM au PID 1, attend 10 secondes, puis envoie SIGKILL. Le noyau traite le PID 1 d'un namespace à part : un signal pour lequel le programme n'a pas prévu de traitement est ignoré, au lieu de le terminer. Un programme qui ne gère pas SIGTERM met donc 10 secondes à s'arrêter, puis est tué sans avoir pu fermer proprement ses fichiers et ses connexions. Même problème si le PID 1 est un shell (/bin/sh -c "...") qui lance l'application : le shell reçoit le signal et ne le transmet pas. Vous verrez à la semaine 9 comment écrire la commande de démarrage d'une image pour l'éviter.
7. Le registre¶
Un registre (registry) est un serveur qui stocke et distribue des images. Le registre par défaut est Docker Hub. Le nom complet d'une image indique où la trouver :
docker.io/library/nginx:latest
│ │ │ └── l'étiquette
│ │ └── le nom
│ └── le compte qui publie l'image (library = images officielles)
└── le registre
nginx est l'abréviation de ce nom complet. migrc/aria-web:1.0 désigne l'image aria-web publiée par le compte migrc sur Docker Hub.
Les images marquées Docker Official Image sont maintenues par Docker et par les éditeurs des logiciels. Les autres sont publiées par des comptes quelconques.
Exécuter une image, c'est exécuter le code de son auteur
Une image peut contenir n'importe quel programme. Sur un serveur, on n'utilise que des images officielles, ou des images dont l'auteur est connu et digne de confiance.
D'autres registres existent : GitHub Container Registry (ghcr.io), les registres des fournisseurs infonuagiques, ou un registre privé hébergé par l'entreprise.
8. Le moteur Docker¶
Docker se compose de deux parties :
- le client
docker, la commande que vous tapez ; - le démon
dockerd(le Docker Engine), un service qui s'exécute en permanence sur l'hôte. Il télécharge les images, crée, démarre et arrête les conteneurs.
Le client ne fait que transmettre des requêtes au démon, par le socket /var/run/docker.sock, et en afficher les réponses. C'est pourquoi docker version affiche deux sections : Client, et Server, la réponse du démon. Si la section Server est absente, le démon ne s'exécute pas, ou l'utilisateur n'a pas le droit d'accéder au socket.
Le droit d'accès au socket est accordé aux membres du groupe docker. Comme le démon s'exécute en root et peut monter n'importe quel dossier de l'hôte dans un conteneur, être membre du groupe docker équivaut à avoir les droits root sur l'hôte.
9. Les étapes de docker run¶
sequenceDiagram
participant C as Client docker
participant D as Démon dockerd
participant H as Docker Hub
C->>D: run hello-world
D->>D: Recherche de hello-world:latest sur le disque
D->>H: Image absente : téléchargement
H-->>D: Couches et métadonnées
D->>D: Création du conteneur (couche inscriptible)
D->>D: Démarrage de la commande prévue par l'image
D-->>C: Sortie du programme
- Le client transmet la requête au démon.
- Le démon cherche l'image
hello-world:latestdans son stockage local. - Si elle est absente, il la télécharge depuis le registre (
Unable to find image 'hello-world:latest' locally, puis une ligne par couche). - Il crée le conteneur : couche inscriptible, namespaces, cgroups.
- Il lance la commande de démarrage de l'image.
- Il transmet au client ce que le programme affiche.
- Le programme se termine, et le conteneur passe à l'état arrêté.
Au lancement suivant, l'étape 3 est sautée : l'image est déjà dans le stockage local.
Pièges fréquents¶
- Confondre image et conteneur. Supprimer un conteneur ne supprime pas son image. Une image ne peut pas être supprimée tant qu'un conteneur, même arrêté, en dépend.
- Traiter un conteneur comme une petite VM. Il n'a ni noyau, ni système d'initialisation, ni services. Les images contiennent souvent le strict minimum, sans éditeur de texte ni outils de diagnostic.
- Croire que LXC et Docker isolent différemment. Ils utilisent les mêmes namespaces et les mêmes cgroups. La différence est dans le contenu (un système ou une application) et dans la gestion (entretenu ou remplacé).
- Lancer un programme qui passe en arrière-plan comme PID 1. Le processus racine se termine dès que le programme se détache, et le conteneur s'arrête avec lui. Le programme doit rester au premier plan.
- Se fier à
latest. L'étiquette change à chaque nouvelle version publiée. En production, on indique toujours la version :nginx:1.27.
Vérification des acquis¶
Question 1¶
Vous lancez trois fois docker run nginx. Combien d'images et combien de conteneurs se trouvent sur le disque ?
- a) Trois images et trois conteneurs.
- b) Une image et trois conteneurs.
- c) Une image et un conteneur, réutilisé trois fois.
Voir la réponse
**b) Une image et trois conteneurs.** L'image est téléchargée au premier `docker run`, puis réutilisée. Chaque `docker run` crée un **nouveau** conteneur, avec sa propre couche inscriptible, au-dessus des mêmes couches en lecture seule. Le choix c) est faux : `docker run` ne réutilise jamais un conteneur existant. Pour redémarrer un conteneur déjà créé, la commande est `docker start`.Question 2¶
docker version n'affiche que la section Client, suivie d'un message d'erreur. Que faut-il en conclure ?
- a) Docker n'est pas installé.
- b) Le démon
dockerdne s'exécute pas, ou l'utilisateur n'a pas accès à son socket. - c) Docker Hub est inaccessible.
Voir la réponse
**b) Le démon ne s'exécute pas, ou l'utilisateur n'a pas accès à son socket.** La section `Client` prouve que la commande `docker` est installée. La section `Server` est la réponse du démon. Si elle manque, soit le service est arrêté (`sudo systemctl status docker`), soit l'utilisateur n'est pas membre du groupe `docker` (la commande fonctionne alors avec `sudo`). Le choix c) est faux : `docker version` ne contacte pas le registre.Question 3¶
Un conteneur Alpine affiche uname -r : la version du noyau est identique à celle de la VM qui l'héberge. Pourquoi ?
- a) Par coïncidence : Alpine utilise la même version de noyau que Debian 13.
- b) Un conteneur est un processus de l'hôte. Il n'a pas de noyau propre et utilise celui de la VM.
- c) Docker copie le noyau de la VM dans l'image au moment du téléchargement.
Voir la réponse
**b) Un conteneur utilise le noyau de l'hôte.** Les namespaces isolent ce que le processus voit (fichiers, processus, réseau), mais le noyau qui l'exécute est celui de l'hôte. Une image ne contient aucun noyau. Le choix c) est faux : une image ne contient pas de noyau, et Docker n'en ajoute pas.Question 4¶
Vous lancez docker run hello-world. Le texte s'affiche, puis l'invite revient. Dans quel état est le conteneur ?
- a) En cours d'exécution, en arrière-plan.
- b) Arrêté : son programme principal s'est terminé.
- c) Supprimé automatiquement par Docker.
Voir la réponse
**b) Arrêté.** Un conteneur s'exécute aussi longtemps que son programme principal. Celui de `hello-world` se termine après avoir affiché son texte. Le choix c) est faux : un conteneur arrêté reste sur le disque, et `docker ps -a` l'affiche. Seule l'option `--rm` provoque sa suppression automatique.Question 5¶
Vous lancez un conteneur avec --memory 256m. Quel mécanisme du noyau empêche ses processus d'en utiliser davantage ?
- a) Le namespace
mnt. - b) Les cgroups.
- c) chroot.
Voir la réponse
**b) Les cgroups.** Docker écrit la limite dans le fichier `memory.max` du cgroup du conteneur. Les namespaces et chroot limitent ce que le processus **voit**, pas ce qu'il **consomme**.Question 6¶
Un processus root réussit à sortir d'un conteneur Docker lancé avec les réglages par défaut. Avec quels droits se retrouve-t-il sur l'hôte ?
- a) Ceux d'un utilisateur sans privilège, grâce au namespace
user. - b) Ceux de
root: Docker n'active pas le namespaceuserpar défaut. - c) Aucun : un processus ne peut pas sortir d'un namespace.
Voir la réponse
**b) Ceux de `root`.** Sans namespace `user`, l'UID 0 du conteneur est l'UID 0 de l'hôte. C'est une raison d'exécuter Docker dans une VM et de n'utiliser que des images de confiance. Le choix c) est faux : des failles du noyau ou une mauvaise configuration (`--privileged`, montage du socket Docker) permettent d'en sortir.Question 7¶
Quelle affirmation sur LXC et Docker est exacte ?
- a) LXC isole les conteneurs avec les namespaces ; Docker utilise un hyperviseur léger.
- b) Les deux utilisent les namespaces et les cgroups du noyau de l'hôte ; un conteneur LXC contient un système complet géré par
systemd, un conteneur Docker une seule application qui est son PID 1. - c) Docker est plus sûr que LXC parce que
rooty est toujours remplacé par un utilisateur ordinaire.
Voir la réponse
**b)** Le choix a) est faux : Docker n'utilise pas d'hyperviseur. Le choix c) est l'inverse de la réalité : par défaut, Docker n'active pas le namespace `user`, alors que Proxmox l'active pour les conteneurs LXC non privilégiés.Question 8¶
Un conteneur exécute un programme qui ne gère pas le signal SIGTERM. docker stop prend 10 secondes. Pourquoi ?
- a) Docker attend toujours 10 secondes avant d'arrêter un conteneur.
- b) Le programme est le PID 1 du conteneur : le noyau ignore les signaux qu'il ne traite pas. Après 10 secondes, Docker envoie
SIGKILL. - c) Le démon
dockerddoit d'abord sauvegarder la couche inscriptible.
Voir la réponse
**b)** Pour un processus ordinaire, `SIGTERM` sans traitement prévu termine le processus. Pour le PID 1 d'un namespace, le signal est ignoré. Docker attend le délai de grâce (10 secondes par défaut, option `-t` de `docker stop`), puis envoie `SIGKILL`, qui ne peut pas être ignoré.Pour aller plus loin¶
- What is a container? et What is an image?, dans la documentation de Docker.
- Docker overview, l'architecture client, démon et registre.
- namespaces(7) et cgroups(7), les pages de manuel des namespaces et des cgroups Linux.