Aller au contenu

Introduction aux namespaces Linux

Mise à jour :

Les namespaces Linux sont un peu comme des compartiments étanches dans un navire : ils isolent les ressources, permettant aux processus de naviguer dans leur propre petit univers sans interférer avec les autres. Dans le monde de la virtualisation et de la conteneurisation, les namespaces jouent un rôle essentiel. Ils sont au cœur des technologies comme Docker et Kubernetes, offrant une manière légère et efficace de créer des environnements isolés directement au sein du système d’exploitation.

Mais pourquoi isoler des processus, des réseaux, ou encore des systèmes de fichiers ? Imaginez que vous ayez plusieurs applications qui, pour diverses raisons, doivent rester bien séparées : vous ne voulez pas qu’un bug dans une application affecte l’ensemble de votre système, ou que des configurations spécifiques entrent en conflit. Les namespaces offrent cette séparation, vous permettant d’exécuter plusieurs processus ou environnements comme s’ils étaient sur des systèmes totalement distincts.

Un peu d’Histoire

Les namespaces Linux ont émergé au début des années 2000 pour répondre aux besoins croissants d’isolation des ressources dans un système multi-utilisateurs. Dès 2002, avec la version 2.4.19 du noyau, le premier namespace, dédié aux espaces de montage, a permis de créer des points de montage isolés pour chaque processus. Ce concept a été progressivement étendu avec les PID namespaces pour isoler les processus en 2008, suivi des Network namespaces pour l’isolation réseau et des IPC namespaces pour les communications entre processus.

L’arrivée de Docker en 2013 a marqué un tournant majeur, exploitant pleinement les namespaces pour créer des conteneurs légers et rapides à déployer, sans les lourdeurs des machines virtuelles. En combinant isolation (namespaces) et gestion fine des ressources cgroups, Docker a démocratisé l’usage des conteneurs, transformant les pratiques de développement et de déploiement d’applications.

Aujourd’hui, les namespaces sont incontournables dans des technologies comme Kubernetes, qui orchestrent des milliers de conteneurs en production. Ils représentent une solution native, légère et performante d’isolation des ressources dans Linux, propulsant la virtualisation moderne.

Le fonctionnement des Namespaces Linux

Les namespaces Linux sont des outils d’isolation puissants, permettant de cloisonner des ressources spécifiques du système pour chaque application ou processus. Cette isolation est particulièrement utile pour créer des environnements sécurisés et indépendants, semblables aux conteneurs. Expliquons les principaux types de namespaces et voyons comment ils fonctionnent ensemble pour créer des espaces cloisonnés.

Les Principaux Types de Namespaces

  1. PID Namespace (Isolation des Processus)

    • Chaque namespace PID possède son propre ensemble de processus, avec des identifiants uniques. Les processus dans ce namespace ne voient que ceux qui y sont créés, sans accès aux processus en dehors.
    • Usage : Utilisé pour isoler les processus dans des conteneurs. Par exemple, chaque conteneur peut lancer ses propres applications sans interférer avec les processus du système principal.
  2. Network Namespace (Isolation Réseau)

    • Le Network namespace permet à chaque environnement d’avoir ses propres interfaces réseau, adresses IP, et configurations. Cela crée des réseaux virtuels indépendants.
    • Usage : Parfait pour tester des configurations réseau sans risque pour le réseau principal. Chaque conteneur peut avoir sa propre adresse IP et règles de pare-feu.
  3. Mount Namespace (Isolation du Système de Fichiers)

    • Ce namespace donne à chaque environnement son propre espace de montage pour les systèmes de fichiers, permettant de monter et démonter des volumes sans impacter le reste du système.
    • Usage : Utile pour isoler des données. Par exemple, un conteneur peut utiliser un répertoire spécifique sans accès aux fichiers du système principal.
  4. UTS Namespace (Isolation du Nom d’Hôte)

    • Le UTS namespace permet de définir un nom d’hôte spécifique pour chaque environnement. Cela donne une identité propre à chaque namespace.
    • Usage : Essentiel pour les conteneurs ayant besoin d’un nom unique pour se distinguer. Ainsi, un conteneur peut se présenter sous un nom distinct comme “conteneur-web” tandis que le système principal garde son propre nom.
  5. IPC Namespace (Isolation de la Communication Inter-Processus)

    • L’IPC namespace isole les mécanismes de communication entre processus, comme la mémoire partagée, pour éviter les interférences entre différents environnements.
    • Usage : Garantit une communication sécurisée entre processus au sein d’un conteneur, sans affecter les processus à l’extérieur.
  6. User Namespace (Isolation des Permissions)

    • Le User namespace permet aux utilisateurs et processus dans un environnement d’avoir des permissions locales sans impact global. Par exemple, un utilisateur root dans un conteneur n’a pas de privilèges sur le système principal.
    • Usage : Renforce la sécurité en permettant un accès administrateur dans le conteneur sans compromettre la sécurité du système principal.

Comment Fonctionnent ils Ensemble ?

Chaque namespace offre une isolation spécifique, mais leur force réside dans leur combinaison pour créer des environnements cloisonnés complets, proches de véritables conteneurs. Par exemple :

  1. PID et Mount Namespaces :

    • Lorsqu’on utilise un PID namespace pour isoler les processus, il est souvent nécessaire de combiner un Mount namespace pour afficher un système de fichiers /proc propre. Cela permet d’utiliser des commandes comme ps aux dans le namespace PID sans voir les processus du système principal.
  2. Network et User Namespaces :

    • En combinant un Network namespace (pour un réseau indépendant) et un User namespace (pour les permissions), chaque conteneur peut gérer sa propre configuration réseau en sécurité. L’utilisateur “root” du conteneur peut configurer son réseau sans accès au réseau du système principal, ce qui offre une sécurité renforcée.
  3. Intrication Totale pour un Conteneur Complet :

    • Pour créer un environnement cloisonné complet, on peut combiner plusieurs namespaces : PID, Network, Mount, UTS, User, et IPC. Cela permet de créer un mini-système isolé :
      • Le PID namespace cloisonne les processus.
      • Le Network namespace donne une interface réseau unique.
      • Le Mount namespace isole le système de fichiers.
      • Le UTS namespace donne un nom d’hôte distinct.
      • Le User namespace limite les permissions utilisateur à l’intérieur du conteneur.
      • L’IPC namespace sécurise la communication entre processus.

En combinant tous ces namespaces, on obtient un conteneur capable de fonctionner de manière autonome, sécurisé et indépendant du système principal. C’est exactement ce que fait Docker ou d’autres technologies de conteneurisation pour créer des environnements légers et cloisonnés.

Les Commandes Essentielles pour Manipuler les Namespaces Linux

Les namespaces Linux se manipulent à l’aide de plusieurs commandes, qui permettent de les créer, les gérer, et les administrer. Voici les commandes principales pour manipuler les namespaces, avec des exemples d’utilisation pour chaque type de namespace.

lsns : Lister les Namespaces Actifs

La commande lsns liste tous les namespaces actifs sur le système, en affichant des informations sur leur type, leur PID associé, et leur identifiant.

  • Syntaxe de base :

    Terminal window
    lsns
  • Exemple : Lister tous les namespaces avec leurs détails

    Terminal window
    lsns

    Cette commande affiche tous les namespaces du système (PID, network, mount, etc.), avec des colonnes indiquant le type, l’identifiant et le processus associé. Pour filtrer, on peut utiliser grep :

    Terminal window
    lsns | grep net # Lister les namespaces réseau
    lsns | grep pid # Lister les namespaces PID

unshare

La commande unshare permet de créer un nouveau namespace et d’y exécuter une commande. Cette commande est particulièrement utile pour créer un environnement cloisonné pour des processus, le réseau, ou les systèmes de fichiers.

  • Syntaxe de base :

    Terminal window
    sudo unshare [options] <commande>
  • Options importantes :

    • --pid : Crée un namespace PID (processus).
    • --net : Crée un namespace réseau.
    • --mount : Crée un namespace de montage.
    • --uts : Crée un namespace UTS (nom d’hôte).
    • --user : Crée un namespace utilisateur.
    • --ipc : Crée un namespace IPC (communication inter-processus).
    • --fork : Lance la commande dans un processus enfant isolé.
  • Exemple : Créer un shell avec un PID et un Mount namespace isolés

    Terminal window
    sudo unshare --pid --mount --fork bash

nsenter : Accéder à un Namespace Existant

La commande nsenter permet d’entrer dans un namespace déjà existant. Elle est souvent utilisée pour le dépannage ou la gestion des conteneurs, pour inspecter un namespace sans arrêter les processus qu’il contient.

  • Syntaxe de base :

    Terminal window
    sudo nsenter --target <PID> --<namespace>
  • Options importantes :

    • --pid : Entre dans le namespace PID.
    • --net : Entre dans le namespace réseau.
    • --mount : Entre dans le namespace de montage.
    • --uts : Entre dans le namespace UTS.
    • --ipc : Entre dans le namespace IPC.
    • --user : Entre dans le namespace utilisateur.
    • --target <PID> : Spécifie le PID d’un processus situé dans le namespace cible.
  • Exemple : Accéder au namespace réseau d’un processus spécifique

    Terminal window
    sudo nsenter --target <PID_du_processus> --net

ip netns : Gérer les Namespaces Réseau

Le sous-ensemble netns de la commande ip est conçu pour créer et manipuler spécifiquement les namespaces réseau.

  • Syntaxe de base :

    Terminal window
    ip netns <commande>
  • Commandes principales :

    • add <namespace> : Crée un namespace réseau.
    • delete <namespace> : Supprime un namespace réseau existant.
    • exec <namespace> <commande> : Exécute une commande dans un namespace réseau.
    • list : Affiche la liste des namespaces réseau existants.
  • Exemple : Créer un namespace réseau et y exécuter une commande

    Terminal window
    ip netns add mynamespace
    ip netns exec mynamespace bash

mount : Gérer les Montages dans un Namespace

La commande mount est utile dans un namespace de montage (Mount namespace). Elle permet de monter des systèmes de fichiers spécifiques, comme /proc, de manière isolée dans un namespace.

  • Syntaxe de base :

    Terminal window
    mount -t <type> <source> <cible>
  • Exemple : Remonter /proc dans un namespace PID pour afficher les processus

    Terminal window
    mount -t proc proc /proc

Un peu d’exploration sur un machine ou tourne de conteneurs

Nous allons explorer les namespaces et les montages sur un système Linux où tourne un moteur de conteneurs comme Docker, Podman ou Incus.

Lancez au moins un container en tâche de fond :

Terminal window
docker run -d --name mon-conteneur nginx

Vérifions

Terminal window
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fcca591aaf02 nginx "/docker-entrypoint.…" 8 seconds ago Up 8 seconds 80/tcp mon-conteneur

Tout est prêt pour notre exploration.

Chaque conteneur ou processus isolé est associé à des namespaces spécifiques. Pour les identifier, vous pouvez utiliser la commande suivante :

Terminal window
sudo lsns
NS TYPE NPROCS PID USER COMMAND
4026532431 mnt 5 413658 root nginx: master process nginx -g daemon off;
4026532432 uts 5 413658 root nginx: master process nginx -g daemon off;
4026532433 ipc 5 413658 root nginx: master process nginx -g daemon off;
4026532434 pid 5 413658 root nginx: master process nginx -g daemon off;
4026532435 net 5 413658 root nginx: master process nginx -g daemon off;
4026532510 cgroup 5 413658 root nginx: master process nginx -g daemon off;

Cette commande montre que Nginx (PID 413658) utilise plusieurs types de namespaces pour être isolé du reste du système. Voici ce que cela signifie simplement :

  • mnt : Nginx a son propre système de fichiers isolé.
  • uts : Nginx a son propre nom d’hôte.
  • ipc : Les communications internes de Nginx sont séparées.
  • pid : Les processus de Nginx ne voient que leurs propres PIDs.
  • net : Nginx utilise un réseau indépendant avec ses propres interfaces.
  • cgroup : Les ressources (CPU, mémoire) utilisées par Nginx sont contrôlées.

En résumé, Nginx est isolé dans un environnement sécurisé et indépendant.

Pour vous connnecter au namespace dans les mêmes conditions qu’avec la commande docker exec <Id_Container> sh, vous pouvez utiliser la commande suivante :

Terminal window
sudo nsenter --target 413658 --mount --uts --ipc --pid --net --cgroup sh
#

Essayez ! Vous serez agréablement surpris du résultat.

Étapes pour créer un namespace basique et fonctionnel

  1. Créer les namespaces PID, Mount et Network en même temps

    • On démarre par l’isolation des processus et du système de fichiers avec les options --pid et --mount.
    • Cela ouvre un nouveau shell isolé.
    Terminal window
    sudo unshare --pid --mount --fork bash

    Vous êtes maintenant dans un shell isolé où les processus, le réseau et le système de fichiers sont indépendants du système principal. Essayez la commande ps aux pour voir les processus du système principal. Cela ne fonctionne pas.

  2. Remonter le système de fichiers /proc dans le nouveau namespace

    • Pour permettre à des commandes comme ps de fonctionner dans ce nouveau namespace PID, nous devons monter un nouveau système de fichiers /proc spécifique au namespace.

    Commande à exécuter dans le nouveau shell isolé :

    Terminal window
    mount -t proc proc /proc

    Cette commande monte un système de fichiers /proc spécifique au namespace actuel, permettant à ps et autres commandes d’afficher les processus du namespace isolé.

À ce stade, vous pouvez tester la configuration avec des commandes comme ps aux pour vérifier les processus.

Terminal window
ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 7576 4000 pts/2 S 08:45 0:00 bash
root 9 0.0 0.0 10884 4160 pts/2 R+ 08:46 0:00 ps aux

Si vous quittez le shell isolé, vous retournez dans le shell principal et le namespace sera détruit.

Conclusion

Vous avez compris ce que sont les namespaces Linux, leur rôle dans l’isolation des ressources, et comment ils sont utilisés dans des outils comme Docker ou Kubernetes. Vous savez maintenant qu’ils permettent de cloisonner des processus, des réseaux, et des systèmes de fichiers pour créer des environnements indépendants et sécurisés.

Je vous invite à expérimenter ! Testez la création de vos propres namespaces, manipulez-les avec des outils comme unshare et nsenter, ou explorez ceux utilisés par vos conteneurs. Ces exercices vous permettront de mieux maîtriser ce concept clé du noyau Linux et de l’intégrer dans vos pratiques professionnelles. 🚀