сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Сети

DNS: TTL, search-домены, записи

DNS: кэш, search-домены, вершина зоны

Спросил адрес нашего домена у сервера, который этот домен обслуживает: 36, 34 и 42 миллисекунды на три попытки. Спросил то же самое у резолвера на этой машине: 0, 1 и 1 миллисекунда. Разница в тридцать раз и есть весь DNS в одном опыте - почти всегда отвечает кэш, а не источник.

Стержень: ответ разрешено хранить указанное в нём время, и до конца этого срока никто не узнает, что запись поменялась.

// Формулировки: «сменили адрес, трафик сутки шёл на старый сервер», «почему резолв внутри кластера медленный?», «почему нельзя поставить CNAME на домен без www?»

Срок жизни ответа

Резолвер - это служба, которая по имени находит адрес. Своих данных у неё нет: она спрашивает серверы, отвечающие за зону, и складывает ответ в кэш - память о недавних ответах, чтобы не спрашивать снова. Насколько долго его можно там держать, говорит само число в ответе - TTL (time to live). У нашего домена это 600 секунд.

Проверил, как это выглядит. Три замера с паузой в четыре секунды дали остаток 534, 530 и 526 секунд: ответ всё это время лежал в кэше, а счётчик тикал вниз. А сервер зоны на тот же вопрос неизменно отвечает полными 600 - у него счётчик не идёт. Когда остаток дойдёт до нуля, резолвер сходит за свежим ответом.

// Отсюда процедура переезда, а не надежда на удачу. За сутки до смены адреса срок опускают до минуты-пяти, ждут, пока по старому значению истекут все кэши, меняют запись, дожидаются перетекания трафика и возвращают обычный срок. Старый сервер держат живым, пока на него ещё идут запросы. И отдельно проверяют приложения, которые узнают адрес один раз при запуске и потом держат его в памяти: им никакой срок не указ, их надо перезапускать.

резолвер
служба, которая находит адрес по имени и кэширует ответ
TTL
сколько ответ разрешено хранить в кэше
зона
часть дерева имён, за которую отвечают конкретные серверы

Ответ «такого имени нет» и файл hosts

Отсутствие записи - тоже ответ, и он тоже кэшируется. Спросил несуществующее имя в нашей зоне: первый раз ответ NXDOMAIN пришёл за 36 миллисекунд, второй раз за 1. Сколько разрешено помнить, что имени нет, написано в служебной записи зоны SOA (start of authority): у нас это 300 секунд. Поэтому только что созданная запись иногда «не видна» ещё несколько минут, и это не поломка.

Вторая вещь, которая ломает разбор полётов, - файл hosts. Он сильнее любого сервера имён, потому что смотрят в него раньше. Проверил в контейнере: обычный резолв нашего домена даёт настоящий адрес 147.45.234.86, а тот же контейнер с одной подсунутой строкой в hosts уверенно отвечает 10.9.9.9.

// Из этой пары растёт половина историй «у меня работает, у тебя нет». Прежде чем винить сеть, стоит посмотреть, что вообще отвечает на имя на конкретной машине, и сравнить с тем, что отдаёт сервер зоны. Заодно полезно помнить: у одного имени бывает несколько разных записей - адрес, серверы имён зоны, почтовые серверы, текстовые. У нашего домена, например, четыре сервера имён и две почтовые записи с разным приоритетом.

NXDOMAIN
ответ «такого имени не существует»; тоже кэшируется
SOA
служебная запись зоны; в ней и срок хранения отрицательных ответов
файл hosts
локальный список соответствий; смотрят в него раньше сервера имён

search-домены: лишние вопросы перед правильным ответом

Резолвер читает настройки из /etc/resolv.conf. Там три интересные строки: nameserver - куда спрашивать, search - какие суффиксы дописывать к неполным именам, options ndots - сколько точек должно быть в имени, чтобы считать его полным и спросить как есть.

В кластере, то есть в группе машин, где сервисы разложены по своим отсекам, обычно стоит ndots со значением 5 и пара search-доменов. Значит, имя api.github.com с двумя точками считается неполным: сначала спросят api.github.com.svc.cluster.local, потом api.github.com.cluster.local, получат отказ на оба и только третьим вопросом спросят настоящее имя. Замерил в контейнере с такими настройками: 5,81 миллисекунды на попытку против 1,03 у того же имени с точкой на конце. Точка на конце означает «имя полное, не дописывай ничего».

// Пятикратная разница на каждом обращении к внешнему сервису - это заметно, когда обращений тысячи. Лечится точкой в конце имени в настройках приложения или своими настройками резолвера для конкретного приложения с меньшим значением ndots.

// Отдельное правило, о котором спрашивают: на вершине зоны, то есть на домене без поддомена, нельзя поставить псевдоним CNAME. Причина механическая: CNAME означает «у этого имени больше нет никаких своих записей», а на вершине зоны обязаны лежать SOA и записи серверов имён. Поэтому провайдеры дают свою замену, ALIAS, которая раскрывает цель на их стороне и отдаёт готовый адрес.

search-домены
суффиксы, которые резолвер дописывает к неполному имени
ndots
порог точек, после которого имя считают полным
вершина зоны
сам домен без поддомена; там уже есть служебные записи

Как отвечать: «Сменили адрес домена, но часть трафика сутки шла на старый сервер. Почему?»

Из-за срока хранения ответа. У каждой записи есть время, в течение которого её разрешено держать в кэше, и пока оно не вышло, резолверы провайдеров, операционные системы и сами приложения отдают старый адрес. Я это видел вживую: сервер зоны на каждый вопрос отвечает полным сроком, а локальный кэш отдаёт тот же ответ с убывающим счётчиком и в источник не ходит. Поэтому переезд готовят заранее: за сутки опускают срок до минуты-пяти, ждут истечения старых кэшей, меняют запись, дожидаются перетекания трафика и возвращают обычное значение. Старый сервер держат живым, пока на него идут запросы. И отдельно перезапускаю сервисы, которые узнают адрес один раз при старте: им срок хранения ничего не диктует.

Ответ объясняет механику, даёт готовую процедуру и вспоминает про клиентов, которые кэшируют адрес сами. Последнее обычно и оказывается тем самым хвостом на сутки.

На чём валятся

  • Меняют адрес, не снизив срок хранения заранее, и ждут переезда сутки.
  • Забывают, что ответ «имени нет» тоже кэшируется, и паникуют из-за новой записи.
  • Списывают медленный резолв на сеть, не заглянув в настройки резолвера.
  • Не проверяют файл hosts на машине, где «не работает».
  • Пробуют поставить псевдоним на вершину зоны и упираются в отказ.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 6, остальные разбираются в тренажёре.

  1. #dvo_net_dns1 / 5
    Переключили A-запись на новый IP, но часть трафика сутки шла на старый сервер. Почему?
    A)Записи распространяются по корневым серверам сутки
    B)Старый сервер отвечал быстрее, и клиенты выбирали его
    C)Смена IP требует перевыпуска сертификата, до этого работает старый маршрут
    D)Резолверы и клиенты держали запись в кэше до истечения TTL
    показать ответ и разбор
    +D)Резолверы и клиенты держали запись в кэше до истечения TTL

    // разбор: TTL записи — это разрешение кэшировать её указанное время: провайдерские резолверы, ОС и рантаймы приложений будут отдавать старый адрес, пока срок не истечёт. Потому переезды планируют заранее: за сутки TTL опускают до 60-300 секунд, переключают запись, ждут, потом возвращают обычное значение. Старый сервер держат живым, пока не иссякнет трафик.

  2. #dvo_net_dns2 / 5
    Из пода запрос к api.partner.com резолвится с задержкой, в tcpdump видно пять неудачных запросов подряд. Причина?
    A)kube-dns отвечает только на внутренние имена, внешние идут по таймауту
    B)ndots:5 в resolv.conf: имя сначала перебирается по search-доменам
    C)IPv6 отключён, и резолвер ждёт таймаут на AAAA
    D)У пода нет своего резолвера, запросы идут через API-сервер
    показать ответ и разбор
    +B)ndots:5 в resolv.conf: имя сначала перебирается по search-доменам

    // разбор: В кластере resolv.conf пода содержит options ndots:5: имя, где меньше пяти точек, считается неполным, и резолвер сначала перебирает search-домены — namespace.svc.cluster.local, svc.cluster.local, cluster.local. Для внешних имён это лишние отказы перед правильным ответом. Лечится точкой в конце имени (api.partner.com.) или своим dnsConfig с меньшим ndots.

  3. #dvo_net_dns3 / 5
    Нужен example.com (без www) на балансировщик, у которого только DNS-имя. Почему нельзя просто поставить CNAME?
    A)На вершине зоны уже есть SOA и NS, а CNAME не уживается с другими записями
    B)CNAME работает только для поддоменов третьего уровня и ниже
    C)CNAME разрешён лишь на записи внутри той же зоны
    D)Почта сломается: CNAME отменяет MX-записи домена
    показать ответ и разбор
    +A)На вершине зоны уже есть SOA и NS, а CNAME не уживается с другими записями

    // разбор: По стандарту у имени с CNAME не может быть других записей, а на вершине зоны обязательно живут SOA и NS — потому CNAME туда не ставится. Обходы: A-запись на статический адрес, ALIAS/ANAME у провайдера DNS (он сам резолвит цель и отдаёт A) либо редирект с apex на www на уровне HTTP.

  4. #dvo_net_dns4 / 5
    dig api.local отдаёт один IP, а приложение стучится на совсем другой. Куда смотреть?
    A)В кэш DNS-резолвера — dig его почему-то не видит
    B)/etc/hosts и порядок nsswitch: файл раньше DNS
    C)В TTL записи — dig показывает уже устаревшее значение
    D)В фаервол — это он подменяет адрес назначения пакетов
    показать ответ и разбор
    +B)/etc/hosts и порядок nsswitch: файл раньше DNS

    // разбор: Порядок разрешения имён задаёт /etc/nsswitch.conf (обычно hosts: files dns): источник files (/etc/hosts) проверяется раньше DNS. Запись в /etc/hosts перебивает то, что вернул бы DNS, а dig ходит прямо в DNS, минуя hosts, — поэтому dig и приложение расходятся. Проверяй /etc/hosts и getent hosts api.local (он идёт по nsswitch, как само приложение).

  5. #dvo_net_dns5 / 5
    Добавили новую A-запись, но приложение ещё несколько минут получает NXDOMAIN, хотя запись уже есть. Почему?
    A)Резолвер закэшировал отрицательный ответ; его TTL задаёт SOA
    B)Новая запись ещё не разошлась, DNS реплицируется сутками
    C)Клиент держит старое соединение и не перезапрашивает DNS
    D)TTL самой A-записи слишком большой, надо дождаться его
    показать ответ и разбор
    +A)Резолвер закэшировал отрицательный ответ; его TTL задаёт SOA

    // разбор: Резолверы кэшируют и отрицательные ответы (RFC 2308). TTL записи NXDOMAIN ограничен полем negative-cache (minimum) в SOA зоны. Если имя недавно спрашивали и его не было, клиенты продолжают получать NXDOMAIN, пока не истечёт негативный кэш, — даже после того как запись добавили. Если планируешь добавлять имена, которые могли пробивать заранее, держи negative TTL в SOA небольшим.

дальше

Теорию прочитали. Навык ставится повторением

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