Вопрос или проблема
Когда я пытаюсь использовать curl из контейнера Docker для обращения к ‘другому имени контейнера’, curl сначала пытается разрешить имя в IPv6. Это вызывает задержку в несколько секунд, потому что веб-сервер недоступен по ipv6.
Я удалил ссылочный локальный адрес на интерфейсе контейнера и также отключил ipv6 на интерфейсах lo и eth0 контейнера. curl все равно пытается сначала разрешить имя в IPv6 (если это не принудительно указано через curl -4).
Это кажется неправильным. Почему curl пытается разрешить имя в ipv6, даже если ipv6 отключен?
В моем случае, глобальное отключение IPv6 не работает
Я все еще наблюдаю 5-секундную задержку “инициализации”.
Только аргумент -4
работает.
(То же самое происходит с командой wget
)
Я также пытался заставить iptables отклонять трафик IPV6.
↪ Ничего не меняется
DNS
Мои тесты показывают, что именно разрешение имен вызывает эту задержку.
Если я вызываю URL-адрес, основанный на IP, это происходит мгновенно.
Странно, но само разрешение имен, выполненное с помощью nslookup
, является мгновенным (и не содержит ответа IPV6)
Вы можете изменить это поведение, отредактировав /etc/gai.conf
и раскомментировав precedence ::ffff:0:0/96 100
.
Тем не менее, это повлияет на большее количество, чем просто curl
.
Ответ или решение
Чтобы избежать попыток разрешения имен в IPv6 с помощью команды curl в контейнере Docker, следует учесть несколько аспектов настройки сети и конфигурации DNS. Этим вопросом часто задаются пользователи, работающие с многоуровневыми приложениями, где контейнеры могут сильно зависеть от сетевых настроек.
Причины проблемы
При использовании curl для разрешения имени другой контейнер в Docker, по умолчанию система пытается выполнить разрешение через IPv6, что может вызвать задержку, если IPv6 не настроен или не доступен. Вы заметили, что при отключении IPv6 на интерфейсах контейнера и при использовании iptables для блокировки IPv6 проблема все еще сохраняется, особенно в контексте использования имени хоста.
Решения
-
Явное указание IPv4:
Наиболее простым и эффективным решением является использование параметра-4
, который принуждает curl использовать только IPv4. Например:curl -4 http://имя_контейнера
Это решение может быть временным, но оно гарантирует отсутствие задержек.
-
Изменение конфигурации gai.conf:
Если вы хотите изменить поведение разрешения имен для всех приложений (включая curl), вы можете отредактировать файл/etc/gai.conf
. Откомментировав строку:precedence ::ffff:0:0/96 100
вы приоритизируете IPv4-адреса по сравнению с IPv6 при разрешении имен. Однако, это затронет все сетевые утилиты и может вызвать несовпадение в зависимости от ваших других сетевых приложений, использующих IPv6.
-
Настройка резолвера DNS:
Проверьте, какой DNS-резолвер используется в вашем контейнере. Часто задержки вызваны DNS-сервером, который может неверно обрабатывать запросы. Убедитесь, что у вас правильные настройки в файле/etc/resolv.conf
. Вы можете попробовать использовать общедоступные DNS-серверы, такие как Google DNS (8.8.8.8
и8.8.4.4
), чтобы проверить, не связана ли проблема с вашим текущим резолвером. -
Отключение IPv6 на уровне хоста:
Несмотря на то что вы упомянули о том, что глобальное отключение IPv6 не помогает, вы можете также попытаться добавить следующие настройки в/etc/sysctl.conf
:net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1
После редактирования, примените изменения командой:
sudo sysctl -p
Это могло бы повлиять на все сетевые интерфейсы, включая Docker.
-
Проверка iptables:
Убедитесь, что ваши правила iptables правильно настроены для блокировки IPv6. Например, вы можете использовать следующее правило, чтобы заблокировать все входящие и исходящие соединения по IPv6:ip6tables -A INPUT -j DROP ip6tables -A OUTPUT -j DROP
Заключение
Каждое из этих решений имеет свои плюсы и минусы в зависимости от вашего окружения и требований к сетевым протоколам. Однако использование параметра -4
является самым простым и быстрым способом избежать задержек без многоуровневых изменений в конфигурациях. Если у вас есть необходимость более глобально управлять сетевыми настройками, внедрение изменений в gai.conf
и конфигурацию IPv6 может быть более адекватным подходом. Убедитесь, что тестируете каждое решение, чтобы определить, какое из них наиболее эффективно в вашем конкретном случае.