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

Conectar dos contenedores Docker que tengan sus propios archivos Docker Compose

El contenedor proveedor crea una red Docker que puede ser utilizada por un contenedor consumidor.

26 mayo 2021
En Docker
post main image
Image by Pixabay

Quería crear una red entre un contenedor de base de datos Docker y un contenedor de aplicación Docker , ambos con sus propios archivos Docker Compose . Y también quería asegurarme de hacerlo bien antes de implementar esto en los archivos docker-compose reales. Prueba primero bebé ...

También hice esto hace algún tiempo, pero tenía que mirar en esto de nuevo porque Docker Compose ahora tiene una opción de nombre en la sección de redes. Escribo este post para documentar cómo lo hice, espero que os sea útil también.

Dos contenedores y comandos para las pruebas

En esta configuración estoy usando dos contenedores:

  • container#1: el contenedor de la base de datos
  • container#2: el contenedor de la aplicación

Una buena herramienta para jugar con contenedores y redes es la imagen Busybox . Es pequeña y contiene un montón de comandos de red.

Contenedor de base de datos

El contenedor de la base de datos (el proveedor) debe contener un deamon que está escuchando las conexiones entrantes. En el contenedor de la aplicación (el consumidor) ejecutamos un programa que llama al deamon en el contenedor de la base de datos.

Para la escucha (un deamon de base de datos real está escuchando) primero probé el comando obvio netcat , por ejemplo cuando se escucha el puerto 1234:

nc -l -p  1234

Pero parecía que netcat terminaba cuando la conexión se cerraba (por telnet) y esto terminaba el contenedor. Netcat también tiene una opción persistente '-k' pero no funcionó, es un problema conocido. Parece que hay una versión mejor llamada ncat pero no está disponible en la imagen Busybox .

Por eso uso el comando httpd :

httpd  -f -v -p  1234

Resumen, en el contenedor de base de datos utilizamos httpd como servicio de escucha.

Contenedor de aplicaciones

Desgraciadamente curl no está disponible en la imagen Busybox y el comando wget en Busybox no soporta otros puertos que no sean el 80. Por eso utilizo telnet en el contenedor de aplicaciones para conectarme al servidor httpd .

Por último, utilizo netstat para comprobar los puertos de escucha en los contenedores.

Los dos archivos docker-compose

El archivo de la base de datos docker-compose , db.yml

En el contenedor de la base de datos creamos el grafo '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

El archivo de la aplicación docker-compose , app.yml

En el contenedor de la aplicación consumimos la red '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

Probando el contenedor de la base de datos

Prepárate, aquí usamos muchas ventanas de terminal.

Abre una ventana de terminal, e inicia el contenedor de base de datos:

docker-compose  -f  db.yml  up

Para comprobar si el contenedor está en marcha, abre otra ventana de terminal y escribe:

docker ps

Resultado:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS         PORTS    NAMES
4ab28dc6d47b    busybox    "/bin/httpd  -f -v -p…"   19 minutes ago   Up 19 minutes           postgres12_container

Para comprobar si la red Docker está creada, escribe:

docker network ls

Resultado:

NETWORK ID     NAME                                   DRIVER    SCOPE
539decc283dd    postgres12_network                      bridge    local

En una tercera ventana de terminal entramos en el contenedor de la base de datos, utilizando exec, e iniciamos una sesión de shell (sh) :

docker-compose  -f  db.yml  exec postgres12 /bin/sh

Comprobar si el deamon httpd está escuchando el puerto 1234:

netstat -l -t

Resultado:

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

Conéctese ahora al deamon httpd :

telnet  postgres12  1234

Resultado:

Connected to postgres12

En telnet, pulsa <ENTER> o escribe algo más y pulsa <ENTER>.

Resultado:

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

Puede parecer malo, pero en realidad tiene buena pinta, ¡tenemos una respuesta del deamon httpd !

En la primera ventana de la terminal debería aparecer un mensaje como

postgres12_container | [::ffff:192.168.48.2]:33264: response:400

Si intentas telnet con un puerto diferente, el mensaje será:

telnet: can't connect to remote host (192.168.48.2): Connection refused

Hasta aquí todo bien, pasemos al contenedor de aplicaciones.

Probando el contenedor de aplicaciones

Abre una ventana de terminal, e inicia el contenedor de aplicaciones:

docker-compose   -f  app.yml   up

En otra ventana de terminal comprueba si el contenedor está en marcha, escribe:

docker ps

Resultado:

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

Los dos contenedores están en marcha ahora.

En otra ventana de terminal entramos en el contenedor de aplicación, usando exec, e iniciamos una sesión de shell (sh) :

docker-compose  -f  app.yml  exec app /bin/sh

Comprueba si podemos conectarnos al deamon httpd en el contenedor de base de datos:

telnet  postgres12  1234

Resultado:

Connected to postgres12

Muy bien, todo funciona como se espera.

Resumen

Es curioso (NO) que la pregunta que responde + sobre cómo conectar dos contenedores Docker tenga una gran cantidad de votos en Stack Overflow, ver enlaces abajo. Creo que la documentación en el sitio web de Docker ha mejorado mucho, pero necesita más ejemplos (triviales). La opción 'name' en la sección de redes facilita la definición de redes y la lectura de lo que ocurre en un archivo docker-compose .
Finalmente, Busybox es una imagen pequeña pero también muy limitada. Estaría bien que se añadieran más comandos de red.

Enlaces / créditos

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/

Deje un comentario

Comente de forma anónima o inicie sesión para comentar.

Comentarios

Deje una respuesta.

Responda de forma anónima o inicie sesión para responder.