Проблемы с разрешением имён контейнеров - одна из частых причин сбоев в Docker-окружениях. Эта статья даёт полное понимание работы DNS в Docker, от базовых принципов до продвинутых сценариев с внешними серверами. Вы получите готовые команды для настройки service discovery, алгоритм диагностики типичных ошибок и рекомендации по выбору стратегии DNS для проектов 2026 года.
Как работает DNS в Docker: основа для понимания и отладки
Каждый контейнер Docker по умолчанию получает встроенный DNS-сервер с IP-адресом 127.0.0.11. Этот сервис автоматически создаёт DNS-записи для всех контейнеров, запущенных в одной пользовательской сети. Записи включают имя контейнера, его алиасы и сетевые алиасы, указанные при создании. Путь DNS-запроса определяется файлом /etc/resolv.conf внутри контейнера, где 127.0.0.11 указан как первый nameserver. Поведение встроенного DNS может различаться в зависимости от версии Docker Engine, поэтому важно проверять актуальность инструкций для 2026.x.
Встроенный DNS-сервер Docker: архитектура и ограничения
Встроенный DNS Docker работает «из коробки» для простых сценариев: мультиконтейнерные приложения в одной пользовательской bridge-сети, где контейнеры находят друг друга по имени сервиса. Однако у этого решения есть границы. Оно не поддерживает условный форвардинг запросов, сложную маршрутизацию по доменным зонам и интеграцию с внешними DNS-серверами корпоративной сети. Если вашему приложению нужно разрешать имена хостов из локальной сети компании или делегировать запросы для определённых доменов, встроенного DNS будет недостаточно. В таких случаях требуется настройка внешнего решения - CoreDNS или dnsmasq. Официальная документация Docker по сетевой модели рекомендует использовать встроенный DNS для service discovery внутри изолированных сетей.
Практика: настройка DNS в bridge-сетях с автоматическим service discovery
Для работы автоматического обнаружения сервисов необходимо создать пользовательскую bridge-сеть. Стандартная сеть bridge (docker0) не предоставляет встроенного DNS. Создайте сеть с явным указанием подсети для контроля адресного пространства:
docker network create --driver bridge --subnet 172.28.0.0/16 --gateway 172.28.0.1 app_network
Запустите контейнеры в этой сети, указав имена. Docker автоматически зарегистрирует их во встроенном DNS:
docker run -d --name web_app --network app_network nginx:alpine
docker run -d --name database --network app_network postgres:15
Теперь внутри контейнера web_app вы можете обратиться к контейнеру database по имени. Проверьте работу:
docker exec web_app ping database
docker exec web_app dig @127.0.0.11 database
Для управления группой сервисов используйте docker-compose. Файл docker-compose.yml ниже создаёт сеть и определяет сервисы, имена которых станут DNS-именами.
Пример: развёртывание веб-приложения с БД и автоматическим резолвингом
version: '3.8'
services:
nginx:
image: nginx:alpine
networks:
- app-net
depends_on:
- app
app:
image: python:3.11-alpine
command: python app.py
networks:
- app-net
environment:
- DB_HOST=database
database:
image: postgres:15
networks:
- app-net
environment:
POSTGRES_DB: mydb
networks:
app-net:
driver: bridge
ipam:
config:
- subnet: 172.29.0.0/24
После запуска docker-compose up -d сервис app сможет подключиться к database по этому имени. Для проверки выполните docker-compose exec app ping database.
Особенности default bridge сети: почему service discovery там не работает
Сеть bridge по умолчанию (docker0) не поддерживает встроенный DNS-сервер и автоматическое обнаружение сервисов. Контейнеры в этой сети могут общаться только по IP-адресам, которые назначаются динамически и могут меняться. Устаревший флаг --link предоставляет ограниченный резолвинг через файл /etc/hosts, но он считается legacy и не рекомендуется к использованию. Правильная практика - всегда создавать пользовательские bridge-сети для взаимодействующих контейнеров. Это обеспечивает изоляцию, безопасность и стабильную работу DNS. Подробнее о создании и управлении пользовательскими сетями читайте в руководстве «Настройка пользовательской Docker bridge-сети».
Диагностика проблем с DNS: алгоритм отладки и типичные ошибки
Если имена контейнеров не разрешаются, следуйте чёткому алгоритму диагностики. Этот подход поможет быстро локализовать проблему.
- Проверьте файл
/etc/resolv.confвнутри контейнера:docker exec <container_name> cat /etc/resolv.conf. Первым nameserver должен быть 127.0.0.11. - Убедитесь, что встроенный DNS-сервер доступен:
docker exec <container_name> nc -zv 127.0.0.11 53. - Выполните прямой DNS-запрос с помощью
digилиnslookup:docker exec <container_name> dig @127.0.0.11 <target_service_name>. - Проверьте, находятся ли контейнеры в одной сети:
docker network inspect <network_name>и найдите разделContainers. - Изучите логи Docker daemon на предмет сетевых ошибок:
journalctl -u docker --since "5 minutes ago".
Типичные ошибки включают: конфликт подсетей при использовании macvlan, неправильный MTU в overlay-сетях, блокировку порта 53 фаерволом на хосте, а также использование устаревших сетевых драйверов.
Инструменты для диагностики: dig, nslookup и docker network inspect
Команда dig даёт детальную информацию о DNS-запросе. Используйте её внутри контейнера для проверки работы встроенного DNS:
docker exec web_app dig @127.0.0.11 database.app-net
; Ответ должен содержать секцию ANSWER с IP-адресом контейнера database.
; Если её нет - проблема с регистрацией имени в DNS.
Команда docker network inspect показывает всю конфигурацию сети, включая подключённые контейнеры и их IP-адреса. Для фильтрации информации о DNS выполните:
docker network inspect app-net --format '{{ json .IPAM.Config }}' | jq .
docker network inspect app-net --format '{{ json .Containers }}' | jq .
Проблема резолвинга имён хоста из контейнера
Контейнеры используют свой DNS и по умолчанию не видят записи из домена хостовой машины или локальной корпоративной сети. Попытка обратиться к внутреннему сервису по имени хоста (например, internal-api.company.local) завершится ошибкой. Есть несколько решений.
- Использование
extra_hostsв docker-compose: явно добавить записи в файл/etc/hostsконтейнера. - Проброс host-файла: использовать флаг
--add-hostпри запуске:docker run --add-host=host.docker.internal:host-gateway .... - Настройка условного форвардинга через внешний DNS: развернуть CoreDNS, который будет перенаправлять запросы для определённых доменов на корпоративные DNS-серверы.
Решение host.docker.internal автоматически резолвится в адрес хоста на Docker Desktop для Mac/Windows, но на Linux требует ручной настройки. Для комплексной диагностики и исправления сетевых проблем обратитесь к практическому руководству «Практическое устранение сетевых проблем Docker».
Продвинутые сценарии: overlay, macvlan и интеграция с внешним DNS
Когда приложение масштабируется на несколько хостов или требует прямого доступа к физической сети, стандартные bridge-сети перестают работать. В этих случаях используются драйверы overlay и macvlan.
DNS в Swarm кластере: service discovery для глобальных сервисов
В Docker Swarm сервисы развёртываются на нескольких нодах. Встроенный DNS Swarm возвращает не IP конкретного контейнера, а Virtual IP (VIP) сервиса. Запрос dig @127.0.0.11 my_service вернёт этот VIP, а трафик будет сбалансирован через routing mesh. Для получения IP-адресов всех конкретных экземпляров (тасков) используйте специальное DNS-имя tasks.my_service. Это полезно для приложений, которым нужен прямой доступ к репликам. Настройка пользовательских overlay-сетей в Swarm позволяет изолировать трафик разных приложений. Подробный гайд по развёртыванию кластера смотрите в статье «Docker Swarm 2026: практическое руководство по оркестрации».
Замена встроенного DNS на CoreDNS или dnsmasq: пошаговая настройка
Если вам нужен условный форвардинг, кастомные доменные зоны или интеграция с инфраструктурой, замените встроенный DNS. CoreDNS - гибкое решение с системой плагинов, ставшее стандартом в Kubernetes. dnsmasq - легковесный сервер, подходящий для простых сценариев.
Развёртывание CoreDNS в Docker:
- Создайте конфигурационный файл
Corefile:
.:53 {
forward . 8.8.8.8 1.1.1.1
log
errors
}
company.local:53 {
forward . 10.0.0.1 10.0.0.2
}
docker.internal:53 {
file /etc/coredns/docker.internal.db
}
- Запустите контейнер CoreDNS, подключив его ко всем необходимым Docker-сетям:
docker run -d --name coredns \
--network app_network \
--network another_network \
-p 53:53/udp \
-v $(pwd)/Corefile:/Corefile \
coredns/coredns:latest
- Перенастройте контейнеры приложений, указав IP-адрес контейнера CoreDNS в качестве DNS-сервера через флаг
--dnsили опцию сети--dnsвdocker network create.
Эта конфигурация позволит контейнерам резолвить имена в зоне company.local через корпоративные серверы, а все остальные запросы - через публичные резолверы. Для понимания общей сетевой архитектуры Docker изучите руководство «Сетевые драйверы Docker: bridge, host и overlay».
Выбор стратегии DNS: сводная таблица и рекомендации на 2026
Выбор решения зависит от сложности среды, требований к интеграции и масштаба.
| Сценарий использования | Рекомендуемое решение | Критерии выбора | Примечания (Docker 2026.x) |
|---|---|---|---|
| Простой проект, несколько контейнеров на одном хосте | Встроенный DNS Docker в пользовательской bridge-сети | Простота, нулевая настройка | Работает «из коробки». Всегда создавайте пользовательские сети. |
| Кластер Docker Swarm, распределённые сервисы | Встроенный DNS Swarm + overlay-сети | Масштабируемость, встроенная балансировка (VIP) | Используйте tasks.<service_name> для прямого доступа к таскам. |
| Гибридная среда, интеграция с локальной сетью, кастомные зоны | Внешний DNS-сервер (CoreDNS) | Гибкость, поддержка условного форвардинга, плагины | Требует дополнительного контейнера и настройки. Используйте для сложных корпоративных сред. |
| Лёгкое решение для условного форвардинга на одном хосте | dnsmasq в контейнере | Лёгковесность, простота конфигурации | Подходит для домашних лабораторий и небольших развёртываний. |
Общая рекомендация: начинайте со встроенного DNS Docker. Переходите на внешние решения только при явной необходимости - интеграции с внешними DNS-зонами или реализации сложной логики маршрутизации запросов. Регулярно сверяйтесь с официальной документацией Docker по сетевым функциям, так как поведение может меняться в новых мажорных версиях. Для комплексного подхода к безопасности и оптимизации Docker-сред ознакомьтесь с материалом «Продвинутый Docker в 2026».
Для автоматизации работы с различными AI-моделями, которые могут помочь в генерации конфигураций или анализе логов, можно использовать агрегатор AiTunnel. Он предоставляет единый API для более чем 200 моделей, включая GPT, Gemini и Claude, с оплатой в рублях и без необходимости VPN.