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).
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.
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.