Comment tester la connectivité entre les conteneurs Docker

DockerDockerBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Les conteneurs Docker sont devenus une partie fondamentale du développement et du déploiement d'applications modernes. Lorsque vous travaillez avec plusieurs conteneurs, vous vous assurez que la connectivité adéquate entre eux est cruciale pour que vos applications fonctionnent correctement.

Dans ce laboratoire, vous allez apprendre à vérifier et à résoudre les problèmes de connectivité entre les conteneurs Docker. Nous commencerons par les concepts de base des conteneurs Docker, mettrons en place des conteneurs pour les tests, puis explorerons diverses méthodes pour vérifier et diagnostiquer les connexions réseau entre les conteneurs.

À la fin de ce tutoriel, vous serez en mesure de tester, de vérifier et de résoudre avec confiance les problèmes de connectivité dans vos applications emballées dans des conteneurs.

Ce laboratoire nécessite une connexion Internet pour l'apprentissage, donc seuls les utilisateurs Pro peuvent démarrer la machine virtuelle. Mettez à niveau votre compte en Pro.

Mise en place de conteneurs Docker pour les tests

Avant de pouvoir tester la connectivité entre les conteneurs, nous devons créer quelques conteneurs avec lesquels travailler. Dans cette étape, nous allons mettre en place deux conteneurs Docker simples et découvrir les commandes Docker de base.

Comprendre les conteneurs Docker

Les conteneurs Docker sont des packages légers et autonomes qui incluent tout ce qui est nécessaire pour exécuter une application : le code, le runtime, les outils système, les bibliothèques et les paramètres. Les conteneurs partagent le noyau du système d'exploitation de la machine hôte, mais s'exécutent dans des environnements isolés.

Création de conteneurs de test

Commençons par créer deux conteneurs simples basés sur l'image Ubuntu. Nous utiliserons ces conteneurs tout au long du laboratoire pour tester la connectivité entre eux.

Tout d'abord, créons notre premier conteneur :

docker run -d --name container1 ubuntu:22.04 sleep infinity

Maintenant, créons le second conteneur :

docker run -d --name container2 ubuntu:22.04 sleep infinity
exécuter des conteneurs

Explication des paramètres de la commande :

  • -d : Exécute le conteneur en mode détaché (en arrière-plan)
  • --name : Assigne un nom au conteneur
  • ubuntu:22.04 : L'image Docker à utiliser (version Ubuntu 22.04)
  • sleep infinity : Une commande qui maintient le conteneur en cours d'exécution indéfiniment

Vérification que nos conteneurs sont en cours d'exécution

Pour vérifier si nos conteneurs sont exécutés correctement, utilisez la commande suivante :

docker ps

Vous devriez voir une sortie similaire à celle-ci :

CONTAINER ID   IMAGE          COMMAND            CREATED         STATUS         PORTS     NAMES
f8d97c645cce   ubuntu:22.04   "sleep infinity"   5 seconds ago   Up 4 seconds             container2
a2c516a57cb8   ubuntu:22.04   "sleep infinity"   18 seconds ago  Up 17 seconds            container1

Si vous ne voyez pas les deux conteneurs listés, ils peuvent ne pas avoir démarré correctement. Vous pouvez essayer de les recréer.

Installation d'outils réseau

Par défaut, l'image de conteneur Ubuntu est très minimale et ne contient pas les outils réseau dont nous aurons besoin. Installons ces outils dans les deux conteneurs :

Pour container1 :

docker exec container1 apt-get update
docker exec container1 apt-get install -y iputils-ping net-tools iproute2 curl

Pour container2 :

docker exec container2 apt-get update
docker exec container2 apt-get install -y iputils-ping net-tools iproute2 curl

Ces commandes :

  1. Utilisent docker exec pour exécuter des commandes à l'intérieur d'un conteneur en cours d'exécution
  2. Mettent à jour la liste des packages avec apt-get update
  3. Installent les outils réseau (iputils-ping pour ping, net-tools pour netstat, iproute2 pour les commandes ip et curl)

Maintenant, nos conteneurs sont prêts pour les tests de connectivité dans les étapes suivantes.

Comprendre les réseaux Docker

Les conteneurs Docker communiquent entre eux via des réseaux. Comprendre le fonctionnement des réseaux Docker est essentiel pour tester et résoudre les problèmes de connectivité entre les conteneurs.

Les bases des réseaux Docker

Lorsque vous installez Docker, il crée automatiquement plusieurs réseaux par défaut. Les plus couramment utilisés sont :

  • bridge : Le réseau par défaut auquel les conteneurs se connectent si aucun autre réseau n'est spécifié
  • host : Les conteneurs utilisent directement le réseau de l'hôte (pas d'isolation)
  • none : Les conteneurs n'ont pas accès au réseau

Examnons les réseaux de votre système :

docker network ls

Vous devriez voir une sortie similaire à :

NETWORK ID     NAME      DRIVER    SCOPE
1b95853bf83b   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local

Comprendre le réseau bridge par défaut

Par défaut, nos deux conteneurs sont connectés au réseau bridge par défaut. Examnons ce réseau :

docker network inspect bridge

Cette commande affiche des informations détaillées sur le réseau bridge, y compris les conteneurs connectés à celui-ci et leurs adresses IP. Dans la sortie, recherchez la section "Containers" pour voir container1 et container2 listés avec leurs adresses IP.

Trouver les adresses IP des conteneurs

Pour travailler avec la connectivité des conteneurs, nous devons connaître les adresses IP attribuées à nos conteneurs. Il existe plusieurs façons de trouver ces informations :

En utilisant docker inspect :

docker inspect --format='{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1

Ou depuis l'intérieur du conteneur :

docker exec container1 hostname -i

Notez les adresses IP des deux conteneurs :

docker exec container1 hostname -i
docker exec container2 hostname -i

La sortie montrera l'adresse IP de chaque conteneur, qui commence généralement par 172.17.0.x sur le réseau bridge par défaut.

Création d'un réseau Docker personnalisé

Alors que le réseau bridge par défaut permet la communication entre les conteneurs, la création d'un réseau personnalisé offre une meilleure isolation et une résolution DNS intégrée (les conteneurs peuvent communiquer entre eux par nom au lieu d'IP).

Créons un réseau bridge personnalisé :

docker network create --driver bridge my-network

Maintenant, connectons nos conteneurs existants à ce nouveau réseau :

docker network connect my-network container1
docker network connect my-network container2

Nous pouvons vérifier que nos conteneurs sont connectés au nouveau réseau :

docker network inspect my-network

Maintenant, nos conteneurs sont connectés à la fois au réseau bridge par défaut et à notre réseau personnalisé my-network. Dans l'étape suivante, nous testerons la connectivité entre eux.

Test de la connectivité de base entre les conteneurs

Maintenant que nous avons configuré nos conteneurs et les connectés à des réseaux, nous pouvons tester la connectivité entre eux. Nous utiliserons plusieurs méthodes pour vérifier que les conteneurs peuvent communiquer entre eux.

Utilisation de ping pour tester la connectivité

Le moyen le plus simple de tester la connectivité réseau de base est d'utiliser la commande ping, qui envoie des requêtes d'écho ICMP à l'hôte cible.

Pongons de container1 à container2 en utilisant l'adresse IP :

## Premièrement, obtenons l'adresse IP de container2
CONTAINER2_IP=$(docker exec container2 hostname -i)
echo "Adresse IP de container2 : $CONTAINER2_IP"

## Obtenons la première adresse IP de CONTAINER2_IP
CONTAINER2_IP=$(echo $CONTAINER2_IP | cut -d' ' -f1)
echo "Adresse IP de container2 : $CONTAINER2_IP"

## Maintenant, pongons de container1 à container2
docker exec container1 ping -c 4 $CONTAINER2_IP

Vous devriez voir une sortie similaire à :

PING 172.17.0.3 (172.17.0.3) : 56 octets de données
64 octets de 172.17.0.3 : icmp_seq=0 ttl=64 temps=0.095 ms
64 octets de 172.17.0.3 : icmp_seq=1 ttl=64 temps=0.067 ms
64 octets de 172.17.0.3 : icmp_seq=2 ttl=64 temps=0.090 ms
64 octets de 172.17.0.3 : icmp_seq=3 ttl=64 temps=0.087 ms
--- Statistiques de ping pour 172.17.0.3 ---
4 paquets transmis, 4 paquets reçus, perte de paquets 0%
min/avg/max/stddev du temps de trajet aller-retour = 0.067/0.085/0.095/0.000 ms

Test de la résolution DNS

Un avantage des réseaux Docker personnalisés est qu'ils offrent une résolution DNS automatique, permettant aux conteneurs de communiquer entre eux par nom.

Testons la résolution DNS en pongant le conteneur par son nom :

docker exec container1 ping -c 4 container2

Cela devrait fonctionner car les deux conteneurs sont sur notre réseau personnalisé my-network, qui offre la résolution DNS. Vous devriez voir des réponses de ping similaires au test précédent, mais en utilisant le nom du conteneur au lieu de l'adresse IP.

Utilisation de curl pour tester la connectivité HTTP

Pour les applications exécutant des services web, nous avons souvent besoin de tester la connectivité HTTP. Installons un serveur HTTP simple dans container2 et testons la connectivité à partir de container1.

Tout d'abord, démarrons un serveur HTTP de base dans container2 :

docker exec container2 apt-get install -y python3
docker exec -d container2 bash -c "echo 'Hello from container2' > /index.html && cd / && python3 -m http.server 8080"

Attendez quelques secondes pour que le serveur démarre, puis testez la connexion à partir de container1 :

docker exec container1 curl -s http://container2:8080

Vous devriez voir la sortie :

Hello from container2

Cela confirme que container1 peut se connecter au service HTTP de container2 en utilisant le nom du conteneur pour la résolution DNS.

Test de la connexion avec différentes méthodes

Il est également utile de savoir comment tester la connectivité à l'aide d'autres outils. Essayons d'utiliser nc (netcat) pour vérifier si un port spécifique est ouvert :

## Assurez-vous que netcat est installé dans container1
docker exec container1 apt-get install -y netcat

## Testez la connectivité au serveur HTTP sur container2
docker exec container1 nc -zv container2 8080

Vous devriez voir une sortie indiquant que la connexion a réussi :

Connection to container2 (172.18.0.3) 8080 port [tcp/*] succeeded!

Ces tests confirment que nos conteneurs peuvent communiquer entre eux à la fois au niveau réseau (ping) et au niveau application (HTTP).

Dépannage des problèmes de connectivité des conteneurs

Vous pouvez sauter cette étape si vous n'avez pas de problèmes de connectivité.

Maintenant que nous comprenons comment tester la connectivité entre les conteneurs, explorons comment résoudre les problèmes de connectivité courants.

Problèmes de connectivité courants

Lorsque vous travaillez avec les réseaux de conteneurs Docker, vous pouvez rencontrer plusieurs problèmes courants :

  1. Des conteneurs se trouvant sur des réseaux différents sans un routage approprié
  2. Des paramètres de pare-feu ou de groupe de sécurité bloquant le trafic
  3. Une application ne lisant pas sur l'IP/port attendu
  4. Des erreurs de configuration réseau
  5. Des problèmes de résolution DNS

Passons en revue les étapes de dépannage pour chacun de ces problèmes potentiels.

Vérification de la configuration réseau

Tout d'abord, examinons la configuration réseau de nos conteneurs :

## Affichez les interfaces réseau de container1
docker exec container1 ip addr show

## Affichez les interfaces réseau de container2
docker exec container2 ip addr show

La sortie montre toutes les interfaces réseau de chaque conteneur. Chaque réseau Docker connecté apparaît comme une interface eth avec son adresse IP assignée.

Vérification des itinéraires réseau

Vérifions la configuration de routage dans nos conteneurs :

docker exec container1 route -n

Cela montre la table de routage de container1, indiquant où le trafic réseau est dirigé.

Vérification des ports d'écoute

Pour déterminer si une application écoute correctement les connexions, utilisez :

docker exec container2 netstat -tuln

Cela montre tous les ports d'écoute TCP et UDP. Notre serveur HTTP devrait écouter sur le port 8080.

Diagnostic avec tcpdump

Pour une analyse plus détaillée du trafic réseau, nous pouvons utiliser tcpdump pour capturer et analyser les paquets :

## Installez tcpdump dans container1
docker exec container1 apt-get install -y tcpdump dnsutils

## Capturez les paquets pendant 10 secondes
docker exec container1 timeout 10 tcpdump -i eth0 -n

Pendant que cela tourne, ouvrez un autre terminal et générez du trafic :

docker exec container1 ping -c 3 container2

Vous devriez voir les paquets ICMP capturés dans la sortie de tcpdump.

Vérification de la résolution DNS Docker

Si vous rencontrez des problèmes de résolution DNS entre les conteneurs :

## Vérifiez la configuration DNS
docker exec container1 cat /etc/resolv.conf

## Testez la résolution DNS
docker exec container1 nslookup container2

Simulation d'un problème réseau

Simulons un problème de connectivité en déconnectant temporairement container1 de notre réseau personnalisé :

## Découvrez container1 de my-network
docker network disconnect my-network container1

## Essayez de pinger par nom (cela devrait échouer)
docker exec container1 ping -c 2 container2

Vous devriez voir que le ping échoue car container1 ne peut plus résoudre container2 par nom après avoir été déconnecté du réseau partagé.

Reconnectons-le :

## Reconnectez container1 à my-network
docker network connect my-network container1

## Vérifiez que la connectivité est restaurée
docker exec container1 ping -c 2 container2

Maintenant, le ping devrait fonctionner à nouveau, démontrant comment les conteneurs doivent se trouver sur le même réseau pour que la résolution de nom fonctionne.

Liste de contrôle pour le dépannage

Lorsque vous rencontrez des problèmes de connectivité des conteneurs, suivez cette liste de contrôle :

  1. Vérifiez que les conteneurs sont en cours d'exécution : docker ps
  2. Vérifiez qu'ils sont sur le même réseau : docker network inspect <réseau>
  3. Vérifiez que des adresses IP sont assignées : docker inspect <conteneur>
  4. Testez la connectivité de base (ping) : docker exec <conteneur> ping <cible>
  5. Vérifiez que l'application est en écoute : docker exec <conteneur> netstat -tuln
  6. Vérifiez que la résolution DNS fonctionne : docker exec <conteneur> nslookup <cible>
  7. Cherchez des problèmes de pare-feu : docker exec <conteneur> iptables -L
  8. Vérifiez les journaux des conteneurs : docker logs <conteneur>

En utilisant cette approche systématique, vous devriez être en mesure d'identifier et de résoudre la plupart des problèmes de connectivité des conteneurs.

Sommaire

Dans ce laboratoire, vous avez appris à tester et à résoudre les problèmes de connectivité entre les conteneurs Docker. Vous avez :

  • Créé des conteneurs Docker et configuré leur réseau
  • Appris les bases des réseaux Docker, y compris les réseaux par défaut et personnalisés
  • Utilisé divers outils pour tester la connectivité de base entre les conteneurs (ping, curl, netcat)
  • Exploré les problèmes de connectivité courants et appris des approches systématiques de dépannage

Ces compétences sont essentielles pour développer et maintenir des applications basées sur Docker, en particulier dans les architectures de microservices où plusieurs conteneurs doivent communiquer entre eux.

Pour approfondir vos connaissances, vous pouvez explorer Docker Compose pour les applications multi-conteneurs, Docker Swarm ou Kubernetes pour l'orchestration de conteneurs, et des concepts de réseau plus avancés tels que les réseaux de couche pour les déploiements multi-hôtes.