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

Verbind twee Docker containers met hun eigen Docker Compose bestanden

De provider container creëert een Docker netwerk dat gebruikt kan worden door een consumer container.

26 mei 2021
In Docker
post main image
Image by Pixabay

Ik wilde een netwerk opzetten tussen een database Docker container en een applicatie Docker container, die beide hun eigen Docker Compose bestanden hebben. En ik wilde er ook zeker van zijn dat ik het goed doe voordat ik dit implementeer in de eigenlijke docker-compose bestanden. Test eerst baby ...

Ik heb dit enige tijd geleden ook gedaan, maar moest er nog eens naar kijken omdat Docker Compose nu een naam optie heeft in de netwerken sectie. Ik schrijf deze post om te documenteren hoe ik het deed, hoop dat je het ook nuttig vindt.

Twee containers en commando's om te testen

In deze opstelling gebruik ik twee containers:

  • container#1: de database container
  • container#2: de applicatie container

Een leuke tool om met containers en netwerken te spelen is het Busybox image. Het is klein en bevat veel netwerkcommando's.

Database container

De database container (de provider) moet een deamon bevatten die luistert naar inkomende verbindingen. In de applicatie container (de consument) draaien we een programma dat de deamon in de database container aanroept.

Voor het luisteren (een echte database deamon luistert) probeerde ik eerst het voor de hand liggende netcat commando, bijvoorbeeld als er geluisterd wordt naar poort 1234:

nc -l -p  1234

Maar het bleek dat netcat eindigde toen de verbinding werd gesloten (door telnet) en dit eindigde de container. Netcat heeft ook een '-k' persistente optie maar dat werkte niet, het is een bekend probleem. Er schijnt een betere versie te zijn genaamd ncat maar die is niet beschikbaar in het Busybox image.

Daarom gebruik ik het httpd commando:

httpd  -f -v -p  1234

Samenvattend, in de database container gebruiken we httpd als de luisterende service.

Applicatie container

Helaas is curl niet beschikbaar in de Busybox image en het wget commando in Busybox ondersteunt geen andere poorten dan 80. Daarom gebruik ik telnet in de applicatie container om verbinding te maken met de httpd server.

Tenslotte gebruik ik netstat om de luisterpoorten in de containers te controleren.

De twee docker-compose bestanden

Het database docker-compose bestand, db.yml

In de database container maken we het netwerk 'postgres12_network' aan.

#  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

De toepassing docker-compose bestand, app.yml

In de applicatie container consumeren we het netwerk '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

Testen van de database container

Wees voorbereid, we gebruiken hier veel terminal vensters.

Open een terminal venster, en start de database container:

docker-compose  -f  db.yml  up

Om te controleren of de container opgestart is, open een ander terminal venster en type:

docker ps

Resultaat:

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

Om te controleren of het Docker netwerk is aangemaakt, type:

docker network ls

Resultaat:

NETWORK ID     NAME                                   DRIVER    SCOPE
539decc283dd    postgres12_network                      bridge    local

In een derde terminal venster gaan we de database container binnen, met behulp van exec, en starten een shell (sh) sessie:

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

Controleer of de httpd deamon luistert naar poort 1234:

netstat -l -t

Resultaat:

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

Maak nu verbinding met de httpd deamon:

telnet  postgres12  1234

Resultaat:

Connected to postgres12

In telnet, druk op <ENTER> of typ iets anders en druk op <ENTER>.

Resultaat:

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

Het ziet er misschien slecht uit maar het ziet er in feite goed uit, we kregen een antwoord van de httpd deamon!

In het eerste terminal venster zou er een bericht moeten staan zoals:

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

Als je telnet probeert met een andere poort, zal de boodschap zijn:

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

So far so good, laten we verder gaan met de applicatie container.

Testen van de applicatie container

Open een terminal venster, en start de applicatie container:

docker-compose   -f  app.yml   up

In een ander terminal venster controleer of de container opgestart is, type:

docker ps

Resultaat:

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

Beide containers zijn nu up and running.

In een ander terminal venster gaan we de applicatie container binnen, met exec, en starten een shell (sh) sessie:

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

Controleer of we verbinding kunnen maken met de httpd deamon in de database container:

telnet  postgres12  1234

Resultaat:

Connected to postgres12

Dat is goed, alles werkt zoals verwacht.

Samenvatting

Het is grappig (NOT) dat de vraag + beantwoordt over hoe twee Docker containers te verbinden een enorme hoeveelheid stemmen heeft op Stack Overflow, zie onderstaande links. Ik denk dat de documentatie op de Docker website een stuk verbeterd is, maar het heeft meer (triviale) voorbeelden nodig. De 'name' optie in de netwerken sectie maakt het eenvoudiger om netwerken te definiëren en te lezen wat er in een docker-compose bestand gebeurt.
Tenslotte, Busybox is een klein plaatje maar ook erg beperkt. Het zou leuk zijn als er meer netwerk commando's aan toegevoegd zouden worden.

Links / credits

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/

Laat een reactie achter

Reageer anoniem of log in om commentaar te geven.

Opmerkingen

Laat een antwoord achter

Antwoord anoniem of log in om te antwoorden.