DCNA
Docker Certified Network Associate
DCNANetwork Troubleshooting

Docker Network Troubleshooting

Le dépannage réseau suit toujours la même logique : isoler la couche du problème. Un problème réseau dans Docker se situe soit dans la configuration du container, soit dans le réseau Docker, soit dans l'hôte, soit entre les deux machines.

Méthode : du plus simple au plus profond

1. Le container tourne-t-il ?          → docker ps / docker logs
2. A-t-il une adresse IP ?             → docker inspect
3. Peut-il joindre sa gateway ?        → ping depuis l'intérieur
4. Les DNS fonctionnent-ils ?          → nslookup / cat /etc/resolv.conf
5. Le port est-il bien exposé ?        → docker port / ss
6. Y a-t-il un problème iptables ?     → iptables -L / ip_forward
7. Analyse de trafic                   → tcpdump / nicolaka/netshoot

Étape 1 : État du container

# Voir tous les containers (y compris stoppés, avec code de sortie)
docker ps -a
# STATUS "Exited (1)" → le container a crashé, lire les logs

# Logs du container
docker logs my-container
docker logs --tail 50 --follow my-container  # 50 dernières lignes + live

# Vérifier la santé (si healthcheck configuré)
docker inspect my-container | grep -A 10 '"Health"'

Étape 2 : Adresse IP et configuration réseau

# IP du container (méthode rapide)
docker inspect my-container \
  --format '{{range .NetworkSettings.Networks}}IP: {{.IPAddress}} / GW: {{.Gateway}}{{"\n"}}{{end}}'

# Configuration complète
docker inspect my-container --format '{{json .NetworkSettings}}' | jq

# Vérifier depuis l'intérieur
docker exec my-container ip addr show
docker exec my-container ip route show
# La ligne "default via X.X.X.1" → c'est ta gateway (docker0)

Étape 3 : Connectivité de base

# Ping la gateway (docker0) — si ça échoue, problème de veth/bridge
docker exec my-container ping -c2 172.17.0.1

# Ping l'extérieur
docker exec my-container ping -c2 8.8.8.8

# Ping un autre container par IP
docker exec my-container ping -c2 172.17.0.3

# Ping par nom (ne fonctionne que sur user-defined networks !)
docker exec my-container ping -c2 other-container

Étape 4 : DNS

# Voir la config DNS du container
docker exec my-container cat /etc/resolv.conf
# Sur user-defined network → nameserver 127.0.0.11
# Sur bridge par défaut   → nameserver de l'hôte (pas de DNS container)

# Tester la résolution
docker exec my-container nslookup other-service
docker exec my-container nslookup other-service 127.0.0.11  # forcer le DNS Docker

# Sur le bridge par défaut, les noms de containers ne résoudront PAS
# → utiliser les IPs ou passer sur un user-defined network

Étape 5 : Ports

# Voir les ports publiés d'un container
docker port my-container
# → 80/tcp -> 0.0.0.0:8080

# Vérifier ce qui écoute sur l'hôte
ss -tlnp | grep :8080

# Depuis l'hôte, tester l'accès au port publié
curl -v http://localhost:8080/health

# Vérifier les règles DNAT que Docker a créées
sudo iptables -t nat -L DOCKER -n -v | grep 8080

Problèmes fréquents et solutions

Le container ne peut pas joindre internet

# 1. Vérifier que ip_forward est activé
cat /proc/sys/net/ipv4/ip_forward
# Si 0 → l'activer
sudo sysctl -w net.ipv4.ip_forward=1

# 2. Vérifier la politique FORWARD d'iptables
sudo iptables -L FORWARD | head -5
# Si policy DROP → Docker ne peut pas router le trafic
# Docker devrait avoir ajouté ACCEPT pour son trafic

# 3. Vérifier la règle MASQUERADE
sudo iptables -t nat -L POSTROUTING -n
# Doit avoir: MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16

DNS ne fonctionne pas dans le container

# Diagnostic
docker exec my-container cat /etc/resolv.conf

# Cause 1: sur le bridge par défaut (pas de DNS Docker)
# Solution: créer un user-defined network
docker network create app-net
docker run --network app-net --name api my-image

# Cause 2: DNS personnalisé cassé
# Solution: spécifier un DNS fiable
docker run --dns 8.8.8.8 my-image

"Port already in use" lors du lancement

# Trouver quel processus utilise le port
ss -tlnp | grep :80
fuser 80/tcp

# Soit stopper le processus, soit changer le port de mapping
docker run -p 8081:80 nginx  # utiliser un autre port hôte

Containers sur des hosts différents ne communiquent pas (overlay)

# Vérifier le statut du swarm
docker node ls

# Vérifier que UDP 4789 est ouvert (VXLAN)
sudo iptables -L -n | grep 4789
# Tester depuis l'hôte avec netcat
nc -uz <autre-node-ip> 4789

# Inspecter le réseau overlay
docker network inspect my-overlay
# Regarder "Peers" → liste des nodes dans le réseau

# Ping cross-node avec netshoot
docker run --rm --network my-overlay nicolaka/netshoot ping other-container

"Cannot connect to the Docker daemon"

# Vérifier que Docker tourne
sudo systemctl status docker

# Vérifier les permissions du socket
ls -la /var/run/docker.sock
# Doit être accessible à ton user (group docker) ou en sudo
groups $USER  # vérifie que tu es dans le groupe docker

# Ajouter au groupe si nécessaire
sudo usermod -aG docker $USER
# (se déconnecter et reconnecter pour prendre effet)

L'outil ultime : nicolaka/netshoot

netshoot est un container avec 60+ outils réseau pré-installés. Tu peux l'attacher au namespace réseau d'un container existant :

# Analyser le réseau d'un container en cours
docker run --rm -it \
  --network container:my-container \
  nicolaka/netshoot

# Dans netshoot, tu as accès à :
tcpdump -i eth0 -n port 80   # capturer le trafic
ss -tlnp                      # voir les ports
netstat -rn                   # table de routage
nmap -p 1-1000 other-service  # scanner les ports
iperf3 -c other-service       # tester la bande passante
traceroute 8.8.8.8            # tracer la route
dig @127.0.0.11 my-service    # tester le DNS Docker
# Sur le réseau par nom (sans container existant)
docker run --rm -it --network my-net nicolaka/netshoot

Inspecter les chaînes iptables Docker

# Toutes les règles Docker
sudo iptables -t nat -L DOCKER -n --line-numbers
sudo iptables -L DOCKER-ISOLATION-STAGE-1 -n
sudo iptables -L DOCKER-USER -n

# Ajouter une règle custom sans risquer qu'elle soit écrasée
sudo iptables -I DOCKER-USER -s 192.168.1.0/24 -j ACCEPT

Network Inspect : les champs importants

docker network inspect my-net
  • "Containers" — containers connectés + leurs IPs
  • "IPAM.Config" — subnet et gateway du réseau
  • "Options" — options driver (ex: com.docker.network.bridge.name, encrypted)
  • "Internal": true — pas d'accès à internet depuis ce réseau
  • "Peers" — (overlay) liste des nodes qui ont ce réseau

Résumé

  • Commencer par docker ps -a et docker logs avant de chercher un problème réseau
  • docker inspect donne toutes les infos réseau d'un container
  • Les DNS ne fonctionnent que sur les user-defined networks (pas le bridge par défaut)
  • Vérifier ip_forward et les règles iptables si le trafic ne passe pas
  • nicolaka/netshoot est l'outil de référence pour diagnostiquer depuis l'intérieur du réseau