Exploration approfondie du réseau Docker

DockerBeginner
Pratiquer maintenant

Introduction

Dans cet atelier, nous allons explorer des concepts avancés de mise en réseau avec Docker, en nous appuyant sur les bases fondamentales. Nous approfondirons les trois principaux modes réseau : Bridge (Pont), Host (Hôte) et None (Aucun). Nous apprendrons également à créer des réseaux personnalisés, à connecter des conteneurs appartenant à des réseaux différents et à comprendre les implications de chaque mode sur la communication et l'isolation des conteneurs. Cette expérience pratique vous fournira une base solide pour gérer les réseaux Docker en conditions réelles.

Réseaux Bridge personnalisés

Bien que Docker fournisse un réseau bridge par défaut, la création de réseaux bridge personnalisés offre une meilleure isolation et un contrôle accru sur la communication entre les conteneurs.

  1. Tout d'abord, consultons la liste actuelle des réseaux Docker :
docker network ls

Vous devriez voir un résultat similaire à celui-ci :

NETWORK ID     NAME      DRIVER    SCOPE
296d1b460b17   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local
  1. Créons maintenant un réseau bridge personnalisé :
docker network create my-custom-bridge
  1. Listez à nouveau tous les réseaux Docker pour vérifier la création :
docker network ls

Vous devriez maintenant voir my-custom-bridge dans la liste :

NETWORK ID     NAME               DRIVER    SCOPE
296d1b460b17   bridge             bridge    local
91199fc6ad2e   host               host      local
7215f99d0080   my-custom-bridge   bridge    local
1078d2c781b6   none               null      local
  1. Lancez deux conteneurs sur ce réseau personnalisé et installez l'utilitaire ping :
docker run --network=my-custom-bridge --name container1 -d nginx
docker run --network=my-custom-bridge --name container2 -d nginx

Ensuite, installons l'utilitaire ping dans les deux conteneurs. Cette étape est nécessaire car l'image Nginx par défaut n'inclut pas cet outil :

docker exec container1 apt-get update && docker exec container1 apt-get install -y iputils-ping
docker exec container2 apt-get update && docker exec container2 apt-get install -y iputils-ping
  1. Testez la communication entre les conteneurs :
docker exec container1 ping -c 4 container2

Vous devriez obtenir des réponses positives, ce qui démontre que les conteneurs situés sur un même réseau bridge personnalisé peuvent communiquer en utilisant leurs noms. Cela fonctionne grâce au DNS intégré de Docker qui résout les noms de conteneurs en adresses IP au sein du même réseau.

Si les pings échouent, vérifiez que les deux conteneurs sont bien en cours d'exécution (docker ps) et que l'utilitaire ping a été correctement installé.

Connexion de conteneurs entre plusieurs réseaux

Docker permet de connecter un conteneur à plusieurs réseaux simultanément, facilitant ainsi la communication entre des conteneurs situés sur des réseaux distincts. C'est particulièrement utile pour isoler certains services tout en autorisant des flux spécifiques entre eux.

  1. Commençons par créer un second réseau bridge personnalisé :
docker network create my-second-bridge
  1. Vérifiez la création du réseau :
docker network ls

Vous devriez maintenant voir les deux réseaux personnalisés :

NETWORK ID     NAME               DRIVER    SCOPE
296d1b460b17   bridge             bridge    local
91199fc6ad2e   host               host      local
7215f99d0080   my-custom-bridge   bridge    local
8a15f99d0081   my-second-bridge   bridge    local
1078d2c781b6   none               null      local
  1. Connectez container2 au nouveau réseau :
docker network connect my-second-bridge container2

Cette commande ajoute container2 au réseau my-second-bridge tout en le maintenant connecté à my-custom-bridge.

  1. Créez un nouveau conteneur sur ce second réseau :
docker run --network=my-second-bridge --name container3 -d nginx
docker exec container3 apt-get update && docker exec container3 apt-get install -y iputils-ping
  1. Testez la communication entre tous les conteneurs :
docker exec container1 ping -c 2 container2
docker exec container1 ping -c 2 container3
docker exec container2 ping -c 2 container3

Observez les résultats :

  • container1 peut communiquer avec container2 (ils partagent un réseau commun).
  • container1 ne peut pas communiquer avec container3 (ils sont sur des réseaux totalement distincts).
  • container2 peut communiquer avec container1 ET container3 (il sert de pont car il est connecté aux deux réseaux).

Si container1 parvenait à joindre container3, cela signifierait qu'il y a un problème d'isolation dans votre configuration réseau.

Mode réseau Host

Le mode réseau Host supprime l'isolation réseau entre le conteneur et l'hôte Docker, permettant au conteneur d'utiliser directement la pile réseau de la machine hôte. Cela peut être utile pour maximiser les performances, mais comporte des risques de sécurité car l'isolation est réduite.

  1. Créez un conteneur utilisant le mode réseau host :
docker run --network host --name host-container -d nginx
  1. Vérifiez la liste actuelle des réseaux :
docker network ls

Vous ne verrez pas de nouveau réseau pour ce conteneur car il utilise directement celui de l'hôte.

  1. Confirmez que le conteneur utilise bien le mode host :
docker inspect --format '{{.HostConfig.NetworkMode}}' host-container

La commande devrait renvoyer host.

  1. Essayez d'accéder à la page par défaut de Nginx depuis votre machine hôte :
curl localhost:80

Vous devriez voir la page d'accueil de Nginx. Cela fonctionne car le conteneur utilise le réseau de l'hôte et Nginx écoute sur le port 80 de l'interface réseau de la machine physique.

Note : Si un service tourne déjà sur le port 80 de votre machine hôte, cette étape risque d'échouer. Dans ce cas, vous devrez d'abord arrêter le service existant.

Mode réseau None

Le mode réseau 'none' crée des conteneurs sans aucune interface réseau externe, les isolant totalement. C'est utile pour une sécurité maximale, mais cela signifie que le conteneur ne peut absolument pas communiquer via le réseau.

  1. Créez un conteneur sans réseau :
docker run --network none --name isolated-container -d alpine sleep infinity
  1. Vérifiez la liste des réseaux :
docker network ls

Aucun nouveau réseau n'apparaît pour ce conteneur puisqu'il n'est connecté à rien.

  1. Vérifiez que le conteneur n'a pas d'interface réseau :
docker exec isolated-container ip addr

Vous ne devriez voir que l'interface de bouclage local (lo). Il n'y aura pas d'interface eth0 ou autre.

  1. Tentez de joindre Google depuis ce conteneur isolé :
docker exec isolated-container ping -c 2 google.com

Cela devrait échouer avec une erreur de type "Network is unreachable" (Réseau inaccessible), confirmant l'absence d'accès réseau.

Alias réseau et découverte de services

Les réseaux Docker prennent en charge la découverte de services via des alias réseau, ce qui est essentiel pour créer des applications résilientes et évolutives. Cette fonctionnalité permet à plusieurs conteneurs de répondre au même nom DNS, offrant ainsi un équilibrage de charge basique.

  1. Créez un nouveau réseau bridge pour cet exercice :
docker network create service-network
  1. Vérifiez la création du réseau :
docker network ls

Vous devriez voir service-network dans la liste.

  1. Créez deux conteneurs avec le même alias réseau :
docker run -d --network service-network --network-alias myservice --name service1 nginx
docker run -d --network service-network --network-alias myservice --name service2 nginx
  1. Créez un conteneur client et utilisez nslookup pour résoudre le service :
docker run --rm --network service-network appropriate/curl nslookup myservice

Vous devriez voir les adresses IP des deux conteneurs s'afficher, prouvant que le serveur DNS intégré de Docker répartit les requêtes entre les deux conteneurs.

  1. Testez l'accès au service plusieurs fois :
for i in {1..4}; do docker run --rm --network service-network appropriate/curl ping -c 1 myservice; done

Vous devriez voir des réponses provenant alternativement des deux conteneurs. Le serveur DNS de Docker alterne entre les deux adresses IP lors de la résolution de myservice.

PING myservice (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.106 ms

--- myservice ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.106/0.106/0.106 ms
PING myservice (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.119 ms

--- myservice ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.119/0.119/0.119 ms
PING myservice (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.097 ms

--- myservice ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.097/0.097/0.097 ms
PING myservice (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.140 ms

--- myservice ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.140/0.140/0.140 ms

Résumé

Dans cet atelier avancé sur le réseau Docker, nous avons exploré plusieurs concepts clés :

  1. Les réseaux bridge personnalisés pour une meilleure isolation et communication entre conteneurs.
  2. La connexion de conteneurs à plusieurs réseaux simultanément.
  3. Le mode réseau Host pour un accès direct à la pile réseau de l'hôte.
  4. Le mode réseau None pour une isolation réseau totale.
  5. Les alias réseau et la découverte de services pour concevoir des applications scalables.

Ces fonctionnalités réseau avancées de Docker sont des outils puissants pour concevoir des applications multi-conteneurs complexes avec un contrôle précis sur les flux et l'isolation. La maîtrise de ces concepts est cruciale pour déployer des architectures conteneurisées efficaces, sécurisées et évolutives.

N'oubliez pas que si la flexibilité du réseau Docker est immense, il est primordial de considérer les enjeux de sécurité lors de la conception de votre architecture. Appliquez toujours le principe du moindre privilège en n'exposant que les ports et services strictement nécessaires.

Au fur et à mesure de votre progression avec Docker, ces notions de réseau deviendront indispensables pour orchestrer des microservices. Pratiquez-les régulièrement pour devenir expert dans la gestion des réseaux Docker.