В Kubernetes DNS обычно воспринимается как «просто сервис», пока внезапно не начинается деградация: поды дольше стартуют, приложения ловят таймауты резолва, CoreDNS уходит в 100% CPU, а на нодах растёт количество записей в conntrack. Частый сценарий — лавина отрицательных ответов (NXDOMAIN storm), когда множество подов одновременно и многократно спрашивают про несуществующие имена, а кластерный DNS вынужден это обрабатывать.
Один из самых практичных инструментов стабилизации — NodeLocal DNSCache. Он переносит кеширование DNS максимально близко к клиенту (на ноду), снижает DNS latency и нагрузку на CoreDNS/kube-dns, а заодно уменьшает количество проходов через iptables и давление на conntrack.
Почему Kubernetes DNS может «просесть» даже в здоровом кластере
По умолчанию поды резолвят имена через сервис kube-dns/coredns (обычно это один Service IP). Это означает, что каждый DNS-запрос из каждого пода проходит путь Service → kube-proxy (iptables/IPVS) → CoreDNS-под → ответ назад. На высоких QPS это становится дорогим даже при небольших UDP-пакетах.
Типовые причины, из-за которых DNS начинает «съедать» кластер:
Высокий DNS QPS от приложений (агрессивный резолв в SDK, сервис-меши, контроллеры, экспортеры).
Плохие паттерны имён: случайные/одноразовые домены, опечатки, неверные search-суффиксы.
NXDOMAIN storm: массовые запросы к несуществующим именам + ретраи с короткими таймаутами.
Накладные расходы kube-proxy: много правил
iptablesили нагрузка IPVS на пиках.conntrack pressure: UDP через Service и NAT раздувает таблицу соединений, бьёт по всей ноде.
Парадокс Kubernetes DNS: даже «маленький» компонент способен деградировать весь кластер, потому что DNS — критическая зависимость для старта и работы большинства приложений.
Что такое NodeLocal DNSCache и как он устроен
NodeLocal DNSCache — это DaemonSet, который поднимает локальный DNS-кеш на каждой ноде и перенаправляет DNS-трафик подов на локальный адрес. Обычно используется link-local IP из диапазона 169.254.0.0/16 (часто 169.254.20.10).
Как это работает вживую:
Поды отправляют запросы не в Service IP CoreDNS, а на локальный IP NodeLocal на своей ноде.
NodeLocal кеширует ответы (включая отрицательные) и отдаёт повторные запросы локально.
Если записи нет в кеше — NodeLocal форвардит запрос в кластерный DNS, получает ответ и кладёт его в кеш.
За счёт этого обычно получаете:
Снижение DNS latency (особенно заметно по p95/p99).
Резкое уменьшение QPS на CoreDNS.
Меньше Service-хопов, меньше
iptables-обработки и меньше давления наconntrack.
Чем NodeLocal отличается от «просто увеличить реплики CoreDNS»
Увеличение реплик CoreDNS помогает масштабировать обработку, но не убирает сетевой путь через Service и не снижает повторяемость запросов на уровне ноды. При пиковых нагрузках основную стоимость часто дают именно «поды → Service DNAT → CoreDNS» и массовые повторы. NodeLocal уменьшает количество запросов, которые вообще уходят в CoreDNS.

Откуда берётся NXDOMAIN storm и почему он опасен
NXDOMAIN storm — ситуация, когда система генерирует большое количество запросов к несуществующим доменным именам и повторяет их снова и снова. Причины часто очень приземлённые:
опечатки в конфигурации (неверный домен внешнего API);
неверные
search-суффиксы и/или высокоеndotsвresolv.confвнутри пода;попытки резолвить «короткие» имена как FQDN, что приводит к серии запросов с дописыванием суффиксов;
агрессивные ретраи на уровне библиотек, особенно при маленьких таймаутах;
динамическая генерация доменов (эксперименты, feature flags), где часть имён не существует.
Почему это опасно именно для CoreDNS:
NXDOMAIN — это тоже работа: парсинг, плагины, форвардинг, метрики.
Если отрицательные ответы не кешируются достаточно близко к клиенту, CoreDNS видит каждый повтор.
Пики часто совпадают с деплоем/автоскейлингом, то есть коррелируют с максимальной нагрузкой на кластер.
Как NodeLocal DNSCache помогает при NXDOMAIN storm
NodeLocal кеширует отрицательные ответы (NXDOMAIN) на ноде. В результате, если десятки подов на одной ноде спрашивают «битое» имя, в CoreDNS уйдёт лишь небольшая доля запросов (первые промахи кеша), а дальше поды будут получать быстрый отрицательный ответ локально.
Важно: NodeLocal не лечит первопричину (неправильное имя, плохие search/ndots, ретраи), но сильно снижает ущерб и делает инциденты менее разрушительными.
Быстрая проверка: есть ли у вас симптомы DNS-проблем
Перед внедрением полезно подтвердить, что проблема действительно в DNS и/или сетевой путь DNS дорого обходится:
время старта подов выросло без явной причины;
ошибки вида
i/o timeoutпри обращении к сервисам, при этом L3/L4 проверки иногда «живые»;CoreDNS показывает высокие QPS и/или растут доли
SERVFAIL/NXDOMAIN;на нодах периодически «забивается» conntrack, после чего страдает не только DNS.
Команды для первичной диагностики
Проверить DNS Service и endpoints:
kubectl -n kube-system get svc kube-dns
kubectl -n kube-system get endpoints kube-dns -o wide
Посмотреть логи CoreDNS на предмет всплесков NXDOMAIN/SERVFAIL и таймаутов форвардинга:
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=200
Если у CoreDNS включены метрики, дополнительно смотрите распределение ответов и latency по плагинам. При штормах почти всегда заметен перекос в NXDOMAIN и рост p99.
Внедрение NodeLocal DNSCache: пошагово и с нюансами
В типовой поставке Kubernetes есть манифест NodeLocal DNSCache (в разных дистрибутивах путь/версия отличаются). Логика одинакова: DaemonSet, ConfigMap, ServiceAccount и правила iptables на ноде, которые заставляют поды использовать локальный кеш.
Практические моменты до деплоя:
Выбор локального IP. Часто используют
169.254.20.10. Убедитесь, что адрес не конфликтует с вашей сетью и особенностями CNI.Режим kube-proxy. Эффект заметен и в iptables, и в IPVS, но обычно сильнее там, где много iptables-правил и высокий DNS QPS.
conntrack. Снижая количество «путешествий» DNS-пакетов через Service, вы уменьшаете шанс упереться в лимиты таблицы соединений.
Совместимость с DNS policies. Поды с кастомным
dnsPolicy/dnsConfigмогут обходить оптимизацию; это нормально, но важно учитывать в ожиданиях.
Что поменяется в /etc/resolv.conf внутри подов
После включения NodeLocal обычно меняется nameserver (становится локальным IP NodeLocal), а search и ndots остаются такими, как настроено кластером/дистрибутивом.
Именно связка высокого ndots с «короткими» именами часто порождает пачку лишних запросов. NodeLocal уменьшит ущерб, но если вы видите, что приложение резолвит «api» и генерирует цепочку вида api.namespace.svc.cluster.local, api.svc.cluster.local, api.cluster.local, а потом только api, — это повод пересмотреть, какие имена должны быть FQDN и какие search-суффиксы реально нужны.
TTL, отрицательное кеширование и неожиданные эффекты
DNS-кеш — компромисс между скоростью и актуальностью. При внедрении NodeLocal держите в уме:
Позитивные TTL: в очень динамичных системах кеш может кратковременно отдавать «устаревший» ответ до истечения TTL.
Негативные TTL: при NXDOMAIN storm кеширование — благо, но если запись появилась «прямо сейчас», кеш может некоторое время продолжать отдавать NXDOMAIN.
NodeLocal DNSCache — не только «ускоритель», но и «стабилизатор»: сглаживает пики, локализует шторма на уровне ноды и защищает CoreDNS от лавинных повторов.
Conntrack и iptables: почему DNS внезапно влияет на сеть ноды
DNS — это не только про резолв. Путь DNS-пакета через Service означает обработку kube-proxy, возможный DNAT и прохождение по множеству правил. При высоком QPS это становится заметным потребителем CPU на нодах и может создавать много записей в conntrack.
Когда таблица conntrack переполняется, начинаются странные эффекты далеко за пределами DNS: отвал HTTP к внешним API, проблемы с доступом к базе, деградация ingress/egress. Поэтому снижение DNS-трафика через сервисную цепочку — это прямая профилактика таких инцидентов.
Проверить текущие лимиты и использование conntrack:
sysctl net.netfilter.nf_conntrack_max
sysctl net.netfilter.nf_conntrack_count
Если nf_conntrack_count стабильно подходит к nf_conntrack_max на пиках — это красный флаг. NodeLocal не единственное решение, но часто самое быстрое: вы уменьшаете один из самых массовых видов короткоживущего трафика.
Как понять, что NodeLocal DNSCache реально помог
После внедрения подтвердите эффект цифрами и симптомами:
CoreDNS QPS снизился (иногда в разы).
DNS latency стала ровнее, улучшились p95/p99 по наблюдениям приложений и мониторингу.
Стабильность деплоев: массовые rollouts/автоскейлинг меньше провоцируют «снежный ком» ошибок.
Ноды: снизилась нагрузка на подсистему фильтрации/натирования и косвенно на conntrack.

Типовые ошибки при включении NodeLocal DNSCache
Конфликт локального IP или маршрутизации
Если выбранный link-local адрес конфликтует с сетью, CNI или правилами маршрутизации, вы получите частичные отказы DNS. Типичный симптом: на части нод всё хорошо, на части — таймауты. В первую очередь проверяйте, что IP не используется нигде ещё, и что нода корректно «слушает» его через NodeLocal.
Игнорирование первопричины NXDOMAIN storm
NodeLocal смягчит ситуацию, но ошибка в домене или неверная логика резолва всё равно будут тратить ресурсы (пусть и меньше) и могут приводить к «устаревшему NXDOMAIN» из-за негативного кеша. Параллельно ищите источник запросов: по логам приложений, по метрикам CoreDNS, по характерным доменным именам в запросах.
Неучтённые особенности dnsPolicy и dnsConfig
Если часть подов использует нестандартный резолвер (например, напрямую на внешний DNS), они не получат преимущества NodeLocal. Это может быть осознанным решением, но тогда не ждите пропорционального падения QPS на CoreDNS.
Мини-руководство: что делать при вспышке DNS-таймаутов прямо сейчас
Если инцидент уже идёт, действуйте по приоритету «остановить кровотечение»:
Проверьте, жив ли CoreDNS, сколько реплик, нет ли CrashLoop и ошибок форвардинга.
Оцените, не начался ли всплеск NXDOMAIN: по логам и по топ-именам (если у вас включено логирование или есть метрики по именам).
Посмотрите состояние
conntrackна нодах, особенно на тех, где много подов и высокие сетевые нагрузки.Если причина — конкретный деплой/приложение, временно остановите rollout или ограничьте реплики, чтобы не усиливать шторм.
Планово внедрите NodeLocal DNSCache и приведите в порядок конфигурации резолва: имена,
ndots, таймауты/ретраи DNS в SDK.
Итоги
NodeLocal DNSCache — один из самых простых по внедрению способов сделать Kubernetes DNS быстрее и устойчивее. Он уменьшает DNS latency, разгружает CoreDNS/kube-dns, снижает вероятность NXDOMAIN storm и дополнительно помогает на уровне conntrack и iptables.
Если вы размещаете приложения на VDS или в целом регулярно масштабируете кластеры, относитесь к DNS как к компоненту первого класса: наблюдаемость, capacity planning и кеширование на нодах часто окупаются быстрее любой «оптимизации приложения».
Для смежных задач доменной инфраструктуры может пригодиться материал про перенос домена и контроль DNS-зон через EPP и заметка про автоматизацию wildcard SSL через DNS-01.


