Docker pour les devs - 01 - Containers vs VMs

Ce qu'est vraiment un conteneur Linux, comment il différé d'une VM, et quand utiliser l'un ou l'autre.

  1. 01 Docker pour les devs - 00 - Pourquoi Docker change tout
  2. 02 Docker pour les devs - 01 - Containers vs VMs
  3. 03 Docker pour les devs - 02 - L'architecture de Docker
  4. 04 Docker pour les devs - 03 - Docker Desktop, Engine et alternatives
  5. 05 Docker pour les devs - 04 - Écrire un Dockerfile
  6. 06 Docker pour les devs - 05 - Layers et cache
  7. 07 Docker pour les devs - 06 - Le .dockerignore
  8. 08 Docker pour les devs - 07 - Multi-stage builds
  9. 09 Docker pour les devs - 08 - Choisir son image de base
  10. 10 Docker pour les devs - 09 - Docker Compose, les bases
  11. 11 Docker pour les devs - 10 - Docker Compose avance
  12. 12 Docker pour les devs - 11 - Networking Docker, les bases
  13. 13 Docker pour les devs - 12 - Networking Docker avance
  14. 14 Docker pour les devs - 13 - Volumes et persistance
  15. 15 Docker pour les devs - 14 - Variables d'environnement et secrets
  16. 16 Docker pour les devs - 15 - Permissions et utilisateurs
  17. 17 Docker pour les devs - 16 - Docker et monorepo
  18. 18 Docker pour les devs - 17 - Dev vs Prod
  19. 19 Docker pour les devs - 18 - ENTRYPOINT, CMD et scripts d'initialisation
  20. 20 Docker pour les devs - 19 - Debugger ses conteneurs
  21. 21 Docker pour les devs - 20 - Bases de donnees dans Docker
  22. 22 Docker pour les devs - 21 - Sauvegardes et restauration
  23. 23 Docker pour les devs - 22 - Conteneuriser un frontend
  24. 24 Docker pour les devs - 23 - Sécurité des conteneurs
  25. 25 Docker pour les devs - 24 - Optimisation des images
  26. 26 Docker pour les devs - 25 - Builds multi-platform
  27. 27 Docker pour les devs - 26 - Limiter les ressources de tes conteneurs
  28. 28 Docker pour les devs - 27 - Gerer les logs comme un adulte
  29. 29 Docker pour les devs - 28 - Healthchecks et restart policies
  30. 30 Docker pour les devs - 29 - Nettoyer Docker avant qu'il mange ton disque
  31. 31 Docker pour les devs - 30 - Registries et stratégie de tags
  32. 32 Docker pour les devs - 31 - Docker en CI/CD
  33. 33 Docker pour les devs - 32 - Au-dela de Compose
  34. 34 Docker pour les devs - 33 - Glossaire Docker de A a Z

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

Sources

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.