DNS: A/AAAA, CNAME, TTL, кэш, split horizon

О лекции

Резолв имени — это записи A и AAAA, цепочки CNAME, TTL и несколько кэшей. Split horizon отдаёт разные ответы на одно имя внутри сети и снаружи.

Транспорт и DNS http собеседование

Приложение почти никогда не ходит сразу к корневым серверам. Клиент спрашивает рекурсивный резолвер: systemd-resolved, CoreDNS в кластере, DNS провайдера, 8.8.8.8. Резолвер отвечает из кэша или идёт по иерархии: root → TLD → authoritative NS.

Хендлер уже видит IP. Или таймаут резолва, который легко спутать с «сервис мёртв».

Запись A — IPv4. AAAA — IPv6. Dual-stack клиент может выбрать «не тот» адрес: IPv6 есть в DNS, а маршрут до него плохой. Happy Eyeballs как раз про эту гонку.

Записи и цепочка

CNAME — алиас: «это имя на самом деле другое имя». Цепочка CNAME плюс низкий TTL — лишние круги до TCP connect. MX, TXT, SRV к обычному HTTP не относятся, но на интервью всплывают.

CNAME нельзя повесить на вершину зоны так же свободно, как A. Практика: приложение резолвит имя сервиса, а не хардкодит IP. В Kubernetes имя orders.svc — тоже DNS, только зона кластера.

Пример. Запрос на https://api.example.com. Сначала CNAME на lb.example.net. Потом A = 203.0.113.10. Только после этого TCP connect. Если CNAME ещё и на другой CNAME — это ещё один round-trip.

// GET https://api.example.com
//   stub → 8.8.8.8 / CoreDNS
//   CNAME api.example.com → lb.example.net
//   A     lb.example.net  → 203.0.113.10
//   AAAA  lb.example.net  → 2001:db8::10
//
// Go: ips, err := net.LookupIP("api.example.com")
// TTL низкий → смена IP быстрее, резолверов спросят чаще
// TTL высокий → меньше DNS, дольше «старый» адрес

A и AAAA — адреса, CNAME — алиас. Низкий TTL ускоряет смену IP ценой частых запросов к резолверу.

TTL и чей это кэш

TTL говорит, сколько секунд ответ можно помнить. Кэш есть у резолвера ОС, у glibc/nscd, у sidecar, у CDN, иногда у Go resolver со своим TTL.

Снизили TTL — смена IP доезжает быстрее, нагрузка на authoritative выше. Повысили — трафик на старый IP живёт минутами после выката.

«Мы поставили TTL 30 секунд» не значит, что через 30 секунд все клиенты узнают новый IP. Промежуточные кэши могут держать дольше. DNS не знает, жив ли бэкенд. Это не балансировка с health check.

Пример. Выкатили новый балансировщик, поменяли A-запись. TTL был 300. Часть клиентов ещё пять минут стучится в старый IP. Инцидент «у нас DNS сломался» часто = кэш ещё не истёк.

Split horizon

Одно имя, разные ответы. Внутри кластера — ClusterIP или внутренний NLB. Снаружи — публичный адрес. View на BIND, разные зоны в CoreDNS, private hosted zone в облаке — реализации одной идеи.

Пример. Под резолвит api.example.com в публичный LB. Выходит в интернет и возвращается к себе. Лишняя задержка, сломанные сетевые политики, иногда петля. Split horizon отдал бы внутренний адрес.

Типичная ошибка

Объяснять любой «сайт не открывается после смены IP» поломкой DNS-сервера, а не TTL и кэшем. Путать AAAA с CNAME или с MX. Забыть, что из пода и с ноутбука одно имя может резолвиться в разные адреса.

На собеседовании

Расскажите цепочку резолва, отличие A/AAAA от CNAME и зачем TTL. Split horizon — разные ответы внутри и снаружи. «DNS сломался» часто = кэш + CNAME + не тот view.