Mise en réseau avec les réseaux overlay
Cette série de tutoriels traite de la mise en réseau pour les services swarm. Pour la mise en réseau avec des conteneurs autonomes, voir Mise en réseau avec des conteneurs autonomes. Si vous devez en apprendre davantage sur la mise en réseau Docker en général, voir la vue d'ensemble.
Cette page inclut les tutoriels suivants. Vous pouvez exécuter chacun d'eux sur Linux, Windows, ou un Mac, mais pour le dernier, vous avez besoin d'un second hôte Docker s'exécutant ailleurs.
-
Utiliser le réseau overlay par défaut démontre comment utiliser le réseau overlay par défaut que Docker configure pour vous automatiquement quand vous initialisez ou rejoignez un swarm. Ce réseau n'est pas le meilleur choix pour les systèmes de production.
-
Utiliser des réseaux overlay définis par l'utilisateur montre comment créer et utiliser vos propres réseaux overlay personnalisés, pour connecter des services. Ceci est recommandé pour les services s'exécutant en production.
-
Utiliser un réseau overlay pour des conteneurs autonomes montre comment communiquer entre des conteneurs autonomes sur différents démons Docker en utilisant un réseau overlay.
Prérequis
Ceux-ci nécessitent que vous ayez au moins un swarm à nœud unique, ce qui signifie que
vous avez démarré Docker et exécuté docker swarm init
sur l'hôte. Vous pouvez exécuter
les exemples sur un swarm multi-nœuds également.
Utiliser le réseau overlay par défaut
Dans cet exemple, vous démarrez un service alpine
et examinez les caractéristiques
du réseau du point de vue des conteneurs de service individuels.
Ce tutoriel n'entre pas dans les détails spécifiques au système d'exploitation sur comment les réseaux overlay sont implémentés, mais se concentre sur comment l'overlay fonctionne du point de vue d'un service.
Prérequis
Ce tutoriel nécessite trois hôtes Docker physiques ou virtuels qui peuvent tous communiquer entre eux. Ce tutoriel suppose que les trois hôtes s'exécutent sur le même réseau sans pare-feu impliqué.
Ces hôtes seront appelés manager
, worker-1
, et worker-2
. L'hôte
manager
fonctionnera à la fois comme un gestionnaire et un travailleur, ce qui signifie qu'il peut
à la fois exécuter des tâches de service et gérer le swarm. worker-1
et worker-2
fonctionneront
comme travailleurs seulement.
Si vous n'avez pas trois hôtes à portée de main, une solution facile est de configurer trois hôtes Ubuntu sur un fournisseur cloud tel qu'Amazon EC2, tous sur le même réseau avec toutes les communications autorisées vers tous les hôtes sur ce réseau (en utilisant un mécanisme tel que les groupes de sécurité EC2), puis de suivre les instructions d'installation pour Docker Engine - Community sur Ubuntu.
Procédure
Créer le swarm
À la fin de cette procédure, les trois hôtes Docker seront joints au swarm
et seront connectés ensemble en utilisant un réseau overlay appelé ingress
.
-
Sur
manager
, initialisez le swarm. Si l'hôte n'a qu'une seule interface réseau, le drapeau--advertise-addr
est optionnel.$ docker swarm init --advertise-addr=<IP-ADDRESS-OF-MANAGER>
Prenez note du texte qui est affiché, car cela contient le token que vous utiliserez pour joindre
worker-1
etworker-2
au swarm. C'est une bonne idée de stocker le token dans un gestionnaire de mots de passe. -
Sur
worker-1
, rejoignez le swarm. Si l'hôte n'a qu'une seule interface réseau, le drapeau--advertise-addr
est optionnel.$ docker swarm join --token <TOKEN> \ --advertise-addr <IP-ADDRESS-OF-WORKER-1> \ <IP-ADDRESS-OF-MANAGER>:2377
-
Sur
worker-2
, rejoignez le swarm. Si l'hôte n'a qu'une seule interface réseau, le drapeau--advertise-addr
est optionnel.$ docker swarm join --token <TOKEN> \ --advertise-addr <IP-ADDRESS-OF-WORKER-2> \ <IP-ADDRESS-OF-MANAGER>:2377
-
Sur
manager
, listez tous les nœuds. Cette commande ne peut être exécutée que depuis un gestionnaire.$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS d68ace5iraw6whp7llvgjpu48 * ip-172-31-34-146 Ready Active Leader nvp5rwavvb8lhdggo8fcf7plg ip-172-31-35-151 Ready Active ouvx2l7qfcxisoyms8mtkgahw ip-172-31-36-89 Ready Active
Vous pouvez aussi utiliser le drapeau
--filter
pour filtrer par rôle :$ docker node ls --filter role=manager ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS d68ace5iraw6whp7llvgjpu48 * ip-172-31-34-146 Ready Active Leader $ docker node ls --filter role=worker ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS nvp5rwavvb8lhdggo8fcf7plg ip-172-31-35-151 Ready Active ouvx2l7qfcxisoyms8mtkgahw ip-172-31-36-89 Ready Active
-
Listez les réseaux Docker sur
manager
,worker-1
, etworker-2
et remarquez que chacun d'eux a maintenant un réseau overlay appeléingress
et un réseau bridge appelédocker_gwbridge
. Seule la liste pourmanager
est montrée ici :$ docker network ls NETWORK ID NAME DRIVER SCOPE 495c570066be bridge bridge local 961c6cae9945 docker_gwbridge bridge local ff35ceda3643 host host local trtnl4tqnc3n ingress overlay swarm c8357deec9cb none null local
Le docker_gwbridge
connecte le réseau ingress
à l'interface réseau de l'hôte Docker
afin que le trafic puisse circuler vers et depuis les gestionnaires et
travailleurs du swarm. Si vous créez des services swarm et ne spécifiez pas de réseau, ils sont
connectés au réseau ingress
. Il est recommandé d'utiliser des
réseaux overlay séparés pour chaque application ou groupe d'applications qui travailleront
ensemble. Dans la prochaine procédure, vous créerez deux réseaux overlay et
connecterez un service à chacun d'eux.
Créer les services
-
Sur
manager
, créez un nouveau réseau overlay appelénginx-net
:$ docker network create -d overlay nginx-net
Vous n'avez pas besoin de créer le réseau overlay sur les autres nœuds, car il sera automatiquement créé quand un de ces nœuds commencera à exécuter une tâche de service qui en a besoin.
-
Sur
manager
, créez un service Nginx à 5 répliques connecté ànginx-net
. Le service publiera le port 80 vers le monde extérieur. Tous les conteneurs de tâches de service peuvent communiquer entre eux sans ouvrir aucun port.NoteLes services ne peuvent être créés que sur un gestionnaire.
$ docker service create \ --name my-nginx \ --publish target=80,published=80 \ --replicas=5 \ --network nginx-net \ nginx
Le mode de publication par défaut
ingress
, qui est utilisé quand vous ne spécifiez pas demode
pour le drapeau--publish
, signifie que si vous naviguez vers le port 80 surmanager
,worker-1
, ouworker-2
, vous serez connecté au port 80 sur une des 5 tâches de service, même si aucune tâche n'est actuellement en cours d'exécution sur le nœud vers lequel vous naviguez. Si vous voulez publier le port en utilisant le modehost
, vous pouvez ajoutermode=host
à la sortie--publish
. Cependant, vous devriez aussi utiliser--mode global
au lieu de--replicas=5
dans ce cas, car seulement une tâche de service peut lier un port donné sur un nœud donné. -
Exécutez
docker service ls
pour surveiller les progrès du démarrage du service, qui peut prendre quelques secondes. -
Inspectez le réseau
nginx-net
surmanager
,worker-1
, etworker-2
. Rappelez-vous que vous n'avez pas eu besoin de le créer manuellement surworker-1
etworker-2
car Docker l'a créé pour vous. La sortie sera longue, mais remarquez les sectionsContainers
etPeers
.Containers
liste toutes les tâches de service (ou conteneurs autonomes) connectées au réseau overlay depuis cet hôte. -
Depuis
manager
, inspectez le service en utilisantdocker service inspect my-nginx
et remarquez les informations sur les ports et les points de terminaison utilisés par le service. -
Créez un nouveau réseau
nginx-net-2
, puis mettez à jour le service pour utiliser ce réseau à la place denginx-net
:$ docker network create -d overlay nginx-net-2
$ docker service update \ --network-add nginx-net-2 \ --network-rm nginx-net \ my-nginx
-
Exécutez
docker service ls
pour vérifier que le service a été mis à jour et que toutes les tâches ont été redéployées. Exécutezdocker network inspect nginx-net
pour vérifier qu'aucun conteneur n'est connecté à lui. Exécutez la même commande pournginx-net-2
et remarquez que tous les conteneurs de tâches de service sont connectés à lui.NoteMême si les réseaux overlay sont automatiquement créés sur les nœuds de travailleur swarm comme nécessaire, ils ne sont pas automatiquement supprimés.
-
Nettoyez le service et les réseaux. Depuis
manager
, exécutez les commandes suivantes. Le gestionnaire dirigera les travailleurs pour supprimer les réseaux automatiquement.$ docker service rm my-nginx $ docker network rm nginx-net nginx-net-2
Utiliser des réseaux overlay définis par l'utilisateur
Prérequis
Ce tutoriel suppose que le swarm est déjà configuré et que vous êtes sur un gestionnaire.
Procédure
-
Créez le réseau overlay défini par l'utilisateur.
$ docker network create -d overlay my-overlay
-
Démarrez un service en utilisant le réseau overlay et publiez le port 80 vers le port 8080 sur l'hôte Docker.
$ docker service create \ --name my-nginx \ --network my-overlay \ --replicas 1 \ --publish published=8080,target=80 \ nginx:latest
-
Exécutez
docker network inspect my-overlay
et vérifiez que le service de tâchemy-nginx
est connecté à lui, en regardant la sectionContainers
. -
Supprimez le service et le réseau.
$ docker service rm my-nginx $ docker network rm my-overlay
Utiliser un réseau overlay pour des conteneurs autonomes
Cet exemple montre la découverte de conteneur DNS -- spécifiquement, comment communiquer entre des conteneurs autonomes sur différents démons Docker en utilisant un réseau overlay. Les étapes sont :
- Sur
host1
, initialisez le nœud comme swarm (gestionnaire). - Sur
host2
, rejoignez le nœud au swarm (travailleur). - Sur
host1
, créez un réseau overlay attachable (test-net
). - Sur
host1
, exécutez un conteneur interactif alpine (alpine1
) surtest-net
. - Sur
host2
, exécutez un conteneur interactif et détaché alpine (alpine2
) surtest-net
. - Sur
host1
, depuis une session dealpine1
, pingalpine2
.
Prérequis
Pour ce test, vous avez besoin de deux hôtes Docker différents qui peuvent communiquer entre eux. Chaque hôte doit avoir les ports suivants ouverts entre les deux hôtes Docker :
- Port TCP 2377
- Port TCP et UDP 7946
- Port UDP 4789
Une façon facile de configurer cela est d'avoir deux VMs (soit locales ou sur une plateforme cloud comme AWS), chacune avec Docker installé et en cours d'exécution. Si vous utilisez AWS ou une plateforme cloud similaire, la configuration la plus simple est d'utiliser un groupe de sécurité qui ouvre tous les ports entrants entre les deux hôtes et le port SSH à partir de l'adresse IP de votre client.
Cet exemple fait référence aux deux nœuds de notre swarm comme host1
et host2
. Cet exemple utilise également des hôtes Linux, mais les mêmes commandes fonctionnent sur Windows.
Procédure
-
Configurez le swarm.
a. Sur
host1
, initialisez un swarm (et si demandé, utilisez--advertise-addr
pour spécifier l'adresse IP pour l'interface qui communique avec les autres hôtes du swarm, par exemple, l'adresse IP privée sur AWS) :$ docker swarm init Swarm initialized: current node (vz1mm9am11qcmo979tlrlox42) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-5g90q48weqrtqryq4kj6ow0e8xm9wmv9o6vgqc5j320ymybd5c-8ex8j0bc40s6hgvy5ui5gl4gy 172.31.47.252:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
b. Sur
host2
, rejoignez le swarm comme indiqué ci-dessus :$ docker swarm join --token <your_token> <your_ip_address>:2377 This node joined a swarm as a worker.
Si le nœud ne parvient pas à rejoindre le swarm, la commande
docker swarm join
expire. Pour résoudre, exécutezdocker swarm leave --force
surhost2
, vérifiez vos paramètres de réseau et de pare-feu, et réessayez. -
Sur
host1
, créez un réseau overlay attachable appelétest-net
:$ docker network create --driver=overlay --attachable test-net uqsof8phj3ak0rq9k86zta6ht
Remarquez le NETWORK ID renvoyé -- vous le verrez à nouveau lorsque vous vous connecterez à lui depuis
host2
. -
Sur
host1
, démarrez un conteneur interactif (-it
) (alpine1
) qui se connecte àtest-net
:$ docker run -it --name alpine1 --network test-net alpine / #
-
Sur
host2
, listez les réseaux disponibles -- remarquez quetest-net
n'existe pas encore :$ docker network ls NETWORK ID NAME DRIVER SCOPE ec299350b504 bridge bridge local 66e77d0d0e9a docker_gwbridge bridge local 9f6ae26ccb82 host host local omvdxqrda80z ingress overlay swarm b65c952a4b2b none null local
-
Sur
host2
, démarrez un conteneur détaché (-d
) et interactif (-it
) (alpine2
) qui se connecte àtest-net
:$ docker run -dit --name alpine2 --network test-net alpine fb635f5ece59563e7b8b99556f816d24e6949a5f6a5b1fbd92ca244db17a4342
NoteLa découverte de conteneur DNS automatique ne fonctionne qu'avec des noms de conteneur uniques.
-
Sur
host2
, vérifiez quetest-net
a été créé (et a le même NETWORK ID quetest-net
surhost1
) :$ docker network ls NETWORK ID NAME DRIVER SCOPE ... uqsof8phj3ak test-net overlay swarm
-
Sur
host1
, pingalpine2
depuis le terminal interactif dealpine1
:/ # ping -c 2 alpine2 PING alpine2 (10.0.0.5): 56 data bytes 64 bytes from 10.0.0.5: seq=0 ttl=64 time=0.600 ms 64 bytes from 10.0.0.5: seq=1 ttl=64 time=0.555 ms --- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.555/0.577/0.600 ms
Les deux conteneurs communiquent avec le réseau overlay connectant les deux hôtes. Si vous exécutez un autre conteneur alpine sur
host2
qui n'est pas détaché, vous pouvez pingalpine1
dehost2
(et ici nous ajoutons l'option remove option pour nettoyer automatiquement le conteneur) :$ docker run -it --rm --name alpine3 --network test-net alpine / # ping -c 2 alpine1 / # exit
-
Sur
host1
, fermez la sessionalpine1
(ce qui arrête également le conteneur) :/ # exit
-
Nettoyez vos conteneurs et réseaux :
Vous devez arrêter et supprimer les conteneurs sur chaque hôte indépendamment car les démons Docker fonctionnent indépendamment et ces sont des conteneurs autonomes. Vous n'avez qu'à supprimer le réseau sur
host1
car lorsque vous arrêtezalpine2
surhost2
,test-net
disparaît.a. Sur
host2
, arrêtezalpine2
, vérifiez quetest-net
a été supprimé, puis supprimezalpine2
:$ docker container stop alpine2 $ docker network ls $ docker container rm alpine2
a. Sur
host1
, supprimezalpine1
ettest-net
:$ docker container rm alpine1 $ docker network rm test-net