Lab 6.1 : Réseaux et résolution DNS¶
| Durée | 60 min |
| Niveau | Semi-guidé |
| Prérequis | Lab 5.2 : Sauvegarder et restaurer un volume, cours du chapitre 6 |
| Acquis visés | AA4 |
Objectifs
- Constater que le réseau bridge par défaut ne résout pas les noms
- Créer un réseau défini par l'utilisateur et joindre un conteneur par son nom
- Distinguer le port d'un conteneur et le port publié sur l'hôte
- Brancher et débrancher un conteneur à chaud, et lui donner un alias
- Observer le mode
none(et le modehostsous Linux)
Contexte et schéma¶
Vous lancez de petits conteneurs alpine pour tester la communication, puis un serveur nginx. Dans ce lab, seules les commandes clés vous sont données : à vous de les adapter et de déduire le reste à l'aide du cours.
flowchart LR
subgraph D["Réseau bridge par défaut"]
A1["a1"]
A2["a2"]
end
subgraph T["Réseau reseau-tp"]
B1["b1"]
B2["b2"]
W["web<br/>nginx"]
end
H["Hôte"] -- "127.0.0.1:8080" --> W
Selon votre option
- Sous PowerShell, utilisez
curl.exeet écrivez les commandes sur une seule ligne. - Le mode
host(étape 7) se manipule sous Linux (options B et C) uniquement.
Étapes¶
Étape 1 : Observer les réseaux existants¶
- Objectif : connaître les réseaux présents sur votre machine.
- Indices :
docker network ls: repérez les trois réseaux créés par Docker et leur pilote.docker network inspect bridge: repérez la plage d'adresses (champSubnet) et la liste des conteneurs connectés (vide, si vous n'avez aucun conteneur en cours).
Point de contrôle
- Vous avez relevé les réseaux
bridge,hostetnoneet leur pilote - Vous avez relevé le
Subnetdu réseaubridge
Étape 2 : Tester le réseau bridge par défaut¶
- Objectif : montrer que, sur le réseau par défaut, on joint un conteneur par son adresse IP mais pas par son nom.
- Indices :
- Lancez deux conteneurs
a1eta2(alpine:3.20, commandesleep 3600), sans option--network. - Relevez l'adresse IP de
a2:
- Lancez deux conteneurs
- Depuis
a1, testez la communication avecdocker exec a1 ping -c 2 <adresse-de-a2>, puis avecdocker exec a1 ping -c 2 a2.
Point de contrôle
- Le
pingpar adresse IP réussit - Le
pingpar nom échoue (nom non résolu)
Étape 3 : Créer un réseau défini par l'utilisateur¶
- Objectif : obtenir la résolution des noms.
- Indices :
- Créez le réseau
reseau-tpavecdocker network create. - Lancez deux conteneurs
b1etb2(alpine:3.20,sleep 3600) sur ce réseau avec l'option--network. - Depuis
b1, testezping -c 2 b2puisnslookup b2. - Comparez l'adresse obtenue avec celle affichée par
docker network inspect reseau-tp.
- Créez le réseau
Point de contrôle
-
ping b2depuisb1réussit par nom - L'adresse résolue correspond à celle de
b2dansdocker network inspect - Depuis
a1(réseau par défaut), le nomb2n'est toujours pas résolu : les deux réseaux sont séparés
Le serveur DNS
Dans un conteneur d'un réseau défini par l'utilisateur, docker exec b1 cat /etc/resolv.conf montre l'adresse du serveur DNS intégré de Docker (une adresse locale du conteneur). C'est lui qui répond aux demandes de noms.
Étape 4 : Distinguer port du conteneur et port publié¶
- Objectif : comprendre quel port utiliser selon d'où l'on s'adresse au service.
- Indices :
- Lancez un conteneur
web(nginx:1.27-alpine) surreseau-tp, avec le port 8080 de l'hôte relié au port 80 du conteneur, accessible uniquement depuis l'hôte (voir la section 5 du cours). - Depuis l'hôte :
curl http://localhost:8080. - Depuis
b1, testez les deux adresses ci-dessous. L'imagealpinefournitwget:
- Lancez un conteneur
- Affichez les ports publiés avec
docker port web.
Point de contrôle
-
curl http://localhost:8080affiche la page d'accueil de nginx - Depuis
b1,http://web(port du conteneur, sans publication) fonctionne - Depuis
b1,http://web:8080échoue : le port 8080 n'existe que sur l'hôte - Vous savez expliquer pourquoi, dans les deux cas, l'un des ports est « le bon »
Étape 5 : Brancher, débrancher et donner un alias¶
- Objectif : modifier les réseaux d'un conteneur sans le recréer.
- Indices :
- Branchez
a1(réseau par défaut) surreseau-tpavecdocker network connect. - Depuis
a1, joignez maintenantb2etwebpar leur nom. - Vérifiez avec
docker inspectquea1est sur deux réseaux. - Débranchez
a1dereseau-tpavecdocker network disconnectet refaites le test. - Lancez un conteneur
b3surreseau-tpavec en plus l'option--network-alias serveur, puis joignezb3depuisb1en utilisant le nomserveur.
- Branchez
Point de contrôle
- Après
connect,a1jointb2etwebpar leur nom - Après
disconnect,a1ne les joint plus -
b1jointb3par le nomb3et par l'aliasserveur
Étape 6 : Observer le mode none¶
- Objectif : constater l'absence totale de réseau.
- Indices :
- Lancez un conteneur temporaire (
--rm,alpine:3.20) avec--network nonequi exécuteip addr, puis un autre qui exécuteping -c 2 8.8.8.8.
- Lancez un conteneur temporaire (
Point de contrôle
- Seule l'interface
loapparaît - Le
pingéchoue (aucun accès réseau)
Étape 7 (facultative, options B et C) : Observer le mode host¶
- Objectif : voir un conteneur partager le réseau de l'hôte.
- Indices :
- Lancez un conteneur
web-host(nginx:1.27-alpine) avec--network host, sans option-p. - Depuis l'hôte :
curl http://localhost:80(si le port 80 est déjà utilisé sur votre machine, observez l'erreur dansdocker logs web-host). - Comparez
docker exec web-host ip addravec l'affichage deip addrsur l'hôte.
- Lancez un conteneur
Point de contrôle
- Le serveur répond sur le port 80 de l'hôte sans publication
- Les interfaces vues dans le conteneur sont celles de l'hôte
Questions de réflexion¶
Pourquoi a1 ne parvient-il pas à joindre a2 par son nom, alors que b1 joint b2 ?
a1 et a2 sont sur le réseau bridge par défaut, qui n'offre pas de résolution de noms. b1 et b2 sont sur un réseau défini par l'utilisateur, qui fournit un DNS intégré.
À l'étape 4, pourquoi http://web:8080 échoue-t-il depuis b1 ?
Entre conteneurs d'un même réseau, on utilise le port du conteneur (80). Le port 8080 est un port de l'hôte : il n'existe pas sur l'adresse du conteneur web.
Pourquoi publier avec 127.0.0.1:8080:80 plutôt que 8080:80 ?
Pour que le service ne soit accessible que depuis l'hôte, et non depuis les autres machines du réseau. Moins un service est exposé, mieux c'est.
Quel intérêt présente le mode none ?
Il coupe totalement le conteneur du réseau, ce qui convient aux traitements qui n'en ont pas besoin et qui ne doivent pas pouvoir communiquer.
Dépannage¶
| Symptôme | Pistes |
|---|---|
ping: bad address 'b2' sur reseau-tp |
Les deux conteneurs sont-ils bien sur reseau-tp ? Vérifiez avec docker network inspect reseau-tp |
port is already allocated |
Le port 8080 est déjà utilisé : choisissez un autre port de l'hôte, ou arrêtez le conteneur qui l'utilise |
curl ne répond pas sur localhost:8080 |
Vérifiez docker ps et docker port web ; le conteneur web est-il bien lancé ? |
network ... has active endpoints en supprimant un réseau |
Des conteneurs y sont encore connectés : supprimez-les ou débranchez-les d'abord |
network with name reseau-tp already exists |
Le réseau existe déjà : réutilisez-le, ou supprimez-le avec docker network rm |
wget: bad address ou wget: download timed out |
Voulu à l'étape 4 pour web:8080 ; sinon, vérifiez le réseau et le nom du conteneur |
Sous PowerShell, l'option -f de docker inspect est refusée |
Écrivez la commande sur une seule ligne, avec le modèle entre apostrophes |
Nettoyage et reprise¶
(Si web-host n'a pas été créé, Docker le signale : sans conséquence.) Les réseaux bridge, host et none sont créés par Docker et ne se suppriment pas. Le Lab 6.2 repart de zéro.
Retour au chapitre¶
Chapitre 6 : Réseau Docker · Lab suivant : Lab 6.2 : Isoler une application par réseaux