angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

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.

26 mai 2021
Dans Docker
post main image
Image by Pixabay

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

Laissez un commentaire

Commentez anonymement ou connectez-vous pour commenter.

Commentaires

Laissez une réponse

Répondez de manière anonyme ou connectez-vous pour répondre.