DNS: TTL, 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, остальные разбираются в тренажёре.
- Переключили A-запись на новый IP, но часть трафика сутки шла на старый сервер. Почему?A)Записи распространяются по корневым серверам суткиB)Старый сервер отвечал быстрее, и клиенты выбирали егоC)Смена IP требует перевыпуска сертификата, до этого работает старый маршрутD)Резолверы и клиенты держали запись в кэше до истечения TTL
показать ответ и разбор
+D)Резолверы и клиенты держали запись в кэше до истечения TTL// разбор: TTL записи — это разрешение кэшировать её указанное время: провайдерские резолверы, ОС и рантаймы приложений будут отдавать старый адрес, пока срок не истечёт. Потому переезды планируют заранее: за сутки TTL опускают до 60-300 секунд, переключают запись, ждут, потом возвращают обычное значение. Старый сервер держат живым, пока не иссякнет трафик.
- Из пода запрос к api.partner.com резолвится с задержкой, в tcpdump видно пять неудачных запросов подряд. Причина?A)kube-dns отвечает только на внутренние имена, внешние идут по таймаутуB)ndots:5 в resolv.conf: имя сначала перебирается по search-доменамC)IPv6 отключён, и резолвер ждёт таймаут на AAAAD)У пода нет своего резолвера, запросы идут через 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.
- Нужен 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.
- dig api.local отдаёт один IP, а приложение стучится на совсем другой. Куда смотреть?A)В кэш DNS-резолвера — dig его почему-то не видитB)/etc/hosts и порядок nsswitch: файл раньше DNSC)В 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, как само приложение). - Добавили новую A-запись, но приложение ещё несколько минут получает NXDOMAIN, хотя запись уже есть. Почему?A)Резолвер закэшировал отрицательный ответ; его TTL задаёт SOAB)Новая запись ещё не разошлась, DNS реплицируется суткамиC)Клиент держит старое соединение и не перезапрашивает DNSD)TTL самой A-записи слишком большой, надо дождаться его
показать ответ и разбор
+A)Резолвер закэшировал отрицательный ответ; его TTL задаёт SOA// разбор: Резолверы кэшируют и отрицательные ответы (RFC 2308). TTL записи NXDOMAIN ограничен полем negative-cache (minimum) в SOA зоны. Если имя недавно спрашивали и его не было, клиенты продолжают получать NXDOMAIN, пока не истечёт негативный кэш, — даже после того как запись добавили. Если планируешь добавлять имена, которые могли пробивать заранее, держи negative TTL в SOA небольшим.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.