Réseau par défaut dans Docker
Sur un hôte unique, tous les conteneurs Docker se connectent automatiquement à un pont virtuel appelé docker0, qui fournit une communication avec l'hôte. Par conséquent, les conteneurs sur le même hôte peuvent interagir entre eux et accéder aux réseaux externes sans configuration supplémentaier.
Liaison entre conteneurs avec --link
La commande docker run propose le paramètre --link pour établir une connexion directe entre conteneurs. La syntaxe est --link nom_cible:alias, où nom_cible désigne le conteneur cible et alias un identifiant local pour cette liaison.
Ce mécanisme crée un tunnel sécurisé qui évite d'exposer des ports sur l'hôte via -p ou -P. Docker injecte des variables d'environnement pour divulguer les informations de connexion et ajoute une entrée dans le fichier /etc/hosts du conteneur parent.
Pour attribuer un nom personnalisé à un conteneur, utilisez l'option --name lors de son lancement. Le nom doit être unique sur l'hôte. Vous pouvez vérifier les noms avec docker ps (colonne NAMES).
Exemple de liaison entre conteneurs
$ docker run -d --name serveur-web nginx
$ docker run -itd --name client-centos --link serveur-web:web-link centos
# Vérifier les conteneurs en cours d'exécution
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7d12a34c5e6 centos "/bin/bash" 5 seconds ago Up 4 seconds client-centos
e9a8b7c6d5f4 nginx "nginx -g 'daemon off" 25 seconds ago Up 24 seconds 80/tcp, 443/tcp serveur-web
# Obtenir les adresses IP des conteneurs
$ docker inspect --format "{{ .NetworkSettings.IPAddress }}" serveur-web
172.17.0.4
$ docker inspect --format "{{ .NetworkSettings.IPAddress }}" client-centos
172.17.0.5
# Vérifier les variables d'environnement dans le conteneur client
$ docker exec -it client-centos env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=b7d12a34c5e6
TERM=xterm
WEB_LINK_PORT=tcp://172.17.0.4:80
WEB_LINK_PORT_80_TCP=tcp://172.17.0.4:80
WEB_LINK_PORT_80_TCP_ADDR=172.17.0.4
WEB_LINK_PORT_80_TCP_PORT=80
WEB_LINK_PORT_80_TCP_PROTO=tcp
WEB_LINK_PORT_443_TCP=tcp://172.17.0.4:443
WEB_LINK_PORT_443_TCP_ADDR=172.17.0.4
WEB_LINK_PORT_443_TCP_PORT=443
WEB_LINK_PORT_443_TCP_PROTO=tcp
WEB_LINK_NAME=/client-centos/web-link
WEB_LINK_ENV_NGINX_VERSION=1.25.3-1~bookworm
HOME=/root
# Examen du fichier /etc/hosts dans chaque conteneur
$ docker exec -it serveur-web cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4 e9a8b7c6d5f4
$ docker exec -it client-centos cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4 web-link e9a8b7c6d5f4 serveur-web
172.17.0.5 b7d12a34c5e6
# Test de connectivité depuis le conteneur client
$ docker exec -it client-centos ping serveur-web
PING web-link (172.17.0.4) 56(84) bytes of data.
64 bytes from web-link (172.17.0.4): icmp_seq=1 ttl=64 time=0.342 ms
64 bytes from web-link (172.17.0.4): icmp_seq=2 ttl=64 time=0.153 ms
^C
--- web-link ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.153/0.247/0.342/0.094 ms
Accès au réseau externe et mappage de ports
Par défaut, les conteneurs peuvent communiquer avec le réseau externe, mais l'accès inverse n'est pas possible directement. Pour permettre la connexion depuis l'extérieur, il faut mapper des ports de l'hôte vers les ports du conteneur.
- L'option
-P(majuscule) affecte automatiquement un port hôte aléatoire à chaque port exposé par le conteneur. - L'option
-p(minuscule) permet de spécifier manuellement le mappage, au formathôte:conteneur. Elle peut être utilisée plusieurs fois pour plusieurs ports.
Exemple d'accès au réseau externe
Pour démontrer l'accès sortant depuis un conteneur :
# Lancer un conteneur et tester la connectivité externe
$ docker run -it --name client-test centos bash
$ ping -c 3 www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34: icmp_seq=1 ttl=56 time=25.3 ms
64 bytes from 93.184.216.34: icmp_seq=2 ttl=56 time=24.8 ms
64 bytes from 93.184.216.34: icmp_seq=3 ttl=56 time=25.1 ms
^C
--- www.example.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 24.812/25.080/25.302/0.218 ms
Pour rendre un service interne accessible depuis l'hôte, utilisez le mappage de ports. Par exemple, avec un serveur web Nginx :
# Mapper le port 8080 de l'hôte au port 80 du conteneur
$ docker run -d --name web-serveur -p 8080:80 nginx
# Vérifier le mappage
$ docker port web-serveur
80/tcp -> 0.0.0.0:8080
# Tester l'accès depuis l'hôte
$ curl http://localhost:8080
<html>
<head>
<title>Welcome to nginx!</title>
...