Les modes réseau Docker
Docker propose plusieurs drivers réseau, chacun adapté à des cas d'usage spécifiques.
Comprendre ces drivers évite la plupart des problèmes de connectivité que l'on rencontre avec les conteneurs : une application qui ne trouve pas sa base de données, un port inaccessible depuis l'extérieur, ou au contraire une base exposée sur Internet sans qu'on l'ait voulu. Les drivers les plus utilisés sont bridge, host et overlay ; il existe aussi none, qui coupe tout accès réseau, et macvlan, plus rare. Les commandes de base pour explorer l'existant :
docker network ls
docker network inspect bridge
docker network inspect mon-reseau --format '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{"\n"}}{{end}}'
Bridge (par défaut)
Le mode bridge crée un réseau isolé pour les conteneurs sur un même hôte :
docker network create --driver bridge mon-reseau
docker run --network mon-reseau --name app myapp
docker run --network mon-reseau --name db mysql
Les conteneurs sur le même réseau bridge peuvent communiquer via leur nom de conteneur comme hostname.
Une nuance importante : cette résolution par nom ne fonctionne que sur les réseaux bridge créés par l'utilisateur. Le réseau bridge par défaut, auquel sont rattachés les conteneurs lancés sans option --network, ne fournit pas de DNS entre conteneurs. C'est une raison suffisante pour toujours créer ses propres réseaux, ce que Docker Compose fait automatiquement : chaque projet reçoit un réseau nommé <projet>_default.
Sur un réseau bridge, les conteneurs ont des adresses privées et ne sont pas joignables depuis l'extérieur. Pour rendre un service accessible, on publie un port : Docker ajoute alors une règle de NAT de l'hôte vers le conteneur. Par défaut, le port est ouvert sur toutes les interfaces de l'hôte ; précisez une adresse pour le limiter :
# Accessible depuis l'extérieur sur le port 8080 de l'hôte
docker run -d -p 8080:80 --name web nginx:alpine
# Accessible uniquement depuis l'hôte lui-même
docker run -d -p 127.0.0.1:8081:80 --name admin nginx:alpine
# Rattacher un conteneur existant à un second réseau
docker network connect mon-reseau web
Attention : les règles iptables créées par Docker pour les ports publiés s'appliquent avant celles d'un pare-feu comme UFW. Un port publié sur 0.0.0.0 est donc joignable même si UFW semble le bloquer.
Host
Le mode host supprime l'isolation réseau. Le conteneur utilise directement le réseau de l'hôte :
docker run --network host nginx
Utile pour les performances maximales mais sans isolation.
Il n'y a ni NAT ni port à publier : Nginx écoute directement sur le port 80 de l'hôte, et les options -p sont ignorées. En contrepartie, deux conteneurs ne peuvent pas utiliser le même port, et le conteneur voit toutes les interfaces réseau de la machine. Ce mode se justifie pour des outils qui doivent observer le réseau de l'hôte (agents de monitoring, certains outils VPN) ou pour des charges où la moindre latence compte. Il est pleinement pris en charge sur Linux ; avec Docker Desktop sur macOS et Windows, les conteneurs tournent dans une VM et le comportement n'est pas le même.
None
Avec --network none, le conteneur n'a qu'une interface loopback. C'est utile pour un traitement qui n'a besoin d'aucun accès réseau, par exemple la conversion de fichiers non fiables : même compromis, le processus ne peut rien exfiltrer.
docker run --rm --network none -v "$PWD/input:/data:ro" alpine ls -l /data
Overlay
Pour les clusters Docker Swarm, le réseau overlay permet la communication entre conteneurs sur différents nœuds :
docker network create --driver overlay --attachable mon-overlay
Un réseau overlay nécessite que l'hôte soit un nœud Swarm (docker swarm init). Le trafic entre nœuds est encapsulé en VXLAN : les ports 2377/tcp (gestion du cluster), 7946/tcp et udp (découverte entre nœuds) et 4789/udp (données) doivent être ouverts entre les machines. L'option --attachable permet à des conteneurs lancés avec docker run, et pas seulement aux services Swarm, de rejoindre le réseau. Le trafic de gestion est chiffré par défaut ; pour chiffrer aussi le trafic applicatif entre nœuds, ajoutez --opt encrypted.
Macvlan
Le driver macvlan donne au conteneur sa propre adresse MAC et une adresse IP sur le réseau physique, comme s'il s'agissait d'une machine à part entière. Il sert surtout à intégrer des applications historiques qui attendent une IP dédiée. Particularité à connaître : par défaut, l'hôte lui-même ne peut pas communiquer avec ses conteneurs macvlan.
DNS interne
Docker intègre un serveur DNS permettant la résolution par nom de service :
services:
app:
networks:
- frontend
- backend
nginx:
networks:
- frontend
db:
networks:
- backend
networks:
frontend:
backend:
Dans chaque conteneur, ce DNS est joignable à l'adresse 127.0.0.11. Il résout les noms de service, les noms de conteneur et les éventuels alias déclarés, mais uniquement pour les conteneurs qui partagent un réseau. Dans l'exemple ci-dessus, app peut joindre nginx et db, tandis que nginx ne peut pas résoudre db : un Nginx compromis n'a aucun chemin direct vers la base. Si un service est mis à l'échelle sur plusieurs conteneurs, son nom renvoie plusieurs adresses.
Pour aller plus loin, déclarez le réseau backend comme interne (sans accès vers l'extérieur) et partagez un réseau créé en dehors du projet avec un reverse proxy :
networks:
frontend:
backend:
internal: true
proxy:
external: true
Pour diagnostiquer un problème de résolution ou de connectivité, lancez un conteneur d'outils sur le même réseau plutôt que d'installer des paquets dans vos images :
docker run --rm -it --network mon-reseau nicolaka/netshoot
# Puis, dans le conteneur :
dig db
nc -zv db 3306
Conflits de sous-réseaux
Docker attribue à chaque réseau un sous-réseau privé, souvent en 172.17.0.0/16 et au-delà. Si votre réseau d'entreprise ou votre VPN utilise déjà ces plages, certaines destinations deviennent injoignables depuis l'hôte. La solution consiste à définir des plages dédiées dans /etc/docker/daemon.json, puis à redémarrer Docker et recréer les réseaux :
{
"default-address-pools": [
{ "base": "10.200.0.0/16", "size": 24 }
]
}
Récapitulatif des drivers
| Driver | Portée | Cas d'usage |
|---|---|---|
| bridge | Un hôte | Cas général, applications Compose |
| host | Un hôte | Performance maximale, outils réseau |
| none | Un conteneur | Traitements sans accès réseau |
| overlay | Plusieurs hôtes | Clusters Docker Swarm |
| macvlan | Réseau physique | Applications qui exigent une IP dédiée |
Bonnes pratiques réseau
- Isolez les services par réseau (frontend, backend, monitoring)
- Utilisez des réseaux internes pour les services non exposés
- Documentez vos topologies réseau
- Limitez les ports exposés au strict minimum
- Utilisez les noms de service plutôt que les adresses IP, qui changent à chaque recréation
- Liez à
127.0.0.1les ports qui ne doivent servir qu'en local
Pour la sécurité des conteneurs au-delà du réseau, voir l'article Sécuriser vos conteneurs Docker.