Retour au cours

infra / reseaux-tcp-ip

Network namespaces Linux

Leçon 201 exercice

Explication

Ce que vous allez apprendre

  • Comprendre ce qu'est un network namespace et en quoi il isole complètement une pile réseau
  • Créer un namespace, y exécuter une commande, et constater son isolation totale par défaut
  • Relier deux namespaces entre eux avec une paire veth (virtual ethernet)
  • Reconstituer, à la main, l'équivalent du réseau "bridge" de Docker avec un bridge Linux et du NAT
  • Faire le lien explicite entre ce mécanisme bas niveau et ce que fait réellement docker network create

Dans quel contexte ?

Un développeur qui utilise Docker tous les jours se demande enfin comment un conteneur obtient sa propre adresse IP, isolée du reste de la machine hôte, sans jamais avoir eu à y penser. En recréant à la main un network namespace, une paire veth et une règle NAT MASQUERADE, il comprend soudain que Docker n'a rien de magique : c'est exactement la même combinaison de mécanismes du noyau Linux, simplement automatisée.

Le problème : isoler des processus sans machines virtuelles séparées

Quand plusieurs applications tournent sur la même machine Linux (par exemple plusieurs conteneurs), on veut souvent qu'elles aient chacune leur propre vision du réseau — leurs propres interfaces, leur propre table de routage, leurs propres règles de pare-feu — sans se marcher dessus ni voir le réseau des autres. Créer une machine virtuelle complète pour chaque isolation serait beaucoup trop lourd. Les "network namespaces" du noyau Linux offrent cette isolation à un coût quasi nul.

MécanismeRôle
Network namespacePile réseau isolée (interfaces, routes, règles)
Paire veth"Câble virtuel" reliant deux namespaces ou un namespace à un bridge
Bridge LinuxRelie plusieurs interfaces virtuelles entre elles, comme un switch
NAT (MASQUERADE)Donne l'accès Internet à un namespace isolé

Astuce

Avant de manipuler des network namespaces sur une machine de test, utilise lsns -t net pour voir tous les namespaces réseau déjà actifs (chaque conteneur Docker en cours d'exécution en crée un) : ça aide à distinguer les tiens de ceux déjà présents sur le système.

L'intuition : plusieurs piles réseau indépendantes sur une seule machine

Normalement, une machine Linux n'a qu'une seule pile réseau (interfaces, routes, règles) partagée par tous les processus. Un network namespace crée une pile réseau complètement séparée : un groupe de processus placé dans ce namespace ne voit littéralement aucune des interfaces réseau du système hôte, pas même la boucle locale par défaut. C'est un environnement réseau vide, à construire depuis zéro.

Comment ces environnements isolés communiquent malgré tout

Un namespace complètement isolé ne sert à rien tout seul : il faut le relier au reste du monde. Une paire "veth" (virtual ethernet) fonctionne comme un câble réseau virtuel entre deux points — souvent une extrémité dans le namespace, l'autre reliée à un bridge ou à un autre namespace, exactement comme on brancherait un câble physique entre deux machines. Combiné avec du NAT (masquage d'adresse pour partager une connexion Internet), c'est précisément la brique de base que Docker automatise à chaque fois qu'un conteneur est créé.

Le lien avec les conteneurs

Comprendre les network namespaces à la main démystifie ce que fait réellement docker network create : ce n'est pas de la magie, mais la combinaison de trois mécanismes déjà vus dans ce cours — namespaces, veth, et NAT/iptables.

Commandes & code

Network namespaces Linux

text
# Un network namespace donne à un groupe de process sa PROPRE pile réseau complète :
# interfaces, table de routage, règles de pare-feu, ports en écoute — totalement isolés
# du namespace par défaut. C'est la brique qu'utilise Docker pour isoler chaque conteneur.
bash
# --- Créer et lister des namespaces réseau ---
sudo ip netns add ns-app
sudo ip netns add ns-db
ip netns list
ip netns exec ns-app ip addr show           # namespace vide au départ : seulement "lo", et encore DOWN
sudo ip netns exec ns-app ip link set lo up

# --- Exécuter une commande DANS un namespace précis ---
sudo ip netns exec ns-app bash                # ouvre un shell isolé dans ce namespace réseau
sudo ip netns exec ns-app curl https://exemple.com    # échoue : aucune interface autre que lo

# --- Relier deux namespaces entre eux avec une paire veth ---
sudo ip link add veth-app type veth peer name veth-db
sudo ip link set veth-app netns ns-app
sudo ip link set veth-db netns ns-db
sudo ip netns exec ns-app ip addr add 10.99.0.1/24 dev veth-app
sudo ip netns exec ns-db ip addr add 10.99.0.2/24 dev veth-db
sudo ip netns exec ns-app ip link set veth-app up
sudo ip netns exec ns-db ip link set veth-db up
sudo ip netns exec ns-app ping -c2 10.99.0.2       # les deux namespaces se joignent directement

# --- Relier un namespace à Internet via un bridge et NAT (reproduit le réseau "bridge" de Docker) ---
sudo ip link add br0 type bridge
sudo ip addr add 10.99.1.1/24 dev br0
sudo ip link set br0 up

sudo ip link add veth-host type veth peer name veth-ns
sudo ip link set veth-host master br0
sudo ip link set veth-host up
sudo ip link set veth-ns netns ns-app
sudo ip netns exec ns-app ip addr add 10.99.1.2/24 dev veth-ns
sudo ip netns exec ns-app ip link set veth-ns up
sudo ip netns exec ns-app ip route add default via 10.99.1.1

# NAT en sortie pour donner l'accès Internet au namespace (comme MASQUERADE Docker)
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -s 10.99.1.0/24 -o eth0 -j MASQUERADE
sudo ip netns exec ns-app ping -c2 8.8.8.8            # fonctionne maintenant, via le bridge + NAT

# --- Diagnostiquer depuis l'extérieur ---
ip netns pids ns-app                    # PID des process rattachés à ce namespace
lsns -t net                               # tous les namespaces réseau actifs sur la machine, avec leurs PID

# --- Nettoyage ---
sudo ip netns del ns-app
sudo ip netns del ns-db
sudo ip link del br0

Résumé

  • ip netns add crée un network namespace vide (même pas lo actif) ; une paire veth relie deux namespaces, ou un namespace à un bridge.
  • C'est exactement ce mécanisme, combiné à iptables MASQUERADE, que Docker automatise derrière docker network create.
  • lsns -t net et ip netns pids permettent de retrouver quel process appartient à quel namespace réseau sur une machine hôte.

Exercices pratiques

1 disponible
1

Mission : réparer un namespace qui n'atteint pas Internet

Objectif : Diagnostiquer pourquoi un namespace correctement câblé à un bridge ne peut pas sortir vers Internet, en identifiant la brique NAT manquante.

Contexte

Un développeur a recréé à la main l'équivalent du réseau bridge de Docker : un namespace ns-app, un bridge br0, et une paire veth reliant les deux, avec les adresses IP configurées correctement des deux côtés (10.99.1.1 sur le bridge, 10.99.1.2 dans le namespace). Le ping entre ns-app et le bridge fonctionne, mais impossible de sortir vers Internet.

Résoudre l’exercice →