01 - Containers vs VMs
Ce que tu vas apprendre
- Ce qu'est un conteneur au niveau du noyau Linux
- Les namespaces et les cgroups, les deux piliers de l'isolation
- La différence réelle entre un conteneur et une machine virtuelle
- Quand choisir l'un plutot que l'autre
Prerequisites
- Avoir lu l'article 00 - Introduction ou connaître les bases de Docker
- Notions basiques de Linux (processus, système de fichiers)
Le mensonge de la "VM legere"
Pendant des annees, j'ai explique Docker comme "une VM legere". C'est faux. Ou du moins, c'est trompeur. Un conteneur n'est pas une petite machine virtuelle. C'est un processus Linux avec des barrieres autour.
La nuance est importante. Une VM emule un ordinateur complet : son propre noyau, ses propres drivers, sa propre mémoire physique. Un conteneur partage le noyau de la machine hote. Il n'y a pas d'emulation. C'est juste un processus qui croit etre seul au monde.
Comment une VM fonctionne
Une machine virtuelle repose sur un hyperviseur. Ce logiciel (VirtualBox, VMware, KVM, Hyper-V) simule du materiel pour le système invite. Chaque VM a :
- Son propre noyau
- Ses propres drivers
- Sa propre pile réseau
- Ses propres librairies système
Quand tu lances une VM Ubuntu sur un hote Windows, tu as un Linux complet qui tourne a l'intérieur. Le noyau de la VM ne sait pas qu'il tourne sur du materiel virtuel (en général). L'isolation est totale.
Le coût : chaque VM consomme de la RAM pour son noyau, du CPU pour son hyperviseur, et du disque pour son image système. Une VM Ubuntu minimale, c'est 500 Mo de RAM et 2 Go de disque. Avant meme d'installer ton application.
Comment un conteneur fonctionne
Un conteneur utilise deux mecanismes du noyau Linux : les namespaces et les cgroups. Pas d'hyperviseur, pas de noyau supplementaire.
Namespaces : l'illusion de l'isolement
Les namespaces Linux permettent d'isoler la vue qu'un processus a du système. Il en existe plusieurs types :
| Namespace | Ce qu'il isole |
|---|---|
| PID | Les identifiants de processus |
| NET | La pile réseau (interfaces, routes, ports) |
| MNT | Les points de montage (système de fichiers) |
| UTS | Le hostname |
| IPC | La communication inter-processus |
| USER | Les identifiants utilisateurs |
Quand Docker lance un conteneur, il créé un ensemble de namespaces. Le processus a l'intérieur voit son propre PID 1, son propre hostname, son propre système de fichiers. Mais pour le noyau, c'est juste un processus parmi d'autres.
Tu peux le vérifier :
bash# Lance un conteneur en arriere-plan
docker run -d --name test nginx
# Regarde les processus depuis l'hote
ps aux | grep nginx
Tu verras les processus nginx avec des PIDs normaux, cote hote. A l'intérieur du conteneur, nginx pense etre le PID 1.
Cgroups : les limites de ressources
Les cgroups (control groups) permettent de limiter et mesurer les ressources qu'un processus peut utiliser : CPU, mémoire, I/O disque, réseau.
bash# Limite un conteneur a 256 Mo de RAM et 0.5 CPU
docker run -d --memory=256m --cpus=0.5 nginx
Sans cgroups, un conteneur pourrait consommer toute la mémoire de l'hote et faire tomber les autres services. Les cgroups empechent ca.
Le schema mental
VM :
┌─────────────────────────────┐
│ Hyperviseur (KVM, VMware) │
│ ┌──────────┐ ┌──────────┐ │
│ │ Noyau │ │ Noyau │ │
│ │ Libs │ │ Libs │ │
│ │ App A │ │ App B │ │
│ └──────────┘ └──────────┘ │
│ Hote OS + Hardware │
└─────────────────────────────┘
Conteneur :
┌──────────────────────────────┐
│ ┌──────────┐ ┌──────────┐ │
│ │ Libs │ │ Libs │ │
│ │ App A │ │ App B │ │
│ └──────────┘ └──────────┘ │
│ Docker Engine (containerd) │
│ Noyau Linux partage │
│ Hardware │
└──────────────────────────────┘
Les conteneurs partagent le noyau. Les VMs ont chacune le leur.
Temps de démarrage
C'est là où la différence se sent le plus au quotidien. Une VM prend 30 secondes a 2 minutes pour démarrer. Un conteneur démarré en moins d'une seconde.
bashtime docker run --rm alpine echo "hello"
# real 0m0.4s
0.4 secondes. Ca change tout pour le workflow de dev. Tu peux créer et détruire des conteneurs a volonte, sans attente.
Le piège de l'isolation
Les conteneurs partagent le noyau. Ca veut dire que l'isolation est plus faible qu'avec une VM. Un bug dans le noyau affecte tous les conteneurs. Une escalade de privileges dans un conteneur peut compromettre l'hote.
En pratique, pour du dev et la plupart des cas de prod, c'est acceptable. Docker ajoute des couches de sécurité (seccomp, AppArmor, capabilities) qui reduisent la surface d'attaque. Mais si tu geres une plateforme multi-tenant ou chaque client lance du code arbitraire, les VMs restent plus sures.
Sur paltemps.fr, les conteneurs suffisent largement. On ne fait pas tourner de code utilisateur non fiable.
Quand utiliser quoi
| Critère | Conteneur | VM |
|---|---|---|
| Démarrage | < 1 seconde | 30s - 2min |
| Taille | 5 Mo - 500 Mo | 1 Go - 20 Go |
| Isolation | Processus (namespaces) | Materiel (hyperviseur) |
| Performance | Quasi-native | Overhead hyperviseur |
| OS multiple | Linux uniquement* | N'importe quel OS |
| Sécurité | Bonne | Meilleure |
*Sur Mac et Windows, Docker lance une VM Linux cachee. On en parle dans l'article 03.
Utilise des conteneurs pour tes applications, tes bases de donnees de dev, tes services. Utilise des VMs quand tu as besoin d'isolation forte ou d'un OS différent.
Un conteneur, c'est juste un processus
Pour finir, une experience qui rend le concept concret :
bash# Lance un shell dans un conteneur
docker run -it alpine sh
# A l'interieur, regarde le PID
echo $
# 1
# Dans un autre terminal, sur l'hote
docker top <container_id>
# Tu vois le meme processus avec un PID different
Le meme processus, vu de deux cotes. A l'intérieur, il pense etre seul. A l'extérieur, c'est un processus normal. C'est ca, un conteneur.
Résumé
- Un conteneur n'est pas une VM legere, c'est un processus isole par le noyau
- Les namespaces isolent la vue (PID, réseau, fichiers), les cgroups limitent les ressources
- Les conteneurs demarrent en moins d'une seconde et consomment peu de ressources
- L'isolation est plus faible qu'une VM, mais suffisante pour la plupart des cas
- Le noyau est partage : tous les conteneurs tournent sur le meme Linux
Precedent : 00 - Introduction | Suivant : 02 - Architecture