Как избежать попытки curl разрешить имена через IPv6

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

Когда я пытаюсь использовать 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 проблема все еще сохраняется, особенно в контексте использования имени хоста.

Решения

  1. Явное указание IPv4:
    Наиболее простым и эффективным решением является использование параметра -4, который принуждает curl использовать только IPv4. Например:

    curl -4 http://имя_контейнера

    Это решение может быть временным, но оно гарантирует отсутствие задержек.

  2. Изменение конфигурации gai.conf:
    Если вы хотите изменить поведение разрешения имен для всех приложений (включая curl), вы можете отредактировать файл /etc/gai.conf. Откомментировав строку:

    precedence ::ffff:0:0/96 100

    вы приоритизируете IPv4-адреса по сравнению с IPv6 при разрешении имен. Однако, это затронет все сетевые утилиты и может вызвать несовпадение в зависимости от ваших других сетевых приложений, использующих IPv6.

  3. Настройка резолвера DNS:
    Проверьте, какой DNS-резолвер используется в вашем контейнере. Часто задержки вызваны DNS-сервером, который может неверно обрабатывать запросы. Убедитесь, что у вас правильные настройки в файле /etc/resolv.conf. Вы можете попробовать использовать общедоступные DNS-серверы, такие как Google DNS (8.8.8.8 и 8.8.4.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.

  5. Проверка iptables:
    Убедитесь, что ваши правила iptables правильно настроены для блокировки IPv6. Например, вы можете использовать следующее правило, чтобы заблокировать все входящие и исходящие соединения по IPv6:

    ip6tables -A INPUT -j DROP
    ip6tables -A OUTPUT -j DROP

Заключение

Каждое из этих решений имеет свои плюсы и минусы в зависимости от вашего окружения и требований к сетевым протоколам. Однако использование параметра -4 является самым простым и быстрым способом избежать задержек без многоуровневых изменений в конфигурациях. Если у вас есть необходимость более глобально управлять сетевыми настройками, внедрение изменений в gai.conf и конфигурацию IPv6 может быть более адекватным подходом. Убедитесь, что тестируете каждое решение, чтобы определить, какое из них наиболее эффективно в вашем конкретном случае.

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

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