Nginx: resolver: domain name not found in DNS cache — Решение
При использовании переменных в директиве proxy_pass или обращении к внешним облачным сервисам (AWS S3, RDS, микросервисы) Nginx возвращает ошибку 502 Bad Gateway. В error.log регистрируется сбой разрешения сетевого имени: domain name not found in DNS cache / no resolver defined to resolve example.internal или host not found in resolver "127.0.0.53".
| Тип proxy_pass | Поведение DNS в Nginx | Точка отказа |
|---|---|---|
Статический: proxy_pass http://api.com; | Резолвится строго 1 раз при старте Nginx | Если IP изменился в runtime, Nginx шлет запросы на старый адрес |
Динамический: proxy_pass http://$target; | Требует явного объявления resolver | При отсутствии resolver Nginx падает с 502 ошибкой |
| IPv6 Resolver default | Запрашивает A и AAAA записи параллельно | Таймаут, если локальная сеть не маршрутизирует IPv6 |
- Nginx не может определить актуальный IP-адрес бэкенда в динамических средах (Kubernetes Services, AWS ALB, Docker Swarm).
- При перезапуске контейнеров с новыми IP-адресами веб-сервер продолжает отправлять запросы в пустоту.
- Объявите директиву
resolverс указанием надежного системного или инфраструктурного DNS-сервера в блокеhttpилиserver:# Для Linux систем с systemd-resolved: resolver 127.0.0.53 valid=10s ipv6=off; # Для Docker / Kubernetes DNS: # resolver 127.0.0.11 valid=5s ipv6=off; # Docker internal DNS # resolver 10.96.0.10 valid=5s ipv6=off; # Kube-DNS / CoreDNS # Публичные DNS (если бэкенд во внешнем интернете): # resolver 1.1.1.1 8.8.8.8 valid=30s ipv6=off; - Установите тайм-аут ожидания DNS ответа (
resolver_timeout):resolver_timeout 5s; - Используйте промежуточную переменную в
proxy_pass, чтобы заставить Nginx выполнять регулярный DNS-резолвинг по истечении времениvalid:location /service/ { set $backend_host "app.internal.domain"; proxy_pass http://$backend_host:8080$request_uri; } - Проверьте синтаксис файлов конфигурации:
sudo nginx -t. - Примените изменения:
sudo systemctl reload nginx.
ipv6=off в директиве resolver предотвращает задержки и сбои, когда upstream не имеет AAAA-записей, избавляя Nginx от ожидания ответа по IPv6-стеку.Частые вопросы (FAQ)
Почему статический proxy_pass не обновляет IP бэкенда?
По умолчанию Nginx резолвит DNS-имена из статических директив proxy_pass только один раз в момент запуска мастер-процесса. Если IP изменился в DNS, Nginx узнает об этом только после reload.
Что дает конструкция с переменной set $upstream ...; proxy_pass http://$upstream;?
Использование переменной заставляет Nginx использовать динамический runtime DNS resolver, который периодически заново запрашивает IP-адрес согласно параметру valid=... в директиве resolver.
Какой IP адрес DNS сервера используется в Docker по умолчанию?
Во встроенной сети Docker (user-defined bridge) встроенный DNS-сервер всегда доступен по адресу 127.0.0.11.
Что произойдет при недоступности DNS сервера, указанного в resolver?
Nginx не сможет получить IP-адрес для dynamic upstream и вернет клиенту ошибку 502 Bad Gateway с записью 'host not found in resolver' в логе.