4. DNS — одна из самых частых причин инцидентов
Рекурсивный vs авторитативный DNS, типы записей (A/AAAA/CNAME/TXT/SRV), TTL/кэш, split-horizon и DNS в Kubernetes + практическая диагностика «по IP работает, по hostname — нет».
Теория
Рекурсивный и авторитативный сервер
- Рекурсивный резолвер (recursive resolver) — сервер, к которому обращается клиент (ПК, под, контейнер). Он сам выполняет цепочку запросов: корневые серверы → TLD (.com, .ru) → авторитативный сервер домена и возвращает клиенту итоговый ответ. Примеры: резолвер провайдера, 8.8.8.8 (Google), 1.1.1.1 (Cloudflare), в кластере — CoreDNS/kube-dns.
- Авторитативный сервер (authoritative) — сервер, который хранит зону домена и отдаёт по ней ответы «как истина». Не ходит за другими доменами сам; на него ссылаются через NS-записи. При диагностике важно различать: «спрашиваю рекурсивный» (dig @8.8.8.8) vs «спрашиваю авторитативный» (dig @ns1.example.com).
Понимание разницы помогает: если ответ неверный — проверить и кэш рекурсивного, и данные на авторитативном.
Типы записей: A, AAAA, CNAME, TXT, SRV
| Тип | Назначение |
|---|---|
| A | Имя → IPv4. Пример: api.example.com. A 192.0.2.10 |
| AAAA | Имя → IPv6. |
| CNAME | Псевдоним: имя указывает на другое имя. Резолвер повторно разрешает целевое имя. Нельзя ставить CNAME на корень зоны (apex). |
| TXT | Произвольная строка: верификация домена, SPF, DKIM, подсказки для сервисов. |
| SRV | Услуга (сервис, протокол, порт): имя вида _http._tcp.example.com → хост и порт. Используется в Kubernetes (Headless Service), LDAP, SIP. |
Частая ошибка: CNAME на apex (example.com вместо www.example.com) — по стандарту не допускается; многие провайдеры делают «flattening» (ALIAS/ANAME), но это не классический CNAME.
TTL и кэширование
TTL (Time To Live) — время в секундах, в течение которого ответ можно кэшировать. Рекурсивный резолвер и клиенты хранят ответ в кэше и не спрашивают авторитативный сервер до истечения TTL. Низкий TTL — быстрее распространение изменений, но больше нагрузка на DNS. Высокий TTL — меньше запросов, но дольше «въезжают» правки. После смены IP или имени часто причина «всё ещё старый адрес» — кэш с не истёкшим TTL.
Split-horizon DNS
Split-horizon — одна и та же зона отдаёт разные ответы в зависимости от того, кто спрашивает (внутренний клиент или из интернета). Внутри сети, например, api.example.com резолвится во внутренний IP; снаружи — в публичный или в балансировщик. При отладке важно понимать, с какого места и через какой резолвер идёт запрос: «из пода» и «с ноутбука» могут видеть разные ответы.
DNS в Kubernetes
В кластере обычно работает CoreDNS (или kube-dns): резолвер в подах настроен на ClusterIP этого сервиса (часто 10.96.0.10 или из диапазона service-cluster-ip-range). Он резолвит:
- Внутрикластерные имена: имена сервисов вида
<service>.<namespace>.svc.cluster.local→ ClusterIP; для Headless Service — список IP подов. Короткое имя<service>или<service>.<namespace>тоже разрешается внутри того же namespace (search-список в resolv.conf). - Внешние имена: CoreDNS пересылает запросы на upstream (например, на резолвер узла или 8.8.8.8).
Типичные проблемы: неправильный search-список, недоступность CoreDNS (поды не стартуют, сеть), неправильный upstream или блокировка исходящего DNS (политика сети/firewall). Если приложение работает по IP, но не по hostname — в 99% случаев проблема в резолвинге имени (DNS).
Почему приложение работает по IP, но не по hostname?
Если по IP всё отвечает, а по имени — таймаут или «unknown host», значит сбой на этапе преобразования имени в IP (DNS):
- Резолвер недоступен — в контейнере/поде в resolv.conf указан адрес DNS (например, 10.96.0.10), но до него нет маршрута или порт 53 закрыт.
- Неверный резолвер или search — запрашивается не то имя (например, короткое имя без namespace в Kubernetes не резолвится из другого namespace без полного FQDN).
- Запись не существует или устарела — для этого hostname нет A/AAAA или CNAME, либо на авторитативном сервере уже новое значение, но везде кэш со старым (TTL не истёк).
- Split-horizon — с вашей точки зрения (под, офис) отдаётся другой ответ или NXDOMAIN.
- Сеть/firewall — исходящие запросы на порт 53 (UDP/TCP) блокируются, резолвер не получает ответ.
Порядок проверки: с проблемного хоста выполнить nslookup hostname или dig hostname; затем dig @8.8.8.8 hostname (обходим локальный резолвер). Если через 8.8.8.8 резолвится, а локально нет — проблема в локальном резолвере или в его upstream. Если ни там ни там не резолвится — запись или зона на авторитативном.
Практика: команды
dig
# Запрос к рекурсивному резолверу (по умолчанию — из /etc/resolv.conf)
dig example.com
# Запрос к конкретному резолверу (например, Google)
dig @8.8.8.8 example.com
# Трассировка: как резолвер обходит корень → TLD → авторитативный
dig +trace example.com
# Короткий вывод (только ответы)
dig +short example.com
# Тип записи (A, AAAA, MX, TXT, SRV...)
dig AAAA example.com
dig TXT example.com
nslookup
# Интерактивный режим или однострочный запрос
nslookup example.com
nslookup example.com 8.8.8.8
В контейнере/поде (Kubernetes)
# Кто резолвит и какой search
cat /etc/resolv.conf
# Проверка резолвинга имени сервиса
nslookup kubernetes.default.svc.cluster.local
dig +short kubernetes.default.svc.cluster.local
!!! tip "Практика"
При инциденте «не открывается по имени»: 1) с проблемного хоста — dig/nslookup по имени; 2) dig @8.8.8.8 — сравнить; 3) проверить resolv.conf и доступность резолвера (ping, порт 53); 4) при необходимости dig +trace до авторитативного.
Паттерны и антипаттерны
| Паттерн | Описание |
|---|---|
| Сначала проверить DNS | При «работает по IP, не по имени» сразу смотреть резолвинг и resolv.conf. |
| Знать свой резолвер и upstream | В кластере — адрес CoreDNS и search; снаружи — кто отдаёт ответ (кэш провайдера, 8.8.8.8 и т.д.). |
| Учитывать TTL при смене записей | Заранее снизить TTL перед сменой IP/имени; после смены подождать старый TTL или чистить кэш там, где возможно. |
| Антипаттерн | Почему плохо | Что делать |
|---|---|---|
| Считать «раз с моей машины резолвится — значит везде ок» | Split-horizon и разный кэш. | Проверять с того же контура, откуда идёт трафик (под, другая сеть). |
| CNAME на apex домена | Нарушение стандарта, не все резолверы обрабатывают. | Использовать A/AAAA на apex или ALIAS у провайдера, если нужен аналог. |