Leçon 1 sur 15 · Fondamentaux
Pourquoi les conteneurs ?
Objectif
Comprendre le problème que Docker résout, ce qu'est réellement un conteneur, et maîtriser le vocabulaire de base : image, conteneur, registre, Docker Engine et OCI. Cette leçon ne demande aucune installation.
L'essentiel
- Un conteneur est un processus Linux isolé : il a sa propre vue des fichiers, du réseau et des autres processus, mais il utilise le noyau de la machine hôte.
- Une image est un modèle figé et en lecture seule (le programme, ses bibliothèques, sa configuration). On lance autant de conteneurs qu'on veut à partir d'une même image.
- Un registre stocke et distribue les images (Docker Hub, GitHub Container Registry, un registre privé).
- Docker Engine est le moteur : un démon (
dockerd) qui construit les images et fait tourner les conteneurs, piloté par la commandedocker. - La norme OCI (Open Container Initiative) décrit le format des images et la façon de les exécuter : une image construite avec Docker tourne aussi avec Podman, containerd ou Kubernetes.
Le problème : « ça marche sur ma machine »
Imaginez une boutique en ligne à Casablanca. Le développeur a écrit son site avec Node.js 22 sur son portable Ubuntu. Le serveur de production, lui, tourne sous Debian avec Node.js 18. Le jour de la mise en ligne, une bibliothèque refuse de démarrer : la version de Node ne correspond pas, un paquet système manque, une variable d'environnement a été oubliée.
Ce problème a trois causes classiques :
- Les dépendances diffèrent d'une machine à l'autre (versions du langage, bibliothèques système).
- La configuration n'est pas écrite noir sur blanc : elle est dans la tête de quelqu'un.
- Plusieurs applications sur le même serveur se gênent (l'une veut PHP 8.1, l'autre PHP 8.3).
Un conteneur règle ces trois points : l'application voyage avec tout ce dont elle a besoin, la recette est écrite dans un fichier (le Dockerfile), et chaque application a son propre espace, isolé des autres.
Machine virtuelle contre conteneur
Une machine virtuelle (VM) simule un ordinateur complet : processeur virtuel, disque virtuel, et surtout son propre système d'exploitation avec son propre noyau. Un hyperviseur (VMware, KVM, Hyper-V, VirtualBox) partage le matériel entre les VM.
Un conteneur ne simule rien. C'est un processus normal du système hôte, que le noyau Linux enferme grâce à deux mécanismes :
- les espaces de noms (namespaces) : le processus a sa propre liste de processus (
pid), son propre réseau (net), ses propres points de montage (mnt), son propre nom d'hôte (uts), ses propres utilisateurs (user)… ; - les groupes de contrôle (cgroups) : le noyau limite la mémoire, le processeur et les entrées-sorties que ce processus peut consommer.
| Critère | Machine virtuelle | Conteneur |
|---|---|---|
| Ce qui est isolé | une machine entière | un processus (et ses enfants) |
| Noyau | un noyau par VM | le noyau de l'hôte, partagé |
| Taille typique | plusieurs Go | quelques Mo à quelques centaines de Mo |
| Démarrage | dizaines de secondes | une fraction de seconde |
| Systèmes possibles | n'importe lequel (Windows dans Linux…) | des programmes Linux sur un noyau Linux |
| Densité | quelques VM par serveur | des dizaines ou centaines de conteneurs |
| Isolation | très forte (matériel virtuel) | bonne, mais dépend du noyau partagé |
Les deux ne s'opposent pas. Dans la vraie vie, on loue très souvent une VM (un VPS chez un hébergeur) et on y fait tourner des conteneurs.
Sur Windows et macOS, il n'y a pas de noyau Linux. Docker Desktop démarre donc une petite VM Linux en arrière-plan, et vos conteneurs tournent dedans.
Vous pouvez voir les espaces de noms de n'importe quel processus Linux, même sans Docker :
ls /proc/self/ns # espaces de noms du shell courant
# cgroup ipc mnt net pid pid_for_children time time_for_children user uts
cat /proc/self/cgroup # le groupe de contrôle auquel il appartient
uname -r # le noyau : le MÊME pour l'hôte et tous ses conteneurs
Image et conteneur
La meilleure image mentale est celle de la classe et de l'objet en programmation, ou du moule et du gâteau :
- l'image est le moule : immuable, versionnée, partageable ;
- le conteneur est un gâteau sorti du moule : une instance vivante, qui démarre, travaille, s'arrête et peut être supprimée.
Une image est faite de couches empilées. Chaque couche ajoute, modifie ou supprime des fichiers par rapport à la précédente. Quand un conteneur démarre, Docker pose au-dessus une couche fine en écriture, propre à ce conteneur. Conséquence capitale :
Tout ce qu'un conteneur écrit dans sa couche disparaît quand on le supprime. Les données à garder (base de données, fichiers envoyés par les clients) vont dans un volume. Vous le verrez en détail au niveau 2.
Deux principes guident l'usage des images :
- Une image ne se modifie pas. Pour changer quelque chose, on construit une nouvelle image (nouvelle version), on supprime l'ancien conteneur et on en lance un neuf.
- Un conteneur, un rôle. Le site web dans un conteneur, la base PostgreSQL dans un autre, le cache Redis dans un troisième. On les assemble ensuite avec Docker Compose.
Les registres et le nom d'une image
Un registre est un serveur qui stocke des images, un peu comme un dépôt de paquets apt ou dnf. Docker Hub est le registre public par défaut. Il en existe beaucoup d'autres : GitHub Container Registry (ghcr.io), les registres des clouds (Amazon ECR, Azure ACR, Google), GitLab, Harbor… et vous pouvez héberger le vôtre.
Le nom complet d'une image a trois parties :
ghcr.io / startup-rabat/api : 2.3.1
└──┬──┘ └──────┬────────┘ └─┬─┘
registre dépôt étiquette (tag)
Quand une partie manque, Docker la complète :
| Vous écrivez | Docker comprend |
|---|---|
nginx |
docker.io/library/nginx:latest |
nginx:1.27-alpine |
docker.io/library/nginx:1.27-alpine |
ecole/inscriptions:2.0 |
docker.io/ecole/inscriptions:2.0 |
ghcr.io/startup-rabat/api:2.3.1 |
(nom déjà complet) |
- Sans registre :
docker.io(Docker Hub). - Sans espace de nom :
library/, le dossier des images officielles (nginx, postgres, redis, node, debian…). - Sans étiquette :
latest. Ce mot ne veut pas dire « la plus récente » : c'est juste l'étiquette par défaut. En production, écrivez toujours une étiquette précise.
Docker Engine : qui fait quoi ?
Quand vous tapez docker run nginx, plusieurs programmes travaillent ensemble :
vous ──> docker (client, la commande)
│ API REST sur /var/run/docker.sock
▼
dockerd (le démon Docker Engine)
│ images, réseaux, volumes, construction (BuildKit)
▼
containerd ──> runc ──> le processus isolé (votre conteneur)
dockerest le client : il n'exécute rien lui-même, il envoie des ordres à l'API du démon. Il peut même parler à un démon distant.dockerdest le démon : il gère les images, les réseaux, les volumes et la construction.containerdgère le cycle de vie des conteneurs, etrunccrée concrètement le processus isolé (espaces de noms, cgroups).
Le démon tourne en root. Celui qui peut parler à son socket peut donc tout faire sur la machine : vous verrez au niveau 4 ce que cela implique pour la sécurité.
OCI : une norme ouverte
En 2015, Docker et d'autres acteurs ont créé l'Open Container Initiative. Elle publie des spécifications ouvertes :
- image-spec : le format d'une image (couches, manifeste, configuration) ;
- runtime-spec : comment exécuter un conteneur à partir d'une image décompressée ;
- distribution-spec : comment un registre reçoit et distribue des images.
Grâce à elle, vous n'êtes pas prisonnier d'un outil. Une image construite par Docker sur le portable d'un développeur peut être lancée par Podman sur un serveur Red Hat, par containerd dans Kubernetes, ou stockée dans n'importe quel registre compatible.
Pourquoi Docker est devenu incontournable
| Besoin | Ce que Docker apporte |
|---|---|
| Installer une application en 5 minutes | docker run d'une image officielle, rien à compiler |
| Reproduire un bug de production | lancer exactement la même image en local |
| Déployer souvent et sans risque | nouvelle image = nouvelle version ; retour arrière = relancer l'ancienne |
| Faire cohabiter des versions | PHP 8.1 et PHP 8.3 dans deux conteneurs, sur le même serveur |
| Intégration continue (CI) | chaque test démarre dans un environnement propre et identique |
| Préparer Kubernetes | Kubernetes orchestre… des conteneurs construits comme ici |
Exemple concret : l'application d'inscription d'une école à Fès se compose d'un site web, d'une API et d'une base PostgreSQL. Avec Docker, un nouveau développeur clone le projet, tape une seule commande (docker compose up), et dispose en une minute de la même pile que la production.
Un peu d'histoire
Les conteneurs ne sont pas nés avec Docker. Ils sont le fruit de vingt ans d'ajouts au monde Unix et au noyau Linux :
| Année | Étape |
|---|---|
| 1979 | chroot sous Unix : un processus voit un autre dossier comme racine / |
| 2000 | les jails de FreeBSD : isolation des processus et du réseau |
| 2004 | les zones de Solaris |
| 2002-2013 | les espaces de noms arrivent un à un dans le noyau Linux ; les cgroups (proposés par Google) y entrent en 2008 |
| 2008 | LXC : premiers conteneurs Linux complets, mais difficiles à utiliser |
| 2013 | Docker : une commande simple, des images en couches, un registre public |
| 2015 | création de l'OCI ; Kubernetes 1.0 |
| 2017-2019 | Docker confie containerd à la fondation CNCF ; arrivée de Podman (Red Hat) |
| aujourd'hui | Docker Engine, Podman, containerd et Kubernetes partagent le même format d'image |
La vraie révolution de Docker n'a pas été technique : elle a été d'emballer ces mécanismes dans un outil simple, avec un format d'image portable et un registre où tout le monde partage ses images.
Docker, Podman, containerd : qui utiliser ?
Vous croiserez plusieurs outils. Ils parlent tous le même langage d'images :
| Outil | Ce que c'est | Où on le rencontre |
|---|---|---|
| Docker Engine | démon + client docker, Compose, BuildKit |
serveurs Debian/Ubuntu, VPS, postes de développeurs |
| Docker Desktop | application graphique avec une VM Linux intégrée | postes Windows et macOS |
| Podman | même commandes que Docker, sans démon, rootless natif | RHEL, Rocky, AlmaLinux, Fedora |
| containerd | moteur bas niveau, sans interface conviviale | sous Docker, et dans la plupart des clusters Kubernetes |
Ce cours utilise Docker Engine et Docker Compose, les plus répandus chez les hébergeurs et dans les offres d'emploi. Tout ce que vous apprenez sur les images et les Dockerfile vaut aussi pour Podman.
Le vocabulaire en un coup d'œil
| Mot | Définition courte |
|---|---|
| Image | modèle en lecture seule, fait de couches, identifié par un nom et une étiquette |
| Conteneur | instance en marche d'une image, avec une couche en écriture jetable |
| Couche (layer) | ensemble de modifications de fichiers, partagé entre images |
| Registre | serveur qui stocke et distribue des images |
| Dépôt (repository) | ensemble des versions d'une même image dans un registre |
| Étiquette (tag) | nom d'une version : 1.27, 1.27-alpine, latest |
| Dockerfile | recette texte qui décrit comment construire une image |
| Volume | espace de stockage géré par Docker, qui survit aux conteneurs |
| Compose | outil qui décrit et lance plusieurs conteneurs avec un fichier YAML |
Pièges fréquents
- Croire qu'un conteneur est une petite VM : il n'a pas son propre noyau. Un module noyau ou un réglage
sysctlglobal se fait sur l'hôte. - Stocker des données importantes dans le conteneur : elles disparaissent à la suppression. Utilisez un volume.
- Utiliser
latesten production : vous ne savez plus quelle version tourne, et un simple redémarrage peut changer de version. - Prendre n'importe quelle image sur Docker Hub : préférez les images officielles ou d'éditeurs vérifiés, comme vous choisiriez un dépôt de paquets de confiance.
Lab
Docker n'est pas installé dans le lab : ce n'est pas nécessaire ici. Vous allez :
- lister les espaces de noms d'un processus, la brique de base d'un conteneur ;
- relever la version du noyau, celui que partageraient tous les conteneurs de la machine ;
- écrire le nom complet d'une image officielle ;
- décomposer le nom d'une image hébergée sur GitHub Container Registry.
Quiz
- Quelle est la différence fondamentale entre une machine virtuelle et un conteneur ?
- Quels sont les deux mécanismes du noyau Linux qui isolent et limitent un conteneur ?
- Que devient un fichier écrit par un conteneur dans sa propre couche quand on supprime ce conteneur ?
- Quel nom complet Docker utilise-t-il pour
redis? - À quoi sert la norme OCI pour une entreprise ?
Réponses
- La VM embarque son propre système et son propre noyau sur du matériel virtuel ; le conteneur est un processus de l'hôte, isolé, qui partage le noyau de l'hôte.
- Les espaces de noms (namespaces) pour l'isolation, et les groupes de contrôle (cgroups) pour limiter les ressources.
- Il est perdu. Les données à conserver doivent aller dans un volume ou un dossier monté.
docker.io/library/redis:latest.- Elle garantit qu'une image n'est pas liée à un outil : construite avec Docker, elle peut tourner avec Podman, containerd ou Kubernetes, et être stockée dans tout registre compatible.
Sources de référence : documentation officielle Docker (docs.docker.com, licence Apache 2.0). Texte original MasterLinux.