Réseaux Docker personnalisable

Résoudre un problème, mais lequel ?

Nous avons vu dans la leçon précédente, qu'un réseau est automatiquement créé lorsque l'on construit plusieurs conteneurs Docker sur notre machine locale.

Voyons maintenant comment rattacher les conteneurs à un réseau particulier précédemment créé (par nous-même ou par défaut par Docker).

Utiliser un conteneur personnalisé

Afin de ne pas constamment installer les programmes ping et ip lors de la création d'un nouveau conteneur ubuntu:18.04, nous en utiliserons un qui les contient déjà. Ce conteneur personnalisé est celtak/ubuntu-ping-ip.

C'est un conteneur Ubuntu avec ping et ip déjà installés.

Nous utiliserons désormais celui-ci.

Lister et rattacher des conteneurs à un réseau

Puisqu'il faut relier les conteneurs à un réseau déjà présent, commençons par vérifier la liste des réseaux présents.

Logiquement, étant donné que nous n'avons pas encore créé de réseau (principalement parce que nous ne savons pas le faire pour le moment, mais cela viendra plus tard 🙂), ceux qui apparaîtront, seront ceux créées au lancement de Docker lui-même.

Pour lister les réseaux, utiliser la commande suivante.

docker network ls

Et voici le résultat.

NETWORK ID     NAME      DRIVER    SCOPE
82c94c9f0d53   bridge    bridge    local
626ffa435a5e   host      host      local
c0e354978b8f   none      null      local

Les informations les plus importantes sont le nom du réseau et l'id de celui-ci.

On observe trois réseaux.

Un premier s'appelle bridge, il est celui par défaut et utiliser par Docker pour lier automatiquement les conteneurs entre eux.

Un autre dont le nom est none, isole un conteneur afin qu'il ne soit connecté un aucun réseau.

Enfin nous avons un réseau host. Nous ne parlerons pas de ce type de réseau. Mais si vous voulez en savoir plus à ce sujet, vous pouvez vous référer à la documentation.

Les types de réseaux sont appelés les pilotes.

Connecter manuellement des conteneurs

Pour connecter manuellement des conteneurs, il faut ajouter --network=....

Prenons un exemple. S'il vous plait, ne copiez pas la commande dans votre machine, car ce n'est qu'un exemple pour observer son agencement.

docker run --rm -it --network=bridge celtak/ubuntu-ping-ip

Nous allons maintenant, dans un premier temps, découvrir la solution qui nous permet d'isoler un conteneur du réseau.

Isoler un conteneur Docker du réseau

Pour atteindre cet objectif, nous allons recourir à none.

docker run --rm -it --network=none celtak/ubuntu-ping-ip

Faisons un test et tapons cette commande dans deux terminaux différents pour avoir deux conteneurs.

Maintenant, nous allons vérifier si les conteneurs sont bien isolés, l'un de l'autre (plus de connexion réseau). C'est normalement le cas puisque le pilote none a été utilisé.

Pour ce faire nous allons utiliser une commande que nous connaissons désormais très bien. Il faut la taper sur les deux terminaux.

ip -c a

Si vous avez utilisé le conteneur celtak/ubuntu-ping-ip, normalement ip devrait être disponible. Sinon il faudra l'installer aux deux conteneurs pour pouvoir s'en servir.

Que voyons-nous 🧐?

On s'aperçoit que les deux conteneurs ne sont pas relié par un réseau. Il n'y a pas d'adresse IP associé.

Pour être certain de cela, nous allons ouvrir une autre fenêtre dans notre terminal. Ensuite nous allons taper la même commande que précédemment, mais en omettant le paramètre --network=none. Par conséquent, Docker va attribuer un réseau automatiquement à notre conteneur.

docker run --rm -it celtak/ubuntu-ping-ip

Faisons un ip -c a et vérifions ce qui s'y passe. L'objectif sera de comparer les trois conteneurs (les deux sans réseaux et celui qui est connecté au réseau par défaut).

Trois conteneurs dont deux qui ne sont pas connectés à un réseau

On voit bien la différence 😁. Une adresse IP est attribué au troisième.

Créer un réseau personnalisé : bridge

On va le répéter encore une fois, mais ce n'est pas grave, car c'est important de le comprendre. Lorsque l'on crée des conteneurs sans attribuer de réseau, Docker va les relier automatiquement entre eux sur le réseau bridge par défaut.

Mais on peut en créer d'autres.

Pour bien comprendre cette possibilité puissante, nous allons pratiquer 😋.

L'objectif de cet exercice est de relier deux conteneurs à un réseau et deux autres à un autre réseau.

Créer un réseau

Voici la commande pour créer un réseau avec le pilote bridge dans Docker.

docker network create --driver=bridge fruits

L'option --driver=bridge permet de définir le type de réseau à créer. Et fruits est le nom de mon réseau personnalisé. Vous pouvez choisir n'importe quel nom.

Vérifions que le réseau a bien été créé.

docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
bef673564815   bridge    bridge    local
e6e59788d618   fruits    bridge    local
626ffa435a5e   host      host      local
c0e354978b8f   none      null      local

Ça fonctionne bien, car on voit bien le réseau fruits de type bridge.

On va en créer un autre.

docker network create --driver=bridge legumes
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
bef673564815   bridge    bridge    local
e6e59788d618   fruits    bridge    local
626ffa435a5e   host      host      local
3dd953cb0c35   legumes   bridge    local
c0e354978b8f   none      null      local

Relier des conteneurs au réseau

Nous avons deux réseaux personnalisés et c'est très bien. Maintenant nous allons connecter des conteneurs à ces réseaux.

Pour bien comprendre l'objectif de cet exercice, nous allons projeter un schéma.

Réseau fruits et réseau légume

Comme vous le voyez, nous allons créer quatre conteneurs et nous les nommerons ananas, pomme, oignon et poivron. Le fait de leur donner des noms, nous sera utile pour faire communiquer des conteneurs reliés entre eux. Ce n'est cependant pas obligatoire de les nommer.

Deux conteneurs seront reliés au réseau fruits.

Il existe deux façons de procéder :

  • Créer et connecter en même temps
  • Créer et ensuite connecter

Créer et connecter en même temps

Pour atteindre ce but, copier et coller la commande qui suit dans votre terminal.

docker run -it --rm --network=fruits --name=ananas celtak/ubuntu-ping-ip

Expliquons les options que nous ne sommes pas habitués à utiliser. L'option --network=fruits connecte le nouveau conteneur au réseau fruits. Et --name=ananas donne le nom ananas à notre conteneur.

Faisons la même chose avec un autre conteneur que nous allons appeler pomme.

docker run -it --rm --network=fruits --name=pomme celtak/ubuntu-ping-ip

Avec un docker ps (dans une autre fenêtre du terminal), vérifions que les deux conteneurs aient bien été créés.

CONTAINER ID   IMAGE                   COMMAND   CREATED          STATUS          PORTS     NAMES
bac1e082ff8a   celtak/ubuntu-ping-ip   "bash"    6 seconds ago    Up 5 seconds              pomme
bc33047e1359   celtak/ubuntu-ping-ip   "bash"    20 seconds ago   Up 19 seconds             ananas

On est bien 😉.

Voyons si la communication réseau passe bien entre ces deux conteneurs. Allez dans la fenêtre du terminal correspondant au conteneur ananas et tapez la commande suivante.

ping pomme

Cela fonctionne 😃 ! Vous avez vu la particularité. En nommant un conteneur, nous ne sommes pas obligés d'aller chercher l'IP pour communiquer. Nous pouvons directement recourir au nom du conteneur.

Utiliser ping ananas dans le conteneur pomme marchera également.

Créer et ensuite connecter

Créer un conteneur normalement, nous savons le faire. Créons les deux autres du schéma.

  • Oignon
  • Poivrons

Et dans un second temps, nous les connecterons au réseau légumes.

Commençons par les construire.

docker run --rm -it --name=oignon celtak/ubuntu-ping-ip
docker run --rm -it --name=poivron celtak/ubuntu-ping-ip
docker ps
CONTAINER ID   IMAGE                   COMMAND   CREATED          STATUS          PORTS     NAMES
51399d609fad   celtak/ubuntu-ping-ip   "bash"    4 seconds ago    Up 3 seconds              poivron
0de2c4bb6550   celtak/ubuntu-ping-ip   "bash"    33 seconds ago   Up 32 seconds             oignon
bac1e082ff8a   celtak/ubuntu-ping-ip   "bash"    18 minutes ago   Up 18 minutes             pomme
bc33047e1359   celtak/ubuntu-ping-ip   "bash"    18 minutes ago   Up 18 minutes             ananas

Voilà qui est fait.

Nous allons découvrir la commande qui permet de connecter des conteneurs à un réseau.

Faisons-le avec oignon.

docker network connect legumes oignon

La commande parle d'elle-même.

Continuons avec poivron.

docker network connect legumes poivron

Fait !

Voyons s'il est possible de faire communiquer oignon avec poivron!

Dans le terminal du conteneur oignon, tapez ce qui suit.

ping poivron

Ça marche 👍 ! L'inverse est également vrai.

Conteneurs qui ne sont pas dans le même réseau

Mais est-il possible de faire communiquer deux conteneurs qui ne sont pas dans le même réseau ?

Voyons cela !

Plaçons-nous dans pomme et tapons ping poivron. Ça ne fonctionne pas et c'est normal puisqu'il ne fait pas partie du même réseau. On aurait pu utiliser l'adresse IP et nous serions tombés sur le même résultat négatif.

Vérifier les conteneurs présents dans un réseau

Comment avoir la liste des conteneurs d'un réseau ?

Pour atteindre ce but, tapez la commande ci-dessous (nous testons avec le réseau fruits).

docker network inspect fruits

Le résultat nous retourne énormément d'informations sous forme d'un objet.

[
    {
        "Name": "fruits",
        "Id": "e6e59788d618621a2a083fcd7db586739c1183ad955a45ea47eeaaeec110ab51",
        "Created": "2021-08-30T13:25:50.6940171Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "bac1e082ff8aca9feb8b1152a4ff05377afa2d1180e192a50f496e1a432f11e7": {
                "Name": "pomme",
                "EndpointID": "3f12c35be20d5050f48e6a7dde9b18fe0a48d4d7c9b0f41cb3e348b684ce9c6a",
                "MacAddress": "02:42:ac:14:00:03",
                "IPv4Address": "172.20.0.3/16",
                "IPv6Address": ""
            },
            "bc33047e13597977b79d1782bc840be057dabf7832de4a7afda9a057ac43b2e1": {
                "Name": "ananas",
                "EndpointID": "e3b214aff177366b977d0ee1ee668f77202d91ac65dceff59dd7d6a4fc4d1c1e",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

Pour répondre à notre question, concentrons-nous sur la partie Containers.

 "Containers": {
            "bac1e082ff8aca9feb8b1152a4ff05377afa2d1180e192a50f496e1a432f11e7": {
                "Name": "pomme",
                "EndpointID": "3f12c35be20d5050f48e6a7dde9b18fe0a48d4d7c9b0f41cb3e348b684ce9c6a",
                "MacAddress": "02:42:ac:14:00:03",
                "IPv4Address": "172.20.0.3/16",
                "IPv6Address": ""
            },
            "bc33047e13597977b79d1782bc840be057dabf7832de4a7afda9a057ac43b2e1": {
                "Name": "ananas",
                "EndpointID": "e3b214aff177366b977d0ee1ee668f77202d91ac65dceff59dd7d6a4fc4d1c1e",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },

On y voit nos deux conteneurs poivron et ananas.

Déconnecter des conteneurs

Déconnecter des conteneurs dans Docker est très simple. Il vous suffit de recopier les commandes ci-dessous pour notre exercice.

docker network disconnect fruits ananas
docker network disconnect fruits pomme
docker network disconnect legumes oignon
docker network disconnect legumes poivron

Ainsi, tout est déconnecté et nous avons deux réseaux vides !

À noter que ni les conteneurs, ni les réseaux ne sont pas supprimés.

Supprimer un ou des réseaux dans Docker

Pour supprimer des réseaux, il faut en premier lieu sortir tous les conteneurs des différents réseaux. C'est ce que nous avons fait précédemment.

Maintenant nous pouvons les effacer.

docker network rm legumes fruits

Il existe d'autres types de réseaux

Dans cette leçon, nous avons abordé deux types de réseau :

  • none
  • bridge

Mais il en existe d'autres :

  • host
  • overlay
  • macvlan

Pour en savoir davantage sur ceux-ci, vous pouvez vous référer à la documentation officielle de Docker.