VPN подключён, браузер открывает внутренние сайты, а контейнер по-прежнему не может разрешить те же имена. Установка пакета умирает с ошибкой разрешения имён вроде EAI_AGAIN, или приложение не находит хост базы данных, который хост-машина разрешает без единой жалобы. Контейнер не использует резолвер, установленный VPN. Docker скопировал конфигурацию резолвера хоста при создании контейнера, и после этого её никто больше не копировал.

Два представления резолвера на одной машине

В Linux Docker при создании даёт каждому контейнеру копию конфигурации резолвера хоста, отфильтровывает адреса loopback и запускает встроенный DNS-сервер на 127.0.0.11, который пересылает запросы наружу. Клиент VPN, который переписывает /etc/resolv.conf после запуска контейнера, ничего внутри него не меняет. Перезапуск контейнера помогает только если резолвер хоста в этот момент случайно правильный.

Docker Desktop на macOS или Windows добавляет слой, потому что демон живёт в виртуальной машине. Резолвер VPN хоста может никогда не быть видимым для этой ВМ, поэтому перезапуск не меняет ровно ничего. Сравните два представления, прежде чем выбирать решение: docker exec mycontainer cat /etc/resolv.conf рядом со списком резолверов хоста.

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

Вариант A: передать резолвер туннеля каждому контейнеру

Docker принимает настройки DNS для каждого контейнера, и это наименьшее рабочее изменение. Сначала прочитайте адреса резолвера VPN: scutil --dns на macOS, resolvectl status или собственный вывод состояния клиента в Linux. Затем запустите контейнер с ними, например docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. В Compose та же настройка — список под сервисом, где она живёт в системе контроля версий, а не в чьей-то истории командной оболочки.

Массив dns в /etc/docker/daemon.json применяется к каждому новому контейнеру, что звучит аккуратнее, чем есть. Он применяется и когда туннель опущен, и тогда резолвер, доступный только через VPN, ломает обычную загрузку образов. Настройки для отдельного контейнера проще обосновать и проще отменить.

Вариант B: позволить контейнеру использовать сеть хоста

Сеть хоста полностью обходит копию, потому что контейнер использует резолвер хоста и туннель хоста. Она же убирает изоляцию сети, которую вы, вероятно, хотели, и под Docker Desktop ведёт себя иначе. В Linux это прагматичный выбор для разового инструмента, которому нужно разрешать внутренние имена.

Для сборок не годится ни один вариант, поскольку шаги сборки не наследуют флаги времени выполнения. Собирайте с сетью хоста там, где платформа это позволяет, или держите установку зависимостей на этапе, которому не нужен туннель.

Что не исправляет ни один вариант

Адрес DNS бесполезен, если у контейнера нет маршрута к нему. Резолвер VPN обычно находится внутри адресного пространства туннеля, поэтому контейнеру нужен путь к этому префиксу. Стандартный мост Docker обычно маршрутизирует наружу через хост, и этого достаточно, когда у хоста есть маршрут туннеля и включена пересылка. Пользовательские мостовые сети со своими пулами адресов могут столкнуться с подсетью VPN, и тогда запросы уходят совсем в другое место.

Проверьте подсеть сети Docker на соответствие подсети VPN, прежде чем отлаживать сам резолвер. Перекрытие даёт сбой, который выглядит точно как сломанный DNS-сервер.

Проверьте внутри контейнера

Тестируйте с помощью getent hosts db.internal внутри контейнера, а не браузером или языковой средой выполнения, потому что они применяют собственную политику DNS и собственный кеш. Если getent разрешает имя, а приложение всё ещё падает, резолвер теперь правильный, и оставшаяся проблема на уровне приложения. Если он не разрешает, шаг DNS не завершён.

Пересоздайте контейнер после изменения его настроек DNS. Правка /etc/resolv.conf внутри работающего контейнера исчезает вместе с ним и скрывает проблему конфигурации ровно настолько, сколько кому-то нужно, чтобы его перезапустить.

Похожие статьи