Connecter deux conteneurs Docker ayant leurs propres fichiers Docker Compose
Le conteneur fournisseur crée un réseau Docker qui peut être utilisé par un conteneur consommateur.
Je voulais créer un réseau entre un conteneur de base de données Docker et un conteneur d'application Docker , les deux ayant leurs propres fichiers Docker Compose . Je voulais aussi m'assurer de bien faire les choses avant de les implémenter dans les fichiers docker-compose . Test first baby ...
J'ai également fait cela il y a quelque temps, mais j'ai dû me pencher à nouveau sur la question parce que Docker Compose a maintenant une option de nom dans la section des réseaux. J'écris ce post pour documenter comment je l'ai fait, j'espère que vous le trouverez utile aussi.
Deux conteneurs et commandes pour les tests
Dans cette configuration, j'utilise deux conteneurs :
- container#1 : le conteneur de la base de données.
- container#2 : le conteneur d'application.
Un bon outil pour jouer avec les conteneurs et les réseaux est l'image Busybox . Elle est petite et contient beaucoup de commandes de mise en réseau.
Conteneur de base de données
Le conteneur de base de données (le fournisseur) doit contenir un deamon qui écoute les connexions entrantes. Dans le conteneur d'application (le consommateur), nous exécutons un programme qui appelle le deamon dans le conteneur de base de données.
Pour l'écoute (un deamon de base de données réel est à l'écoute), j'ai d'abord essayé la commande évidente netcat , par exemple en écoutant le port 1234 :
nc -l -p 1234
Mais il s'est avéré que netcat s'est terminé lorsque la connexion a été fermée (par telnet), ce qui a mis fin au conteneur. Netcat possède également une option de persistance '-k' mais cela n'a pas fonctionné, c'est un problème connu. Il semble exister une meilleure version appelée ncat mais elle n'est pas disponible dans l'image Busybox .
C'est pourquoi j'utilise la commande httpd :
httpd -f -v -p 1234
En résumé, dans le conteneur de base de données, nous utilisons httpd comme service d'écoute.
Conteneur d'application
Malheureusement curl n'est pas disponible dans l'image Busybox et la commande wget dans Busybox ne supporte pas les ports autres que 80. C'est pourquoi j'utilise telnet dans le conteneur d'application pour me connecter au serveur httpd .
Enfin, j'utilise netstat pour vérifier les ports d'écoute dans les conteneurs.
Les deux fichiers docker-compose
Le fichier de base de données docker-compose , db.yml
Dans le conteneur de la base de données, nous créons le réseau 'postgres12_network'.
# db.yml
version: '3.7'
services:
postgres12:
image: busybox
container_name: postgres12_container
command: /bin/httpd -f -v -p 1234
networks:
- default
networks:
default:
name: postgres12_network
Le fichier d'application docker-compose , app.yml
Dans le conteneur d'application, nous consommons le réseau 'postgres12_network'.
# app.yml
version: '3.7'
services:
app:
image: busybox
container_name: app_container
command: sleep infinity
networks:
- default
- postgres
networks:
postgres:
external:
name: postgres12_network
Test du conteneur de base de données
Soyez prêt, nous utilisons beaucoup de fenêtres de terminal ici.
Ouvrez une fenêtre de terminal, et démarrez le conteneur de base de données :
docker-compose -f db.yml up
Pour vérifier si le conteneur est en place, ouvrez une autre fenêtre de terminal et tapez :
docker ps
Résultat :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ab28dc6d47b busybox "/bin/httpd -f -v -p…" 19 minutes ago Up 19 minutes postgres12_container
Pour vérifier si le réseau Docker est créé, tapez :
docker network ls
Résultat :
NETWORK ID NAME DRIVER SCOPE
539decc283dd postgres12_network bridge local
Dans une troisième fenêtre de terminal, nous entrons dans le conteneur de base de données, en utilisant exec, et nous démarrons une session shell (sh) :
docker-compose -f db.yml exec postgres12 /bin/sh
Vérifier si le deamon httpd écoute sur le port 1234 :
netstat -l -t
Résultat :
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:41825 0.0.0.0:* LISTEN
tcp 0 0 :::1234 :::* LISTEN
Connectez-vous maintenant au démon httpd :
telnet postgres12 1234
Résultat :
Connected to postgres12
Dans telnet, appuyez sur <ENTER> ou tapez autre chose et appuyez sur <ENTER>.
Résultat :
HTTP/1.1 408 Request Timeout
Date: Wed, 26 May 2021 11:42:22 GMT
Connection: close
Content-type: text/html
<HTML><HEAD><TITLE>408 Request Timeout</TITLE></HEAD>
<BODY><H1>408 Request Timeout</H1>
No request appeared within 60 seconds
</BODY></HTML>
Connection closed by foreign host
Cela peut sembler mauvais mais en fait cela se présente bien, nous avons obtenu une réponse du deamon httpd !
Dans la première fenêtre du terminal, il devrait y avoir un message comme celui-ci :
postgres12_container | [::ffff:192.168.48.2]:33264: response:400
Si vous essayez telnet avec un port différent, le message sera :
telnet: can't connect to remote host (192.168.48.2): Connection refused
Jusqu'ici tout va bien, passons au conteneur d'application.
Test du conteneur d'application
Ouvrez une fenêtre de terminal, et démarrez le conteneur d'application :
docker-compose -f app.yml up
Dans une autre fenêtre de terminal, vérifiez si le conteneur est en place, tapez :
docker ps
Résultat :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9df4c69b8772 busybox "sleep infinity" 58 seconds ago Up 57 seconds app_container
4ab28dc6d47b busybox "/bin/httpd -f -v -p…" 42 minutes ago Up 42 minutes postgres12_container
Les deux conteneurs sont en place et fonctionnent maintenant.
Dans une autre fenêtre de terminal, nous entrons dans le conteneur d'application, en utilisant exec, et démarrons une session shell (sh) :
docker-compose -f app.yml exec app /bin/sh
Vérifier si nous pouvons nous connecter au deamon httpd dans le conteneur de base de données :
telnet postgres12 1234
Résultat :
Connected to postgres12
C'est bon, tout fonctionne comme prévu.
Résumé
Il est amusant (PAS) que la question + répond sur la façon de connecter deux conteneurs Docker a une quantité énorme de votes sur Stack Overflow, voir les liens ci-dessous. Je pense que la documentation sur le site de Docker s'est beaucoup améliorée mais elle a besoin de plus d'exemples (triviaux). L'option 'name' dans la section réseaux facilite la définition des réseaux et la lecture de ce qui se passe dans un fichier docker-compose .
Enfin, Busybox est une petite image mais aussi très limitée. Ce serait bien si plus de commandes de mise en réseau étaient ajoutées.
Liens / crédits
BusyBox - The Swiss Army Knife of Embedded Linux
https://www.busybox.net/downloads/BusyBox.html
Communication between multiple docker-compose projects
https://stackoverflow.com/questions/38088279/communication-between-multiple-docker-compose-projects/38089080#38089080
netcat - keep listening for connection in Debian
https://superuser.com/questions/1008348/netcat-keep-listening-for-connection-in-debian
Networking in Compose
https://docs.docker.com/compose/networking/
En savoir plus...
Docker Docker-compose
Récent
- Masquer les clés primaires de la base de données UUID de votre application web
- Don't Repeat Yourself (DRY) avec Jinja2
- SQLAlchemy, PostgreSQL, nombre maximal de lignes par user
- Afficher les valeurs des filtres dynamiques SQLAlchemy
- Transfert de données sécurisé grâce au cryptage à Public Key et à pyNaCl
- rqlite : une alternative à haute disponibilité et dist distribuée SQLite
Les plus consultés
- Utilisation des Python's pyOpenSSL pour vérifier les certificats SSL téléchargés d'un hôte
- Utiliser UUIDs au lieu de Integer Autoincrement Primary Keys avec SQLAlchemy et MariaDb
- Connexion à un service sur un hôte Docker à partir d'un conteneur Docker
- Utiliser PyInstaller et Cython pour créer un exécutable Python
- SQLAlchemy : Utilisation de Cascade Deletes pour supprimer des objets connexes
- Flask RESTful API validation des paramètres de la requête avec les schémas Marshmallow