Les conteneurs sont devenus incontournables dans notre petit monde de l’IT. On en parle partout : Docker, Kubernetes, Podman… On les utilise pour déployer des applications, faciliter le développement et accélérer les mises en production.
Mais est-ce qu’on s’est déjà vraiment demandé ce qu’est un conteneur, au fond ? Pour beaucoup d’entre nous, c’est juste une boîte noire : on y met une application, et ça marche…
Le problème, c’est que derrière cette boîte noire se cachent des concepts techniques essentiels. Et dans un monde où tout devient de plus en plus automatisé (IA, ChatGPT, orchestrateurs, etc.), comprendre ces bases reste indispensable. Sinon, on risque de devenir de simples utilisateurs de solutions qu’on ne maîtrise plus.
Qu’est-ce qu’un conteneur ?
En fait, dans notre imaginaire collectif, un conteneur, c’est une sorte de VM, mais pas exactement. On sait tous que c’est beaucoup plus léger, aussi que c’est pas super secure… Mais au-delà de ces idées reçues, qu’est-ce qui fait qu’un conteneur est un conteneur ?
Déjà sachez que les containers existent depuis longtemps, même depuis les années 70 !
Simplement, un container est un processus isolé du reste du système. Il ne voit que ce qu’on lui donne à voir, et il ne peut pas interférer avec les autres processus du système. Par exemple on lui donne un nouveau “/”, on lui donne son propre PID 1, et même son propre réseau.
A la base pour faire tout ça, on utilisait chroot. Cette commande ancestrale permet de changer la racine du système de fichiers pour un processus donné. Donc si vous avez votre processus qui tourne dans un chroot, il ne peut pas voir les fichiers en dehors de ce chroot. Voila une petite representation de ce que ça donne :

Mais comme vous le voyez, un chroot ne fait que changer la racine du système de fichiers. Dans notre contexte actuel, ça ne suffit pas. Imaginez un processus qui tourne dans un chroot, mais qui peut toujours voir tous les autres processus du système, consommer toute la mémoire et le CPU, et même accéder au réseau.
Ce n’est pas réellement isolé… Juste on a changé la racine du système de fichiers.
C’est pour cela qu’on utilise pas directement chroot, mais plutot d’autre mécanismes (qui utilisent toujours chroot en interne) pour faire des environnements isolés. Ces mécanismes sont les namespaces et les cgroups.
Les namespaces

La fonction des namespaces est de donner l’illusion à chaque processus qu’il dispose de son propre environnement système. Plus simplement, chaque processus peut avoir sa propre vue du système, indépendante de celle des autres. Grâce aux namespaces, on contrôle précisément ce qu’un processus peut voir et ce qu’il peut faire.
En réalité, un conteneur n’est rien d’autre qu’un ensemble de namespaces combinés. Ce n’est pas juste “un namespace”, mais plusieurs namespaces regroupés pour isoler différentes dimensions du système :
- les processus (PID),
- le système de fichiers (mount),
- le réseau (net),
- les utilisateurs (user),
- etc.
Attention : les namespaces ne créent pas de nouveaux noyaux, ni ne virtualisent le matériel. Tout tourne sur le même noyau Linux partagé. Ce qu’ils font, c’est manipuler la perception qu’un processus a du système et de ses ressources.

Un peu de pratique
Pour illustrer le fonctionnement des namespaces, on va faire un petit exercice pratique. On va créer un conteneur minimaliste en utilisant les namespaces.
D’abord sur votre machine, lancez ps aux. Vous allez voir une liste très longue de processus en cours d’execution.

Maintenant lancez la commande suivante :
sudo unshare --fork --pid --mount-proc bash
Cette commande va detacher notre processus du reste du système en créant un nouveau namespace, et en lui donnant son propre PID namespace.
-
–fork : Lance le programme spécifié (bash) comme un processus enfant direct. C’est important pour que la magie du PID opère.
-
–pid : Crée un nouveau namespace pour les PIDs.
-
–mount-proc : C’est le point crucial ! Par défaut, même dans un nouveau namespace, le système de fichiers /proc (qui est utilisé par des commandes comme ps) reste celui de l’hôte. Cette option monte une nouvelle version de /proc qui correspond à notre nouveau namespace PID. Sans ça, ps continuerait de montrer les PIDs de l’hôte.
Donc si maintenant vous lancez ps aux dans ce nouveau shell, vous verrez que la liste des processus est quasi vide, à part le shell lui-même et le ps que vous venez de lancer. Comme suit :

Donc si vous voyez bien, avant votre PID 1 etait le systemD, le processus qui permet de lancer tous les autres processus du système. Maintenant, dans ce nouveau namespace, votre PID 1 est le bash que vous venez de lancer, donc le bash !!!
Pour que vous soyez sur de ce que vous faites, lancez un nouveau ps -aux dans votre hote pendant que le shell est ouvert dans le namespace. Vous verrez que les PIDs sont différents.

Ici vous voyez clairement que depuis notre hote, on peut voir le processus bash qui tourne dans le namespace, mais sous un PID différent (ici 1125).
Depuis le namespace, les processus de l’hôte sont invisibles. En revanche, depuis l’hôte, on peut toujours voir les processus lancés dans les namespaces.
On peut bien entendu, ajouter plus de namespaces pour isoler d’autres aspects du système. Par exemple, on peut ajouter un namespace de réseau pour isoler le réseau du conteneur, ou un namespace de montage pour isoler le système de fichiers.
Les cgroups

Jusqu’a la vous avez compris que les namespaces permettent d’isoler les processus. Donc si on fait une analogie, on a une grande maison (hote), et la maison on a des chambres (namespaces) ou les gens (processus) dedans chaque chambre ne peuvent pas se voir.
Mais dans cette maison, il y a des ressources partagées : la cuisine (CPU), l’eau (mémoire), l’électricité (I/O). Mais si jamais quelqu’un dans une chambre decide de laisser le robinet ouvert. Les autres personnes dans les autres chambres ne pourront plus utiliser l’eau. C’est la que les cgroups entrent en jeu.
Les cgroups (Control Groups) sont un mécanisme qui permet de limiter, de prioriser et d’isoler les ressources utilisées par les processus. Ils permettent de contrôler la quantité de ressources (CPU, mémoire, I/O, etc.) qu’un groupe de processus peut utiliser.
Et si jamais un processus dans un cgroup utilise trop de ressources, les cgroups peuvent le limiter ou même le killer pour éviter qu’il n’affecte les autres processus. C’est comme si on mettait un robinet sur chaque chambre avec un débitmètre.
Conclusion
Les conteneurs ne sont pas des machines virtuelles légères, ni des outils magiques, ils simplement des processus Linux, isolés et limités grâce à des mécanismes bien connus du noyau comme les namespaces et les cgroups.
Comprendre ces bases permet non seulement de mieux maîtriser Docker, Kubernetes et leurs dérivés, mais aussi de mieux diagnostiquer, optimiser et sécuriser ses environnements de production.
Dans un prochain article, on pourrait même aller plus loin : voir comment Docker ou containerd s’appuient sur ces briques pour créer nos fameux conteneurs.