Запуск нескольких Docker контейнеров в одной сети

Задача — соединить два контейнера в одну сеть. Допустим это будет веб сервер nginx and php-fpm. Естественно они должны обмениваться сообщениями без проблем, ip адреса должна быть из одной подсети. Также должны находить друг друга не просто по ip адресу, но и по имени сервиса. Намного удобнее работать с именем php-service, вместо 172.21.0.2, который еще может измениться при повторном запуске.

Для начала немного теории.

При установке Docker-а автоматически создается три сети под название none, host, bridge. Список можно посмотреть через команду docker network ls

none — у контейнера нет сети, он изолирован, ему сломали ethernet port, host — использовать сеть хоста. Чтобы присоединиться к ним, придется вручную прописать имя сети при запуске docker run —network=host|none.

bridge — По умолчанию при создании контейнера, докер присоединяет контейнер к уже существующей сети под названием bridge.

Настройка двух контейнеров в одной сети

Например, командами

создали два контейнера. Посмотрим состояние сети bridge

два контейнера есть. Зайдя в первый контейнер 172.17.0.3 можно передать сообщение по ИП 172.17.0.2 второму,

но нельзя найти по имени контейнера, будет ошибка

Как найти контейнер в сети по имени?

Docker умеет автоматически находить ип адреса контейнеров по именам (auto service discover), но для этого нужно использовать пользовательское сетевое окружение или именованное сетевое окружение (user-defined-network).

Создать новую сеть можно командой:

Проверка что все работает:

Сервис успешно найден по имени

Как настроить сеть в docker-compose?

Для удобства создадим два конфига для docker-compose в одной папке. Пример первого конфига busybox-1.yml:

Пример второго busybox-2.yml:

networks — описывается используемая сеть, их может быть несколько

default — означает что сеть будет использоваться для всех сервисов. Вместо default  можно написать  «my-awesome-network», тогда эту сеть нужно будет указывать явно сервиса. Удобно если к сети нужно подключить только один из сервисов из пяти.

name — имя сети

external — сеть внешняя, то есть при старте docker-compose будет использовать существующую сеть, а не пытаться создать новую

tty — включить терминал при старте. Нужно чтобы запустить процесс в фоне, иначе процесс сразу же завершить выполнение. Аналог команды docker run -ti

Запустить и протестировать можно командами:

Сеть в порядке

Теперь становится понятной магия docker-compose. Как несколько сервисов, объявленных в docker-compose.yml, находили другу друга? Все дело в том, что при запуске(up) docker-compose неявно создавал user-defined-network, который обычно назывался название_папки_default, и добавлял к этой сети каждый сервис. И как раз при помощи этого сервисы могли общаться с друг другом по именам.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *