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

Соедините два контейнера Docker , имеющих собственные файлы Docker Compose

Контейнер-поставщик создает сеть Docker , которую может использовать контейнер-потребитель.

26 мая 2021
В Docker
post main image
Image by Pixabay

Я хотел создать сеть между контейнером базы данных Docker и контейнером приложения Docker , оба из которых имеют свои собственные файлы Docker Compose . И я также хотел убедиться, что делаю все правильно, прежде чем реализовывать это в реальных файлах docker-compose . Сначала протестируйте ребенка...

Я также делал это некоторое время назад, но мне пришлось изучить это снова, потому что Docker Compose теперь имеет опцию имени в разделе сетей. Я пишу этот пост, чтобы задокументировать, как я это сделал, надеюсь, вы тоже найдете его полезным.

Два контейнера и команды для тестирования

В этой установке я использую два контейнера:

  • container#1: контейнер базы данных
  • container#2: контейнер приложений.

Хорошим инструментом для игры с контейнерами и сетями является образ Busybox . Он небольшой и содержит много сетевых команд.

Контейнер базы данных

Контейнер базы данных (поставщик) должен содержать deamon, который прослушивает входящие соединения. В контейнере приложения (потребитель) мы запускаем программу, которая вызывает deamon в контейнере базы данных.

Для прослушивания (на самом деле прослушивается deamon базы данных) я сначала попробовал очевидную команду netcat , например, при прослушивании порта 1234:

nc -l -p  1234

Но оказалось, что netcat прервался, когда соединение было закрыто (командой telnet) и это прервало работу контейнера. Netcat также имеет опцию '-k' persistent, но это не сработало, это известная проблема. Похоже, что существует лучшая версия под названием ncat , но она недоступна в образе Busybox .

Поэтому я использую команду httpd :

httpd  -f -v -p  1234

Итого, в контейнере базы данных мы используем httpd в качестве службы прослушивания.

Контейнер приложений

К сожалению, curl недоступен в образе Busybox , а команда wget в Busybox не поддерживает порты, отличные от 80. Поэтому я использую telnet в контейнере приложений для подключения к серверу httpd .

Наконец, я использую netstat для проверки прослушиваемых портов в контейнерах.

Два файла docker-compose

Файл базы данных docker-compose , db.yml

В контейнере базы данных мы создаем сеть '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

Файл приложения docker-compose , app.yml

В контейнере приложения мы потребляем сеть '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

Тестирование контейнера базы данных

Будьте готовы, здесь мы используем много терминальных окон.

Откройте окно терминала и запустите контейнер базы данных:

docker-compose  -f  db.yml  up

Чтобы проверить, запущен ли контейнер, откройте другое окно терминала и введите:

docker ps

Результат:

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

Чтобы проверить, создана ли сеть Docker , введите:

docker network ls

Result:

NETWORK ID     NAME                                   DRIVER    SCOPE
539decc283dd    postgres12_network                      bridge    local

В третьем окне терминала заходим в контейнер базы данных, используя команду exec, и запускаем сеанс оболочки (sh) :

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

Проверяем, слушает ли деймон httpd порт 1234:

netstat -l -t

Результат:

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

Теперь подключитесь к httpd deamon:

telnet  postgres12  1234

Результат:

Connected to postgres12

В telnet нажмите <ENTER> или введите что-нибудь еще и нажмите <ENTER>.

Результат:

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

Это может выглядеть плохо, но на самом деле все выглядит хорошо, мы получили ответ от деамона httpd !

В первом окне терминала должно появиться сообщение типа:

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

Если вы попробуете telnet с другим портом, сообщение будет таким:

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

Пока все хорошо, переходим к контейнеру приложений.

Тестирование контейнера приложений

Откройте окно терминала и запустите контейнер приложения:

docker-compose   -f  app.yml   up

В другом окне терминала проверьте, запущен ли контейнер, введите:

docker ps

Результат:

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

Оба контейнера запущены и работают.

В другом окне терминала заходим в контейнер приложения, используя exec, и запускаем сеанс shell (sh) :

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

Проверяем, можем ли мы подключиться к деймону httpd в контейнере базы данных:

telnet  postgres12  1234

Результат:

Connected to postgres12

Все хорошо, все работает, как ожидалось.

Резюме

Забавно (НЕ), что вопрос + о том, как соединить два контейнера Docker , имеет огромное количество голосов на Stack Overflow, см. ссылки ниже. Я думаю, что документация на сайте Docker стала намного лучше, но ей нужно больше (тривиальных) примеров. Опция 'name' в разделе networks упрощает определение сетей и чтение того, что происходит в файле docker-compose .
Наконец, Busybox - это маленький образ, но тоже очень ограниченный. Было бы хорошо, если бы было добавлено больше сетевых команд.

Ссылки / кредиты

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/

Подробнее

Docker Docker-compose

Оставить комментарий

Комментируйте анонимно или войдите в систему, чтобы прокомментировать.

Комментарии

Оставьте ответ

Ответьте анонимно или войдите в систему, чтобы ответить.