Как позволить Docker-контейнерам видеть друг друга по именам?

Вопрос или проблема

У меня есть экземпляр Mongo, работающий в контейнере с именем mongo1, который открыл порт 27017. Я могу подключаться к нему без проблем с хоста.

У меня есть другой контейнер, в котором работает приложение, которое хочет подключиться к экземпляру Mongo.

Как я могу соединить два контейнера так, чтобы имя хоста mongo1 было доступно другому контейнеру, и он мог подключиться к mongo1:27017?

Что происходило, так это то, что сеть по умолчанию в Docker не позволяет отобразить name >> DNS.

Контейнеры на сети моста по умолчанию могут получить доступ друг к другу только по IP-адресам, если вы не используете опцию –link, которая считается устаревшей. На пользовательской сети моста контейнеры могут разрешать имена или псевдонимы друг друга.

Так что я создал новую сеть:

docker network create -d bridge br0

и затем добавил контейнеры в эту сеть:

docker network connect br0 mongo1
docker network connect br0 wiki

теперь они могут видеть друг друга по имени.

Для существующих контейнеров (как временное решение)

docker inspect <mango_container_name> | grep IPAddress

и отредактируйте/добавьте /etc/hosts внутри контейнера

docker exec -it -u 0 <app_container_name> bash

затем изнутри контейнера сопоставьте имя контейнера с IP-адресом.. Пример

echo "172.15.0.5 mango1" >> /etc/hosts

exit

…….
Или вы можете назначить имя хоста для контейнера при его запуске с помощью

docker run -it -h mango1 mango_image

и/или добавить команду echo "172.17.0.5 mango1" >> /etc/hosts в файлы Docker для меньшей головной боли.

Ответ или решение

Для обеспечения возможности взаимодействия контейнеров Docker посредством имен, необходимо использовать именованные сети Docker, которые предоставляют функционал DNS для разрешения имен контейнеров. Ваша задача заключается в том, чтобы контейнер с приложением мог подключаться к контейнеру MongoDB по имени ‘mongo1’ через порт 27017. Рассмотрим основные этапы этого процесса, обратив внимание на теорию, практические примеры и их применение.

Теория

По умолчанию Docker создает сеть типа bridge, которая позволяет контейнерам взаимодействовать, используя IP-адреса. Однако, это не всегда удобно, так как IP-адреса могут меняться, когда контейнеры пересоздаются. Чтобы обеспечить разрешение имен, Docker рекомендует использовать пользовательские сети bridge, которые поддерживают DNS для контейнеров.

При создании пользовательской сети, Docker автоматически добавляет DNS-записи для всех контейнеров, подключенных к этой сети. Это позволяет контейнерам находиться друг с другом по именам без необходимости вручную изменять файл /etc/hosts.

Пример

  1. Создание пользовательской сети:

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

    docker network create -d bridge my_custom_network

    Параметр -d bridge указывает на то, что сеть будет типа bridge, но в отличие от дефолтной сети, будет иметь поддержку DNS.

  2. Подключение контейнеров к сети:

    Подключите оба контейнера к созданной сети:

    docker network connect my_custom_network mongo1
    docker network connect my_custom_network app_container

    Теперь оба контейнера находятся в одной сети и могут использовать DNS для связи.

Применение

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

mongo --host mongo1 --port 27017

Или, если речь идет о какой-то программе на Python, настройте строку подключения к MongoDB с использованием:

from pymongo import MongoClient

client = MongoClient('mongo1', 27017)

Альтернативные методы

  1. Конфигурация /etc/hosts:

    Если по каким-то причинам вы не можете использовать пользовательские сети, можно временно использовать следующие команды для добавления записи в файл /etc/hosts:

    Сначала получите IP-адрес контейнера MongoDB:

    docker inspect mongo1 | grep IPAddress

    Затем, добавьте этот IP-адрес в файл /etc/hosts в приложении:

    docker exec -it -u 0 app_container bash
    echo "172.17.0.X mongo1" >> /etc/hosts
    exit
  2. Настройка хоста контейнера при запуске:

    Добавьте имя хоста при запуске контейнера, используя параметр -h:

    docker run -d -h mongo1 --name mongo1 mongo_image

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

Заключение

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

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

Капча загружается...