Как подключиться к локальному хосту в контейнере Docker
При работе с Docker вы обычно контейнеризуете службы, формирующие стек, и используете межконтейнерную сеть для связи между ними. Иногда вам может понадобиться контейнер для связи со службой на вашем хосте, которая не была контейнеризована. Вот как получить доступ к localhost
или 127.0.0.1
из контейнера Docker.
Простой вариант
Docker Desktop 18.03+ для Windows и Mac поддерживает host.docker.internal
в качестве рабочего псевдонима для localhost
. Используйте эту строку внутри своих контейнеров для доступа к вашему хост-компьютеру.
localhost
и127.0.0.1
— разрешаются в контейнер.host.docker.internal
— разрешается во внешний хост.
Если вы используете сервер MySQL на своем хосте, контейнеры Docker могут получить к нему доступ, подключившись к host.docker.internal:3306
. Это самый простой метод, когда вы работаете на компьютере с Windows или Mac.
Пользователи Docker Engine в Linux также могут включить host.docker.internal
с помощью флага --add-host
для docker run
. Запустите свои контейнеры с этим флагом, чтобы открыть строку хоста:
docker run -d --add-host host.docker.internal:host-gateway my-container:latest
Флаг --add-host
добавляет запись в файл /etc/hosts
контейнера. Значение, показанное выше, сопоставляет host.docker.internal
со шлюзом узла контейнера, который соответствует реальному значению localhost
. Вы можете заменить host.docker.internal
своей собственной строкой, если хотите.
Подключение к хост-сети
Docker предоставляет сеть host
, которая позволяет контейнерам совместно использовать сетевой стек вашего хоста. Этот подход означает, что localhost
внутри контейнера разрешается в физический хост, а не в сам контейнер.
Контейнеры запускаются в хост-сети путем добавления флага --network=host
:
docker run -d --network=host my-container:latest
Теперь ваш контейнер может напрямую ссылаться на localhost
или 127.0.0.1
.
Если вы используете Docker Compose, измените определение службы вашего контейнера, включив в него поле network_mode
:
services: my-service: network_mode: host
В этом подходе есть некоторые оговорки. Важно учитывать все последствия, прежде чем использовать его. Контейнеры обычно получают свою собственную частную сеть, отдельную от стека хоста. Когда вы указываете --network=host
, контейнер по умолчанию наследует общие сетевые настройки от вашего хоста.
Любые порты, предоставляемые контейнером, будут доступны на хосте, даже если они не объявлены явно с помощью флага -p
. Имя хоста контейнера по умолчанию будет совпадать с именем хоста, хотя это можно изменить с помощью флага --hostname
.
Хост-сеть может быть проблемой безопасности, которая нарушает модель изоляции контейнеров Docker. Это все еще может быть полезно в сценариях, где вы уверены, что запущенные контейнеры не будут конфликтовать друг с другом или вызывать проблемы в вашей хост-среде. Режим хост-сети также быстрее, чем режим моста по умолчанию, поскольку для прохождения трафика отсутствует уровень виртуализации.
Доступ к хосту в режиме моста по умолчанию
Доступ к вашему хосту по-прежнему возможен из контейнеров в сетевом режиме bridge
по умолчанию. Вам просто нужно указать его сетевой IP-адрес Docker вместо localhost
или 127.0.0.1
.
Большинство установок Docker Engine будут представлять хост как 172.17.0.1
в мостовой сети docker0
по умолчанию. Вы можете проверить свой собственный IP-адрес, выполнив эту команду на своем хосте:
ip addr show docker0
IP-адрес Docker вашего хоста будет показан в строке inet
. Подключитесь к этому IP-адресу из своих контейнеров, чтобы успешно получить доступ к службам, работающим на вашем хосте.
Одна из ловушек этого подхода заключается в том, что вы не сможете подключиться к службам, которые напрямую связаны с localhost
. Вам нужно убедиться, что ваши сервисы прослушивают соединения на IP-адресе моста Docker, а также на localhost
и 127.0.0.1
. В противном случае вы увидите отказ в соединении
или подобные ошибки в вашем контейнере.
Краткое содержание
У вас есть несколько вариантов, когда вам нужно получить доступ за пределы контейнера Docker к localhost
вашего компьютера. Если вы работаете в Windows или Mac, лучше всего использовать встроенный псевдоним host.docker.internal
. Пользователи Linux могут настроить что-то подобное с флагом --add-host
при запуске контейнера.
Сетевой режим хоста — это универсальная альтернатива, которая позволяет контейнерам совместно использовать сетевой стек вашего хоста. Вы можете ссылаться на localhost
напрямую, но должны помнить о рисках и ограничениях. Это не подходящий вариант, когда требуется сильная сетевая изоляция.
Придерживаться режима моста может быть лучшим вариантом для рабочих нагрузок, которые его поддерживают. Привяжите службы вашего хоста к его IP-адресу Docker, а затем используйте этот адрес для подключения из вашего контейнера. Это позволяет вам использовать виртуализированную сеть Docker для каждого контейнера, предоставляя маршрут к вашему хосту, когда это необходимо.