Les bases du réseau Docker

DockerBeginner
Pratiquer maintenant

Introduction

Dans cet atelier, nous allons explorer les fondamentaux de la mise en réseau avec Docker. Les réseaux Docker permettent aux conteneurs de communiquer entre eux et avec le monde extérieur. Nous aborderons les différents types de réseaux, la création de réseaux personnalisés, la connexion des conteneurs et la gestion des configurations réseau. Cette expérience pratique vous fournira une base solide sur les concepts et les usages du réseau Docker.

Comprendre les types de réseaux Docker

Docker propose plusieurs pilotes de réseau intégrés. Commençons par examiner les réseaux par défaut présents sur votre système.

Dans votre terminal, exécutez la commande suivante pour lister tous les réseaux Docker disponibles :

docker network ls

Cette commande affiche tous les réseaux que Docker a créés sur votre système. Vous devriez voir un résultat similaire à celui-ci :

NETWORK ID     NAME      DRIVER    SCOPE
79dce413aafd   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local

Analysons les types de réseaux par défaut :

  1. bridge : Il s'agit du pilote réseau par défaut. Lorsque vous lancez un conteneur sans spécifier de réseau, il se connecte automatiquement au réseau bridge. Les conteneurs situés sur le même réseau bridge peuvent communiquer entre eux via leurs adresses IP.

  2. host : Ce pilote supprime l'isolation réseau entre le conteneur et l'hôte Docker. Le conteneur partage l'espace de noms réseau de l'hôte, ce qui signifie qu'il utilise directement l'adresse IP et les ports de l'hôte. Cela peut être utile pour optimiser les performances dans certains scénarios spécifiques.

  3. none : Ce pilote désactive toute mise en réseau pour un conteneur. Les conteneurs utilisant ce type de réseau n'auront aucun accès aux réseaux externes ni aux autres conteneurs. C'est utile lorsque vous souhaitez isoler complètement un conteneur.

La colonne SCOPE indique si le réseau est limité à un seul hôte (local) ou s'il peut s'étendre sur plusieurs hôtes dans un cluster Docker Swarm (swarm).

Inspecter le réseau Bridge par défaut

Maintenant que nous avons vu la liste des réseaux, examinons de plus près le réseau bridge par défaut. Ce réseau est créé automatiquement par Docker et est utilisé par les conteneurs, sauf indication contraire.

Exécutez la commande suivante pour inspecter le réseau bridge :

docker network inspect bridge

Cette commande fournit des informations détaillées sur le réseau bridge, notamment son sous-réseau, sa passerelle et les conteneurs connectés. Vous verrez un résultat similaire à celui-ci (tronqué pour plus de clarté) :

[
  {
    "Name": "bridge",
    "Id": "79dce413aafdd7934fa3c1d0cc97decb823891ce406442b7d51be6126ef06a5e",
    "Created": "2024-08-22T09:58:39.747333789+08:00",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
      "Driver": "default",
      "Options": null,
      "Config": [
        {
          "Subnet": "172.17.0.0/16",
          "Gateway": "172.17.0.1"
        }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {},
    "Options": {
      "com.docker.network.bridge.default_bridge": "true",
      "com.docker.network.bridge.enable_icc": "true",
      "com.docker.network.bridge.enable_ip_masquerade": "true",
      "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
      "com.docker.network.bridge.name": "docker0",
      "com.docker.network.driver.mtu": "1500"
    },
    "Labels": {}
  }
]

Analysons quelques informations clés de ce résultat :

  • Subnet : Le sous-réseau utilisé par les conteneurs dans ce réseau est 172.17.0.0/16. Cela signifie que les conteneurs se verront attribuer des adresses IP dans cette plage.
  • Gateway : La passerelle de ce réseau est 172.17.0.1. C'est l'adresse IP que les conteneurs utilisent pour communiquer avec des réseaux extérieurs au leur.
  • Containers : Ce champ est vide car nous n'avons pas encore démarré de conteneurs.
  • Options : Il s'agit de diverses options de configuration pour le réseau bridge. Par exemple, enable_icc réglé sur "true" signifie que la communication inter-conteneurs (Inter-Container Communication) est autorisée sur ce réseau.

Comprendre ces informations est crucial pour résoudre des problèmes réseau ou lorsque vous devez configurer vos conteneurs pour communiquer avec des plages d'adresses IP spécifiques.

Créer un réseau Bridge personnalisé

Bien que le réseau bridge par défaut convienne à de nombreux cas d'utilisation, la création de réseaux personnalisés permet une meilleure isolation et un meilleur contrôle. Les réseaux personnalisés sont particulièrement utiles lorsque vous souhaitez regrouper des conteneurs liés entre eux ou lorsque vous devez contrôler quels conteneurs peuvent communiquer les uns avec les autres.

Créons un réseau bridge personnalisé nommé my-network :

docker network create --driver bridge my-network

Cette commande crée un nouveau réseau bridge. L'option --driver bridge est facultative ici car bridge est le pilote par défaut, mais elle est incluse pour plus de clarté.

Maintenant, vérifions que notre nouveau réseau a bien été créé :

docker network ls

Vous devriez voir my-network dans la liste des réseaux :

NETWORK ID     NAME         DRIVER    SCOPE
1191cb61c989   bridge       bridge    local
91199fc6ad2e   host         host      local
47ac4e684a72   my-network   bridge    local
1078d2c781b6   none         null      local

Notre nouveau réseau my-network apparaît dans la liste, confirmant qu'il a été créé avec succès. Ce réseau est désormais disponible pour que les conteneurs s'y connectent.

Connecter des conteneurs aux réseaux

Maintenant que nous avons notre réseau personnalisé, créons deux conteneurs et connectons-les à celui-ci. Nous utiliserons l'image nginx pour cet exemple, qui fournit un serveur web léger.

Exécutez les commandes suivantes pour créer deux conteneurs :

docker run -d --name container1 --network my-network nginx
docker run -d --name container2 --network my-network nginx

Analysons ces commandes :

  • -d : Ce drapeau lance le conteneur en mode détaché (detached), ce qui signifie qu'il s'exécute en arrière-plan.
  • --name : Cela attribue un nom à notre conteneur, ce qui facilite sa référence ultérieure.
  • --network : Cela spécifie le réseau auquel le conteneur doit se connecter.
  • nginx : C'est le nom de l'image que nous utilisons pour créer nos conteneurs.

Ces commandes créent deux conteneurs détachés nommés container1 et container2, tous deux connectés à notre réseau my-network.

Vérifions que les conteneurs sont en cours d'exécution et connectés à notre réseau :

docker ps

Cette commande liste tous les conteneurs en cours d'exécution. Vous devriez voir les deux conteneurs dans la liste :

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
1234567890ab   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds    80/tcp    container2
abcdef123456   nginx     "/docker-entrypoint.…"   20 seconds ago   Up 19 seconds   80/tcp    container1

Ce résultat montre que les deux conteneurs exécutent l'image Nginx et exposent le port 80 à l'intérieur du conteneur.

Tester la communication inter-conteneurs

L'un des principaux avantages du réseau Docker est que les conteneurs situés sur le même réseau peuvent communiquer entre eux en utilisant leurs noms de conteneur comme noms d'hôte. Cela facilite la mise en place de la communication entre services sans avoir besoin de connaître leurs adresses IP.

Testons cela en utilisant container1 pour envoyer une requête à container2 :

docker exec container1 curl -s container2

Analysons cette commande :

  • docker exec : Indique à Docker d'exécuter une commande à l'intérieur d'un conteneur en cours d'exécution.
  • container1 : C'est le nom du conteneur dans lequel nous voulons exécuter la commande.
  • curl -s container2 : C'est la commande que nous exécutons à l'intérieur du conteneur. Elle envoie une requête GET à container2 et le drapeau -s active le mode silencieux de curl.

Cette commande exécute la commande curl à l'intérieur de container1, envoyant une requête à container2. Vous devriez voir le code HTML de la page d'accueil par défaut de Nginx dans le résultat :

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    <style>
      html {
        color-scheme: light dark;
      }
      body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
      }
    </style>
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    <p>
      If you see this page, the nginx web server is successfully installed and
      working. Further configuration is required.
    </p>

    <p>
      For online documentation and support please refer to
      <a href="http://nginx.org/">nginx.org</a>.<br />
      Commercial support is available at
      <a href="http://nginx.com/">nginx.com</a>.
    </p>

    <p><em>Thank you for using nginx.</em></p>
  </body>
</html>

Cette réponse réussie démontre que container1 peut communiquer avec container2 en utilisant son nom de conteneur. Le serveur DNS intégré de Docker résout le nom du conteneur en son adresse IP au sein du réseau.

Exposer les ports des conteneurs

Par défaut, les conteneurs d'un réseau personnalisé peuvent communiquer entre eux, mais ils ne sont pas accessibles depuis l'extérieur de l'hôte Docker. Pour rendre un conteneur accessible depuis l'hôte ou des réseaux externes, nous devons exposer ses ports.

Créons un nouveau conteneur avec un port exposé :

docker run -d --name exposed-container -p 8080:80 --network my-network nginx

Analysons cette commande :

  • -d : Lance le conteneur en mode détaché.
  • --name exposed-container : Nomme le conteneur "exposed-container".
  • -p 8080:80 : Mappe le port 80 à l'intérieur du conteneur sur le port 8080 de l'hôte.
  • --network my-network : Connecte le conteneur à notre réseau personnalisé.
  • nginx : Utilise l'image Nginx.

Cette commande crée un nouveau conteneur nommé exposed-container, mappe le port 80 du conteneur sur le port 8080 de l'hôte et le connecte à notre réseau my-network.

Désormais, vous pouvez accéder au serveur Nginx de ce conteneur depuis votre machine hôte en ouvrant un navigateur web et en naviguant vers http://localhost:8080, ou en utilisant curl :

curl localhost:8080

Vous devriez voir le même code HTML de la page d'accueil Nginx que précédemment. Cette fois, cependant, nous accédons au conteneur directement depuis l'hôte, et non depuis un autre conteneur.

Utiliser le mode réseau Host

Pour les scénarios où vous souhaitez qu'un conteneur partage la pile réseau de l'hôte, vous pouvez utiliser le pilote réseau host. Cela supprime l'isolation réseau entre le conteneur et l'hôte, ce qui peut être utile pour certaines applications mais doit être utilisé avec précaution en raison des conflits de ports potentiels.

Créons un conteneur utilisant le réseau host :

docker run -d --name host-networked --network host nginx

Cette commande crée un nouveau conteneur nommé host-networked en utilisant le réseau de l'hôte. Notez que vous ne pouvez pas utiliser -p avec le mode host, car le conteneur utilise déjà directement les interfaces réseau de l'hôte.

Pour vérifier que le conteneur utilise le réseau host, nous pouvons inspecter ses paramètres réseau :

docker inspect --format '{{.HostConfig.NetworkMode}}' host-networked

Cette commande inspecte le conteneur et formate la sortie pour n'afficher que le NetworkMode. Elle devrait renvoyer host, confirmant que le conteneur utilise le réseau de l'hôte.

En utilisant le réseau host, le conteneur partage l'adresse IP de l'hôte et peut accéder directement à toutes les interfaces réseau de celui-ci. Cela peut être utile pour maximiser les performances, mais cela signifie également que tous les ports utilisés par le conteneur seront ouverts directement sur l'hôte, ce qui pourrait entraîner des conflits si vous n'y prenez pas garde.

Résumé

Dans cet atelier, nous avons exploré les fondamentaux du réseau Docker. Nous avons abordé les différents types de réseaux, la création de réseaux personnalisés, la connexion des conteneurs, le test de la communication inter-conteneurs, l'exposition des ports des conteneurs et l'utilisation du réseau host. Ces concepts constituent la base du réseau Docker et sont essentiels pour concevoir et gérer des applications conteneurisées.

Nous avons appris à :

  • Lister et inspecter les réseaux Docker
  • Créer des réseaux bridge personnalisés
  • Connecter des conteneurs à des réseaux
  • Tester la communication entre les conteneurs
  • Exposer les ports des conteneurs vers l'hôte
  • Utiliser le réseau host pour les conteneurs

La compréhension de ces concepts réseau vous aidera à concevoir des applications conteneurisées plus robustes et sécurisées. Au fur et à mesure que vous continuerez à travailler avec Docker, vous rencontrerez des scénarios réseau plus avancés, mais les principes que nous avons couverts ici serviront de base solide pour votre parcours dans l'orchestration de conteneurs et l'architecture de microservices.

N'oubliez pas que le réseau Docker est un outil puissant qui vous permet de créer des environnements isolés pour vos applications tout en permettant une communication contrôlée entre les conteneurs et avec le monde extérieur. Pratiquez ces concepts et explorez des sujets plus avancés pour devenir expert dans la gestion des réseaux Docker.