Соедините два контейнера Docker , имеющих собственные файлы Docker Compose
Контейнер-поставщик создает сеть Docker , которую может использовать контейнер-потребитель.
Я хотел создать сеть между контейнером базы данных 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
Недавний
- Скрытие первичных ключей базы данных UUID вашего веб-приложения
- Don't Repeat Yourself (DRY) с Jinja2
- SQLAlchemy, PostgreSQL, максимальное количество строк для user
- Показать значения в динамических фильтрах SQLAlchemy
- Безопасная передача данных с помощью шифрования Public Key и pyNaCl
- rqlite: альтернатива dist с высокой степенью готовности и SQLite
Большинство просмотренных
- Используя Python pyOpenSSL для проверки SSL-сертификатов, загруженных с хоста
- Использование UUID вместо Integer Autoincrement Primary Keys с SQLAlchemy и MariaDb
- Подключение к службе на хосте Docker из контейнера Docker
- Использование PyInstaller и Cython для создания исполняемого файла Python
- SQLAlchemy: Использование Cascade Deletes для удаления связанных объектов
- Flask Удовлетворительный запрос API проверка параметров запроса с помощью схем Маршмэллоу