Как диагностировать сбои разрешения DNS в контейнерах Docker

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

Я сталкиваюсь с периодическими сбоями разрешения DNS для внутренних серверов компании (например, mydb.mycompany.net) в моем контейнеризированном приложении на .NET 7. Ошибки отображаются как исключения со стеком вызовов, прерывающимся в моменте разрешения имени. Эти сбои происходят каждые несколько дней и не являются согласованными. Некоторые запросы будут завершаться неудачно из-за проблем с разрешением DNS, некоторые – успешно. Обычно сбои прекращаются через несколько минут или часов.

Вот выдержка из логов демона Docker, показывающая сбои DNS:

Feb 18 09:08:46 myUbuntuVM dockerd[3173690]: time="2025-02-18T09:08:46.778275198-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:52783" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:52783->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 09:08:47 myUbuntuVM dockerd[3173690]: time="2025-02-18T09:08:47.777014788-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:43541" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:43541->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:05:04 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:05:04.311059423-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:36103" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:36103->127.0.0.53:53: i/o timeout" question=";ppt.mycompany.net.\tIN\t A"
Feb 18 11:05:19 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:05:19.232703491-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:41228" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:41228->127.0.0.53:53: i/o timeout" question=";mydb.mycompany.net.\tIN\t A"
Feb 18 11:05:29 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:05:29.976200375-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:53810" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:53810->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:05:30 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:05:30.816163166-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:60524" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:60524->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:05:30 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:05:30.816181135-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:35904" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:35904->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:05:30 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:05:30.816202107-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:42835" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:42835->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:06:14 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:06:14.075792943-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:48602" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:48602->127.0.0.53:53: i/o timeout" question=";telemetry.mycompany.net.\tIN\t A"
Feb 18 11:06:18 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:06:18.077290136-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:41062" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:41062->127.0.0.53:53: i/o timeout" question=";telemetry.mycompany.net.\tIN\t A"
Feb 18 11:09:17 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:09:17.935630694-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:41776" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:41776->127.0.0.53:53: i/o timeout" question=";ppt.mycompany.net.\tIN\t A"
Feb 18 11:09:24 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:09:24.978859801-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:58735" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:58735->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:10:44 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:10:44.060869814-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:34441" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:34441->127.0.0.53:53: i/o timeout" question=";mydb.mycompany.net.\tIN\t A"
Feb 18 11:10:44 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:10:44.124596532-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:58926" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:58926->127.0.0.53:53: i/o timeout" question=";mydb.mycompany.net.\tIN\t A"
Feb 18 11:10:44 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:10:44.463900463-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:43359" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:43359->127.0.0.53:53: i/o timeout" question=";mydb.mycompany.net.\tIN\t A"
Feb 18 11:10:44 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:10:44.509781009-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:56974" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:56974->127.0.0.53:53: i/o timeout" question=";mydb.mycompany.net.\tIN\t A"
Feb 18 11:12:09 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:12:09.169706914-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:60172" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:60172->127.0.0.53:53: i/o timeout" question=";ppt.mycompany.net.\tIN\t A"
Feb 18 11:12:11 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:12:11.779481491-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:60831" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:60831->127.0.0.53:53: i/o timeout" question=";telemetry.mycompany.net.\tIN\t A"
Feb 18 11:12:15 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:12:15.433962276-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:41538" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:41538->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:12:43 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:12:43.275193831-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:57606" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:57606->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:12:44 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:12:44.271722202-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:42726" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:42726->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:16:39 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:16:39.337231433-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:58320" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:58320->127.0.0.53:53: i/o timeout" question=";ppt.mycompany.net.\tIN\t A"
Feb 18 11:19:10 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:19:10.883903477-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:57383" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:57383->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:19:32 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:19:32.489115270-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:48824" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:48824->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:19:33 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:19:33.489227763-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:46159" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:46159->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:28 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:28.367331081-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:48714" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:48714->127.0.0.53:53: i/o timeout" question=";telemetry.mycompany.net.\tIN\t A"
Feb 18 11:30:42 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:42.362106730-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:49773" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:49773->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:42 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:42.368875474-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:44795" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:44795->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:42 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:42.734673764-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:35794" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:35794->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:42 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:42.780385916-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:40332" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:40332->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:42 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:42.780613539-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:50583" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:50583->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:42 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:42.783087559-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:59715" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:59715->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:42 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:42.793575722-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:59408" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:59408->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:42 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:42.793637732-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:35385" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:35385->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"
Feb 18 11:30:43 myUbuntuVM dockerd[3173690]: time="2025-02-18T11:30:43.112342965-08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:127.0.0.1:46130" dns-server="udp:127.0.0.53:53" error="read udp 127.0.0.1:46130->127.0.0.53:53: i/o timeout" question=";storage.mycompany.net.\tIN\t A"

В моей компании есть внутренняя сеть с 2 DNS-серверами.

Хост контейнера Docker – это виртуальная машина Ubuntu 22, настроенная на использование внутренних именовых серверов компании для разрешения имен.

Приложение запускается внутри контейнера Docker, основанного на образе mcr.microsoft.com/dotnet/aspnet:7.0, который, похоже, основан на образе debian 11 slim. Контейнер создается с помощью docker compose и использует автоматически созданную сеть моста docker myapp_default.

Внутри контейнера файл /etc/resolv.conf содержит следующее:

# Generated by Docker Engine.
# This file can be edited; Docker Engine will not make further changes once it
# has been modified.

nameserver 127.0.0.11
search .
options edns0 trust-ad ndots:0

# Based on host file: '/etc/resolv.conf' (internal resolver)
# ExtServers: [host(127.0.0.53)]
# Overrides: []
# Option ndots from: internal

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

Я вижу, что у серверов (например, mydb.mycompany.net) есть записи в кэше systemd-resolved на хосте с разумным временем жизии (TTL) (более 2 часов)

Я вижу это сообщение в логах dockerd при запуске контейнера, но не уверен, является ли это ожидаемым поведением или указывает на проблему с конфигурацией.

Feb 12 12:37:46 myCompanyVMHostname dockerd[3173690]: time="2025-02-12T12:37:46.979459646-08:00" level=info msg="detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: /run/systemd/resolve/resolv.conf

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

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

Чтобы диагностировать сбои разрешения DNS в Docker-контейнерах, необходимо учитывать множество факторов, так как проблема может заключаться как на уровне хоста, так и внутри контейнера. В приведенной вами ситуации, где сбой наблюдается в .NET 7 приложении, работающем в контейнере на базе образа Debian 11, первым делом следует исследовать различные аспекты сетевой настройки.

Теория: Разрешение DNS в Docker

Для начала стоит понять, как происходит разрешение DNS внутри контейнеров Docker. По умолчанию Docker использует собственный DNS-сервер для контейнеров (127.0.0.11), который затем перенаправляет запросы на DNS-сервера хоста, когда они не могут быть разрешены локально. Этот механизм предполагает, что контейнеры способны обращаться к тому же пулу DNS-серверов, что и сам хост, при наличии у последних доступа к интернету или корпоративной сети.

Проблемы разрешения имен могут возникать из-за различных причин, включая:

  1. Неправильные сетевые настройки контейнера: Если между контейнером и хостом существует конфликт или некорректная настройка, это может вызвать проблемы с разрешением имен.

  2. Проблемы с производительностью DNS-сервера: Временные сбои и задержки на DNS-сервере могут привести к сбоям в разрешении имен.

  3. Конфликты с системным настроением DNS: Использование системных помощников, таких как systemd-resolved, может влиять на поведение DNS, если они настроены неправильно.

Пример: Анализ журналов Docker

Ваши журналы Docker показывают ошибки с тайм-аутом при попытке разрешения определенных доменных имен через 127.0.0.53. Это указывает на возможную проблему с вашим системным разрешением имен. Также важно учесть, что ошибки происходят нерегулярно, что может свидетельствовать о временных перегрузках DNS-сервера или проблемах с сетью.

Сообщение “detected 127.0.0.53 nameserver” указывает, что Docker замечает systemd-resolved настроенный на стороне хоста, однако это возможно не учитывается должным образом при переписывании файла resolv.conf в контейнере.

Применение: Шаги по диагностике и устранению проблемы

  1. Проверка конфигурации DNS на хосте:

    • Убедитесь, что systemd-resolved настроен правильно. Проверьте содержимое файла /run/systemd/resolve/resolv.conf и убедитесь, что он содержит правильные DNS-серверы вашей компании.
    • Запустите команду resolvectl status на хосте, чтобы убедиться, что systemd-resolved функционирует корректно и передает запросы, как ожидается.
  2. Анализ /etc/resolv.conf в контейнере:

    • Проверьте, что файл /etc/resolv.conf не был изменен вручную и содержит правильные настройки от Docker.
    • Подумайте о том, чтобы временно заменить 127.0.0.11 на конкретные DNS-серверы хоста в этом файле для проверки влияния на разрешение DNS.
  3. Сетевая диагностика и мониторинг:

    • Используйте команды ping, dig, и nslookup как на хосте, так и внутри контейнера для проверки соединения с DNS-серверами и быстродействия разрешения имен.
    • Проследите поведение сети с помощью tcpdump для обнаружения возможных сетевых проблем или задержек.
  4. Логирование и мониторинг DNS-серверов:

    • Мониторьте ваши внутренние DNS-серверы на предмет нагрузки и ошибок.
    • Рассмотрите возможность увеличения значений тайм-аута и ретрансляции запросов к другим серверам для проверки влияния на стабильность разрешения.
  5. Тестирование с отключением кеширования:

    • Попробуйте отключить кеширование DNS на время (resolvectl flush-caches и systemctl restart systemd-resolved), чтобы проверить, связано ли поведение с состоянием кеша.
  6. Обновление и патчи:

    • Обратите внимание на версии вашего .NET приложения, Docker двигателя и системных библиотек, так как обновления могут содержать исправления для известных проблем.

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

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

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