Table des matières

, , , ,

Docker : Types des réseaux et usages

Par défaut Docker propose 3 types de réseaux chacun ayant un driver dédié et des caractéristiques spécifiques.

docker network list
NETWORK ID     NAME             DRIVER    SCOPE
5c5d31d57162   bridge           bridge    local
89092ed731fa   host             host      local
5f36f3d8495b   none             null      local

A sa création, le conteneur rejoint un de ces 3 types de réseaux:

Réseau de l’hôte

Le conteneur est intégré directement dans la pile réseau de la machine hôte. Il n'y a pas d'isolation logique au niveau du réseau, cela se traduit notamment par:

# Création d'un conteneur éphémère en mode interactif sur le réseau hote
docker container run -it --rm --name test_host_net --net=host busybox:latest /bin/sh
 
# Depuis l'interpréteur dans le conteneur on peut lister les interfaces
# Les interfaces du conteneur sont identiques à celles de l'hote
ip link show

Dans ce mode de fonctionnement le conteneur n'a pas besoin de règles de forwarding puisqu'il est directement lié aux interfaces de l'hote. Le port mapping de la commande --publish n'a donc aucun effet.

Les conteneurs créés sur le réseau hôte sont accessibles par les conteneurs utilisant le réseau Docker par défaut (docker0) et par les les conteneurs présent dans les réseaux de type pont créés par l'utilisateur.

Les réseaux de type pont

Les ponts permettent à de multiples réseaux indépendants de coexister sur le même hôte physique. Seuls les conteneurs présents dans un même réseaux peuvent communiquer entre eux ou avec l’hôte. Si l’hôte accède à Internet, les conteneurs le pourront aussi. Cela permet d'isoler, de regrouper les conteneurs.

Parmi les réseaux en ponts on distingue:

Le pont par défaut

Le réseau en pont par défaut nommé docker0 est créé automatiquement par Docker lors de l'installation.

# Depuis un interpréteur sur la machine hôte
ip address show docker0

Par défaut le pont docker0 utilise un plan d'adressage 172.16.0.1/16. Ce paramétrage peut être modifié dans le fichier de configuration du daemon Docker /etc/default/docker.

Si aucune indication concernant le réseau n'est donnée sur la ligne de commande à la création du conteneur, c'est le pont par défaut qui est utilisé:

# Création d'un conteneur éphémère en mode interactif sans spécification du réseau
docker container run -it --rm --name test_host_net busybox:latest
 
# Depuis l'interpréteur dans le conteneur on peut lister les interfaces
ip address show
 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    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
17: eth0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

Docker utilise iptables pour gérer le transmission des paquets (forwarding) avec le réseau en pont. Toutes les connexion sortantes semblent provenir d'une des adresses de l'hote (masquerading) et les connexions entrantes sont redirigée vers le bon conteneur via des règles de NAT.

Le pont par défaut docker0 supporte l'usage du mapping de ports via la commande --publish. L'option --link permet également de faire communiquer des conteneurs en partageant les variables d' environnement et en complétant le fichier de /etc/hosts (résolution de noms des conteneurs)

Réseaux par pont définis par l'utilisateur

Docker permet à l'utilisateur de créer des réseaux personnalisés par pont (todo: voir également les réseau de type overlay). Ils réagissent de la même manière que le pont par défaut docker0. Les conteneurs présents dans le réseau peuvent communiquer directement entre eux tout en étant isolés des autres réseaux.

Au sein de ces réseaux, les conteneurs ont la capacité de se trouver mutuellement (se résoudre) via leur nom de conteneur (Docker intègre un service de DNS)

# Création d'un réseau par pont
docker network create vnet_test
 
# Création de 3 conteneurs éphémères dans le réseau vnet_test
for i in {1..3}; do docker run -d --rm --name=node-${i} --net=vnet_test busybox:latest /bin/sh -c "sleep 300"; done
 
# Lister les conteneurs existants
docker container list --filter network=vnet_test --format 'table {{.ID}} {{.Names}}'
CONTAINER ID NAMES
0339126c1815 node-3
95c20c4995a9 node-2
c4f61fa21a23 node-1
 
# Ouverture d'un shell dans le premier conteneur
docker container exec -it node-1 /bin/sh
 
# Depuis le conteneur node-1
# On peut contacter facilement les 2 autres conteneurs via leur nom de conteneur
ping -c 1 node-2
 
PING node-2 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.413 ms
. . .
 
ping -c 1 node-3
 
PING node-3 (172.19.0.4): 56 data bytes
64 bytes from 172.19.0.4: seq=0 ttl=64 time=0.247 ms
. . .

La résolution fonctionne car le conteneur est paramétré pour utiliser comme résolveur le service DNS de Docker (127.0.0.11).

# Depuis le conteneur node-1
cat /etc/resolv.conf
 
search mairie.local
nameserver 127.0.0.11
options edns0 trust-ad ndots:0

Le service DNS de Docker maintient le mapping entre noms de conteneurs et adresses IP pour le réseau dans lequel le conteneur est connecté. Cette fonctionnalité facilite la découverte des nœuds du réseau.

docker0 vs pont utilisateur

Le tableau ci-dessous résume les différences entre le réseau par pont par défaut docker0 et les réseaux par pont créés par l'utilisateur.

Domaine docker0 Pont utilisateur
Déploiement du réseau Créé par Docker lors de l'installation Doit être créé par l'utilisateur.
Association au conteneur Le conteneur rejoint ce réseau par défaut Doit utiliser explicitement l'argument --net et le nom du réseau pour joindre le conteneur au réseau.
Liaison des conteneurs L'usage de l'argument --link permet de relier plusieurs conteneurs La liaison des conteneurs n'est pas supportée.
Mapping des ports supporté supporté
Resolveur de noms non supporté ( la résolution fonctionne pour les conteneurs liés) Les conteneurs dans le réseau résolvent les noms de ceux présents dans ce même réseau grace à la mise à jour du fichier /etc/hosts et au service DNS.
Forwarding utilise iptables utilise iptables

Conteneur sans réseau

Il est également possible de créer un conteneur sans le connecter à un réseau via l'argument --net=none.

Références