Mise en réseau avec des conteneurs autonomes
Cette série de tutoriels traite de la mise en réseau pour les conteneurs Docker autonomes. Pour la mise en réseau avec les services swarm, voir Mise en réseau avec les services swarm. Si vous devez en apprendre davantage sur la mise en réseau Docker en général, voir la vue d'ensemble.
Ce sujet inclut deux tutoriels différents. 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 bridge par défaut démontre comment utiliser le réseau
bridge
par défaut que Docker configure pour vous automatiquement. Ce réseau n'est pas le meilleur choix pour les systèmes de production. -
Utiliser des réseaux bridge définis par l'utilisateur montre comment créer et utiliser vos propres réseaux bridge personnalisés, pour connecter des conteneurs s'exécutant sur le même hôte Docker. Ceci est recommandé pour les conteneurs autonomes s'exécutant en production.
Bien que les réseaux overlay soient généralement utilisés pour les services swarm, vous pouvez aussi utiliser un réseau overlay pour des conteneurs autonomes. Cela est couvert dans le cadre du tutoriel sur l'utilisation des réseaux overlay.
Utiliser le réseau bridge par défaut
Dans cet exemple, vous démarrez deux conteneurs alpine
différents sur le même hôte Docker
et faites quelques tests pour comprendre comment ils communiquent entre eux. Vous devez
avoir Docker installé et en cours d'exécution.
-
Ouvrez une fenêtre de terminal. Listez les réseaux actuels avant de faire quoi que ce soit d'autre. Voici ce que vous devriez voir si vous n'avez jamais ajouté de réseau ou initialisé un swarm sur ce démon Docker. Vous pourriez voir différents réseaux, mais vous devriez au moins voir ceux-ci (les ID de réseau seront différents) :
$ docker network ls NETWORK ID NAME DRIVER SCOPE 17e324f45964 bridge bridge local 6ed54d316334 host host local 7092879f2cc8 none null local
Le réseau
bridge
par défaut est listé, avechost
etnone
. Les deux derniers ne sont pas des réseaux à part entière, mais sont utilisés pour démarrer un conteneur connecté directement à la pile réseau de l'hôte du démon Docker, ou pour démarrer un conteneur sans périphériques réseau. Ce tutoriel connectera deux conteneurs au réseaubridge
. -
Démarrez deux conteneurs
alpine
exécutantash
, qui est le shell par défaut d'Alpine plutôt quebash
. Les drapeaux-dit
signifient démarrer le conteneur détaché (en arrière-plan), interactif (avec la capacité de taper dedans), et avec un TTY (pour que vous puissiez voir l'entrée et la sortie). Puisque vous le démarrez détaché, vous ne serez pas connecté au conteneur immédiatement. Au lieu de cela, l'ID du conteneur sera affiché. Parce que vous n'avez spécifié aucun drapeau--network
, les conteneurs se connectent au réseaubridge
par défaut.$ docker run -dit --name alpine1 alpine ash $ docker run -dit --name alpine2 alpine ash
Vérifiez que les deux conteneurs sont bien démarrés :
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 602dbf1edc81 alpine "ash" 4 seconds ago Up 3 seconds alpine2 da33b7aa74b0 alpine "ash" 17 seconds ago Up 16 seconds alpine1
-
Inspectez le réseau
bridge
pour voir quels conteneurs y sont connectés.$ docker network inspect bridge [ { "Name": "bridge", "Id": "17e324f459648a9baaea32b248d3884da102dde19396c25b30ec800068ce6b10", "Created": "2017-06-22T20:27:43.826654485Z", "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, "Containers": { "602dbf1edc81813304b6cf0a647e65333dc6fe6ee6ed572dc0f686a3307c6a2c": { "Name": "alpine2", "EndpointID": "03b6aafb7ca4d7e531e292901b43719c0e34cc7eef565b38a6bf84acf50f38cd", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "da33b7aa74b0bf3bda3ebd502d404320ca112a268aafe05b4851d1e3312ed168": { "Name": "alpine1", "EndpointID": "46c044a645d6afc42ddd7857d19e9dcfb89ad790afb5c239a35ac0af5e8a5bc5", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "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": {} } ]
Près du haut, les informations sur le réseau
bridge
sont listées, incluant l'adresse IP de la passerelle entre l'hôte Docker et le réseaubridge
(172.17.0.1
). Sous la cléContainers
, chaque conteneur connecté est listé, avec des informations sur son adresse IP (172.17.0.2
pouralpine1
et172.17.0.3
pouralpine2
). -
Les conteneurs s'exécutent en arrière-plan. Utilisez la commande
docker attach
pour vous connecter àalpine1
.$ docker attach alpine1 / #
L'invite change en
#
pour indiquer que vous êtes l'utilisateurroot
dans le conteneur. Utilisez la commandeip addr show
pour montrer les interfaces réseau pouralpine1
telles qu'elles apparaissent depuis l'intérieur du conteneur :# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 27: eth0@if28: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link valid_lft forever preferred_lft forever
La première interface est le périphérique de bouclage. Ignorez-le pour l'instant. Remarquez que la seconde interface a l'adresse IP
172.17.0.2
, qui est la même adresse montrée pouralpine1
dans l'étape précédente. -
Depuis
alpine1
, assurez-vous que vous pouvez vous connecter à internet en pingantgoogle.com
. Le drapeau-c 2
limite la commande à deux tentatives deping
.# ping -c 2 google.com PING google.com (172.217.3.174): 56 data bytes 64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.841 ms 64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.897 ms --- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.841/9.869/9.897 ms
-
Maintenant essayez de pinguer le second conteneur. D'abord, pinguez-le par son adresse IP,
172.17.0.3
:# ping -c 2 172.17.0.3 PING 172.17.0.3 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.086 ms 64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.094 ms --- 172.17.0.3 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.086/0.090/0.094 ms
Cela réussit. Ensuite, essayez de pinguer le conteneur
alpine2
par son nom de conteneur. Cela échouera.# ping -c 2 alpine2 ping: bad address 'alpine2'
-
Détachez-vous de
alpine1
sans l'arrêter en utilisant la séquence de détachement,CTRL
+p
CTRL
+q
(appuyez surCTRL
et tapezp
suivi deq
). Si vous le souhaitez, attachez-vous àalpine2
et répétez les étapes 4, 5 et 6 là, en substituantalpine1
àalpine2
. -
Arrêtez et supprimez les deux conteneurs.
$ docker container stop alpine1 alpine2 $ docker container rm alpine1 alpine2
Rappelez-vous, le réseau bridge
par défaut n'est pas recommandé pour la production. Pour
en savoir plus sur les réseaux bridge définis par l'utilisateur, continuez avec le
tutoriel suivant.
Utiliser des réseaux bridge définis par l'utilisateur
Dans cet exemple, nous démarrons à nouveau deux conteneurs alpine
, mais nous les attachons à un
réseau bridge utilisateur appelé alpine-net
que nous avons déjà créé. Ces
conteneurs ne sont connectés à aucun réseau bridge
par défaut. Nous démarrons ensuite un troisième
conteneur alpine
qui est connecté au réseau bridge
mais
pas connecté à alpine-net
, et un quatrième conteneur alpine
qui est
connecté à les deux.
-
Créez le réseau
alpine-net
. Vous n'avez pas besoin du drapeau--driver bridge
puisqu'il est le défaut, mais cet exemple montre comment le spécifier.$ docker network create --driver bridge alpine-net
-
Listez les réseaux Docker :
$ docker network ls NETWORK ID NAME DRIVER SCOPE e9261a8c9a19 alpine-net bridge local 17e324f45964 bridge bridge local 6ed54d316334 host host local 7092879f2cc8 none null local
Inspectez le réseau
alpine-net
. Cela vous montre son adresse IP et le fait qu'aucun conteneur n'est connecté à lui :$ docker network inspect alpine-net [ { "Name": "alpine-net", "Id": "e9261a8c9a19eabf2bf1488bf5f208b99b1608f330cff585c273d39481c9b0ec", "Created": "2017-09-25T21:38:12.620046142Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Containers": {}, "Options": {}, "Labels": {} } ]
Remarquez que ce réseau's passerelle est
172.18.0.1
, contrairement au réseaubridge
par défaut, dont la passerelle est172.17.0.1
. L'adresse IP exacte peut être différent sur votre système. -
Créez vos quatre conteneurs. Remarquez les drapeaux
--network
. Vous ne pouvez connecter qu'à un réseau pendant la commandedocker run
, donc vous devez utiliserdocker network connect
ensuite pour connecteralpine4
au réseaubridge
aussi.$ docker run -dit --name alpine1 --network alpine-net alpine ash $ docker run -dit --name alpine2 --network alpine-net alpine ash $ docker run -dit --name alpine3 alpine ash $ docker run -dit --name alpine4 --network alpine-net alpine ash $ docker network connect bridge alpine4
Vérifiez que tous les conteneurs sont en cours d'exécution :
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 156849ccd902 alpine "ash" 41 seconds ago Up 41 seconds alpine4 fa1340b8d83e alpine "ash" 51 seconds ago Up 51 seconds alpine3 a535d969081e alpine "ash" About a minute ago Up About a minute alpine2 0a02c449a6e9 alpine "ash" About a minute ago Up About a minute alpine1
-
Inspectez le réseau
bridge
et le réseaualpine-net
à nouveau :$ docker network inspect bridge [ { "Name": "bridge", "Id": "17e324f459648a9baaea32b248d3884da102dde19396c25b30ec800068ce6b10", "Created": "2017-06-22T20:27:43.826654485Z", "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, "Containers": { "156849ccd902b812b7d17f05d2d81532ccebe5bf788c9a79de63e12bb92fc621": { "Name": "alpine4", "EndpointID": "7277c5183f0da5148b33d05f329371fce7befc5282d2619cfb23690b2adf467d", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "fa1340b8d83eef5497166951184ad3691eb48678a3664608ec448a687b047c53": { "Name": "alpine3", "EndpointID": "5ae767367dcbebc712c02d49556285e888819d4da6b69d88cd1b0d52a83af95f", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "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": {} } ]
Les conteneurs
alpine3
etalpine4
sont connectés au réseaubridge
.$ docker network inspect alpine-net [ { "Name": "alpine-net", "Id": "e9261a8c9a19eabf2bf1488bf5f208b99b1608f330cff585c273d39481c9b0ec", "Created": "2017-09-25T21:38:12.620046142Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Containers": { "0a02c449a6e9a15113c51ab2681d72749548fb9f78fae4493e3b2e4e74199c4a": { "Name": "alpine1", "EndpointID": "c83621678eff9628f4e2d52baf82c49f974c36c05cba152db4c131e8e7a64673", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }, "156849ccd902b812b7d17f05d2d81532ccebe5bf788c9a79de63e12bb92fc621": { "Name": "alpine4", "EndpointID": "058bc6a5e9272b532ef9a6ea6d7f3db4c37527ae2625d1cd1421580fd0731954", "MacAddress": "02:42:ac:12:00:04", "IPv4Address": "172.18.0.4/16", "IPv6Address": "" }, "a535d969081e003a149be8917631215616d9401edcb4d35d53f00e75ea1db653": { "Name": "alpine2", "EndpointID": "198f3141ccf2e7dba67bce358d7b71a07c5488e3867d8b7ad55a4c695ebb8740", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
Les conteneurs
alpine1
,alpine2
, etalpine4
sont connectés au réseaualpine-net
. -
Sur les réseaux bridge utilisateur comme
alpine-net
, les conteneurs peuvent ne communiquer que par adresse IP, mais peuvent aussi résoudre le nom d'un conteneur en adresse IP. Cette capacité est appelée découverte de service automatique. Connectons-nous àalpine1
et testons cela.alpine1
devrait être en mesure de résoudrealpine2
etalpine4
(etalpine1
, lui-même) en adresses IP.NoteLa découverte de service automatique ne peut résoudre que les noms de conteneur personnalisés, pas les noms de conteneur par défaut automatiquement générés,
$ docker container attach alpine1 # ping -c 2 alpine2 PING alpine2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.085 ms 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.090 ms --- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.085/0.087/0.090 ms # ping -c 2 alpine4 PING alpine4 (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.076 ms 64 bytes from 172.18.0.4: seq=1 ttl=64 time=0.091 ms --- alpine4 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.076/0.083/0.091 ms # ping -c 2 alpine1 PING alpine1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.026 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.054 ms --- alpine1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.026/0.040/0.054 ms
-
De
alpine1
, vous ne devriez pas être en mesure de vous connecter àalpine3
du tout, puisqu'il n'est pas sur le réseaualpine-net
.# ping -c 2 alpine3 ping: bad address 'alpine3'
Pas seulement cela, mais vous ne pouvez pas vous connecter à
alpine3
dealpine1
par son adresse IP non plus. Regardez en arrière la sortiedocker network inspect
pour le réseaubridge
et trouvez l'adresse IP dealpine3
:172.17.0.2
Essayez de le pinguer.# ping -c 2 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes --- 172.17.0.2 ping statistics --- 2 packets transmitted, 0 packets received, 100% packet loss
Détachez-vous de
alpine1
en utilisant la séquence de détachement,CTRL
+p
CTRL
+q
(appuyez surCTRL
et tapezp
suivi deq
). -
Rappelez-vous que
alpine4
est connecté à les deux réseauxbridge
etalpine-net
. Il devrait être en mesure de atteindre tous les autres conteneurs. Cependant, vous devrez adresseralpine3
par son adresse IP. Attachez-vous à lui et exécutez les tests.$ docker container attach alpine4 # ping -c 2 alpine1 PING alpine1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.074 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.082 ms --- alpine1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.074/0.078/0.082 ms # ping -c 2 alpine2 PING alpine2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.075 ms 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.080 ms --- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.075/0.077/0.080 ms # ping -c 2 alpine3 ping: bad address 'alpine3' # ping -c 2 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.089 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms --- 172.17.0.2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.075/0.082/0.089 ms # ping -c 2 alpine4 PING alpine4 (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.033 ms 64 bytes from 172.18.0.4: seq=1 ttl=64 time=0.064 ms --- alpine4 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.033/0.048/0.064 ms
-
Comme test final, assurez-vous que vos conteneurs peuvent tous se connecter à internet en pinguant
google.com
. Vous êtes déjà attaché àalpine4
donc commencez par essayer de le faire partir de là. Ensuite, détachez-vous dealpine4
et connectez-vous àalpine3
(qui n'est attaché qu'au réseaubridge
) et essayez à nouveau. Enfin, connectez-vous àalpine1
(qui n'est connecté qu'au réseaualpine-net
) et essayez à nouveau.# ping -c 2 google.com PING google.com (172.217.3.174): 56 data bytes 64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.778 ms 64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.634 ms --- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.634/9.706/9.778 ms CTRL+p CTRL+q $ docker container attach alpine3 # ping -c 2 google.com PING google.com (172.217.3.174): 56 data bytes 64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.706 ms 64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.851 ms --- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.706/9.778/9.851 ms CTRL+p CTRL+q $ docker container attach alpine1 # ping -c 2 google.com PING google.com (172.217.3.174): 56 data bytes 64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.606 ms 64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.603 ms --- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.603/9.604/9.606 ms CTRL+p CTRL+q
-
Arrêtez et supprimez tous les conteneurs et le réseau
alpine-net
.$ docker container stop alpine1 alpine2 alpine3 alpine4 $ docker container rm alpine1 alpine2 alpine3 alpine4 $ docker network rm alpine-net