Привет, Хабр! И вновь на связи Анатолий Кохан, DevOps-инженер из К2Тех.
В первой части мы разобрали, как в Linux работает процесс разрешения имен — от вызова getaddrinfo()
до получения IP-адреса. Однако если бы каждый вызов требовал нового DNS-запроса, это было бы неэффективно и сильно нагружало как систему, так и сеть. Поэтому используется кэширование.
Кэширование DNS может быть везде — в glibc, в systemd-resolved, в браузерах и даже в приложениях на Go. Кэш помогает увеличить скорость работы, но создает дополнительные сложности при отладке. Например: вы меняете DNS-запись, но сервер продолжает ходить по старому IP-адресу. Или, Dig показывает правильный адрес, а curl всё равно подключается к устаревшему.
В этой статье разберем различные уровни кэшей самой системы, приложений и языков программирования, контейнеров, прокси. А также их мониторинг и сброс.
Что такое DNS-кэш и зачем он нужен
DNS-кэш — это не единое хранилище, а многоуровневая система механизмов кэширования на разных уровнях системы. Каждый DNS-запрос — это долгий сетевой вызов, поэтому многие компоненты стараются сохранять результаты локально.
TTL (Time To Live) — время жизни записи в кэше. Оно указывается в DNS-ответе и определяет, как долго можно использовать сохранённый IP-адрес. Задается обычно в секундах. После истечения TTL необходимо обновить данные.
Таким образом, кэширование позволяет:
- повысить скорость обработки повторных DNS запросов
- снизить нагрузку на серверную и сетевую инфраструктуру
- обеспечить отказоустойчивость при временной потере соединения
- уменьшить задержки в работе приложений
Но у кэширования есть и обратная сторона: устаревшие данные могут стать причиной недоступности сервисов при изменении инфраструктуры.
Где именно кэшируется DNS в Linux. Уровни работы с кэшем
Ядро
Ядро Linux может опосредованно “кэшировать” DNS-трафик через подсистему netfilter/conntrack, если используется stateful-фильтрация. Несмотря на то, что UDP — протокол без установления соединения, ядро отслеживает состояние пакетов, относящихся к одному блоку запрос-ответ (например, запрос от [src_ip:src_port] к [8.8.8.8:53] и ожидаемый ответ от [8.8.8.8:53] к [src_ip:src_port]) и временно хранит информацию — по умолчанию около 30 секунд. Это необходимо для NAT и правил вроде iptables -m conntrack --ctstate ESTABLISHED,RELATED
.
Проверить текущие записи можно командой:
conntrack -L -p udp --dport 53
В списке отобразятся активные DNS-сессии, которые считаются допустимыми до истечения таймаута. Повторные DNS-запросы к тем же адресам в пределах срока жизни этих записей могут быть обработаны в рамках существующей записи состояния. Это не полноценное кэширование DNS-ответов, но conntrack может влиять на поведение сетевого уровня, особенно при диагностике проблем с NAT или firewall.
Для удаления записей из таблицы отслеживания соединений можно воспользоваться командой:
conntrack -D -p udp --dport 53
Системный уровень
1. systemd-resolved
Современные дистрибутивы с systemd часто используют systemd-resolved
в качестве основного DNS-клиента, который:
имеет собственный кэш DNS-запросов, включая положительные и (опционально) отрицательные ответы;
поддерживает split DNS (разные DNS-серверы для разных доменов), конфигурируется через systemd-networkd или NetworkManager;
поддерживает DNS-over-TLS (DoT), включая fallback-серверы и DNSSEC;
предоставляет API по D-Bus (org.freedesktop.resolve1), позволяет получать статус, менять настройки и управлять кэшем через resolvectl.
2. nscd (Name Service Cache Daemon)
Если запущен nscd, он кэширует результаты NSS-вызовов, включая DNS. Его настройки находятся в /etc/nscd.conf
enable-cache hosts yes
positive-time-to-live hosts 600
negative-time-to-live hosts 20
Важный момент: nscd устарел и не рекомендуется к использованию в новых системах. В Debian-based дистрибутивах чаще всего его заменяет systemd-resolved, но в RHEL-based дистрибутивах он ещё встречается.
3. Популярные локальные кэширующие резолверы
dnsmasq — популярный выбор для локального кэширования:
Настройка кэша
cache-size=1000 (cache-size управляет размером кэша. По умолчанию он небольшой (150), и для заметного эффекта его увеличивают до 1000–5000)
neg-ttl=60
unbound — более мощный DNS-рекурсор.
Управление кэшем гибкое:
Размер кэша задаётся параметром msg-cache-size (отвечает за ответы) и rrset-cache-size (за записи ресурсов):
msg-cache-size: 50m
rrset-cache-size: 100m
TTL кэшированных ответов можно ограничить директивами cache-min-ttl и cache-max-ttl
cache-min-ttl: 30 # минимальный TTL для любых ответов
cache-max-ttl: 86400 # максимальный TTL (24 часа)
bind - распространенный DNS-сервер с поддержкой рекурсивного разрешения и кэширования. Управление кэшем и его мониторинг осуществляется через команду rndc (Remote Name Daemon Control).
В конфигурационном файле named.conf можно задавать TTL для кэша и контролировать поведение:
options {
max-cache-ttl 86400; // максимальное время жизни кэша (в секундах)
max-ncache-ttl 3600; // максимальное время жизни негативных ответов (NXDOMAIN)
};
Уровень приложений и языков программирования
glibc
Хотя официально считается, что glibc не реализует полноценный DNS-кэш (в отличие от демонов вроде systemd-resolved, dnsmasq или nscd), в её реализации резолвера есть несколько механизмов, которые действуют как очень простое и ограниченное кэширование или оптимизация запросов.
Во-первых, используется NSS (Name Service Switch), который может быть сконфигурирован для работы с nscd, systemd-resolved или другими кэширующими компонентами. Например, с помощью следующей директивы в файле nsswitch.conf:
hosts: files resolved myhostname
Где вместо resolved также может быть и nscd. Хотя nscd — отдельный демон, он поставляется вместе с glibc в большинстве дистрибутивов и тесно интегрирован с ней.
Когда nscd запущен и настроен (часто включен по умолчанию для passwd, group, hosts), библиотеки glibc (getaddrinfo, gethostbyname) будут обращаться к нему первыми. Nscd кэширует ответы до истечения их TTL. Кэширование в этом случае происходит вне самой библиотеки glibc, но glibc использует этот кэш прозрачно для приложения.
В реализации DNS-резолвера внутри glibc (в файле resolv/res_query.c и др.) содержатся оптимизации, такие как повторное использование сокета и игнорирование TTL при повторных запросах внутри одного вызова, которые можно рассматривать в качестве некого микро-кэша в контексте одного вызова функции разрешения. Эти оптимизации не сохраняют результаты между разными вызовами getaddrinfo или между разными процессами и действуют только в рамках одного системного вызова функции.
Модули NSS (особенно files) кэшируют данные из статических файлов. Например, nss-files (работающий в том числе с /etc/hosts) по сути "кэширует" содержимое этих файлов в памяти процесса после их первого чтения (до перезагрузки процесса или вызова, инвалидирующего кэш NSS). Это не DNS-кэширование в чистом виде, но влияет на процесс разрешения имен, в котором участвует DNS.
Также можно упомянуть, что устаревшая функция gethostbyname имела примитивный внутренний кэш (фиксированный малый размер, неразделяемый между процессами, игнорирующий TTL). Эта информация может оказаться полезной при работе с legacy.
Java
Java поддерживает встроенный DNS-кэш с гибкими настройками времени жизни записей.
Особенности работы
Без использования Security Manager (начиная с Java 11 - это поведение по умолчанию):
- положительные ответы кэшируются на 30 секунд (максимум, даже если DNS-сервер указал больший TTL);
- отрицательные ответы (NXDOMAIN) — 10 секунд.
С использованием Security Manager:
- положительные ответы кэшируются бесконечно (риск устаревших записей);
- отрицательные ответы не кэшируются.
Управление
Настройки указываются в свойствах JVM. TTL в секундах для успешных запросов:
networkaddress.cache.ttl=60
TTL для неудачных запросов (NXDOMAIN):
networkaddress.cache.negative.ttl=10
Варианты значений:
0 — отключить кэширование;
-1 — кэшировать бессрочно (только для положительных ответов).
Способы настройки
1. Аргументы JVM:
java -Dnetworkaddress.cache.ttl=60 -jar app.jar
2. В коде (глобально для JVM):
Security.setProperty("networkaddress.cache.ttl", "60");
Go
Go использует две модели резолвинга:
- через cgo — вызывает системный getaddrinfo()
(включая NSS). Работает через системные настройки (/etc/nsswitch.conf, /etc/resolv.conf);
- Pure Go resolver — реализует собственный DNS клиент, минуя системные библиотеки.
Выбор резолвера:
GODEBUG=netdns=go # встроенный резолвер с кэшем
GODEBUG=netdns=cgo # через системный getaddrinfo()
При использовании Pure Go резолвера Go реализует in-memory DNS-кэш внутри процесса. Этот кэш хранит успешные (A, AAAA, CNAME) и отрицательные (NXDOMAIN) ответы, соблюдая их TTL. Кэш имеет фиксированный размер (реализует эвристику LRU), хранится в памяти процесса и разделяется между горутинами внутри этого процесса, но не разделяется между разными процессами или экземплярами приложений.
Python
По умолчанию модуль socket и большинство стандартных библиотек (включая requests, urllib3) используют системный вызов getaddrinfo() и не имеют встроенного кэша DNS.
• requests → использует urllib3, который делегирует разрешение DNS системной библиотеке (socket.getaddrinfo()), без кэширования.
• aiohttp по умолчанию работает через getaddrinfo(), но может быть настроен на использование aiodns (асинхронный DNS через libcares), где возможно встроенное кэширование.
• dnspython — отдельный DNS-клиент, выполняющий DNS-запросы напрямую. С версии 2.0 поддерживает явное включение кэша:
import dns.resolver
resolver = dns.resolver.Resolver()
resolver.cache = dns.resolver.Cache()
Таким образом, поведение зависит от конкретной библиотеки. Стандартный socket и большинство оберток над ним, включая requests, кэширование не реализуют и полагаются на системный резолвер.
Контейнеры и оркестрация
Docker
Контейнеры используют DNS-сервер хоста (при использовании сетевого режима host) или встроенный резолвер.
В Docker по умолчанию - это адрес 127.0.0.11 - встроенный DNS в dockerd, который использует libnetwork. Кэш может находиться как в хосте, так и в самом контейнере.
Podman
В Podman, в зависимости от версии, могут использоваться разные схемы.
Если используется сетевой бэкенд CNI (устаревший, но поддерживаемый, который использовался по умолчанию в Podman ≤ 3.x), задействуется плагин dnsname, отвечающий за работу DNS в виртуальной сети Podman.
Кэширование DNS происходит на уровне контейнера. Если контейнер использует systemd-resolved, dnsmasq или другой локальный кэширующий резолвер, то кэш работает там. Сам dnsname не кэширует ответы.
Если используется сетевой бэкенд Netavark (бэкенд по умолчанию в Podman ≥ 4.0.), то Netavark запускает aardvark-dns — легковесный DNS-сервер, который:
- поддерживает A-записи (имена → IP) и PTR-записи (обратный DNS);
- поддерживает внешний DNS: контейнеры используют aardvark-dns как резолвер, перенаправляющий внешние запросы (например, ya.ru) в системные DNS-серверы, но при этом не сохраняет ответы.
Как и в случае с CNI, кэширование возможно только на стороне: системного резолвера или локального кэша внутри контейнера.
Kubernetes
Обычно за DNS в Kubernetes отвечает CoreDNS. Важно понимать, что его поведение по умолчанию различается для внутренних и внешних запросов:
Внутренние записи Kubernetes, например my-svc.my-namespace.svc.cluster.local, обрабатываются плагином kubernetes. Они всегда кэшируются в памяти CoreDNS на время, указанное в поле TTL записи (обычно 5 секунд для headless-сервисов и 30 сек для остальных). Это кэширование включено всегда и не требует дополнительных плагинов.
Внешние запросы, например google.com, обрабатываются плагином forward, который отправляет запросы резолверам из /etc/resolv.conf CoreDNS. Без плагина cache в конфигурации ответы на внешние запросы не кэшируются! Каждый запрос от подов будет идти на upstream-резолвер, создавая нагрузку и увеличивая задержку.
Чтобы включить кэширование, нужно добавить плагин cache в Corefile:
.:53 {
errors
health
# Кэшируем ВСЕ ответы (включая внешние) на 30 секунд:
cache 30 .
forward . 8.8.8.8 1.1.1.1 # Важно: cache ДОЛЖЕН стоять перед forward!
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
reload
}
Прокси-серверы на примере Nginx и HAProxy
Nginx и HAProxy имеют разные подходы к DNS-кэшированию, что важно учитывать при проксировании к динамическим бэкендам.
Nginx по умолчанию кэширует DNS-записи на время их TTL и не перезапрашивает их до истечения срока — это создает проблемы в контейнерных средах, где IP-адреса сервисов меняются при перезапуске.
Решение: использовать переменную в proxy_pass
(set $backend "http://service.local"; proxy_pass $backend;
) и директиву resolver 8.8.8.8 valid=30s
для принудительного обновления каждые 30 секунд.
HAProxy более гибок в настройке DNS-резолвинга через секцию resolvers
с параметрами hold valid 10s
и resolve-prefer ipv4
.
Ключевая особенность — возможность автоматического обновления IP-адресов бэкендов без перезагрузки конфигурации через default-server check resolvers dns_resolvers
. Однако HAProxy агрессивно кэширует разрешенные адреса и может “застревать” на одном IP из multiple A-записей. Это может быть нежелательно в ситуациях, когда важна равномерная загрузка, или при динамическом изменении IP-адресов. Для контроля этого поведения в блоке resolvers следует правильно настроить ключевые параметры.
Пример конфигурации:
resolvers mynameservers
nameserver ns1 192.168.2.10:53
nameserver ns2 192.168.3.10:53
...
hold valid 10s # время актуальности DNS-записи (рекомендуется 10-30s)
hold obsolete 0s # время хранения нерабочих IP (всегда 0s!) - настройка по умолчанию для версий выше 2.0+
resolve_retries 3 # количество попыток разрешения (2-3 оптимально)
timeout retry 1s # интервал между попытками (1-2s)
timeout resolve 2s # общий таймаут разрешения (2-3s)
Пара советов по мониторингу. Отслеживайте в логах записи вида DNS resolution failed
(HAProxy) и upstream timed out
(Nginx) — это индикаторы проблем с DNS-кэшем. Для Nginx также можно добавить error_log /var/log/nginx/dns_debug.log debug;
в контекст resolver.
И небольшое примечание: не все уровни позволяют принудительно сбросить кэш. Например, библиотека musl (в Alpine Linux) использует минималистичный встроенный резолвер без отдельного кэша, но с фиксированным таймаутом и retry. В нем DNS-кэш отсутствует, а каждый вызов делает новый DNS-запрос.
Специальные случаи кэширования
Negative Caching (кэширование NXDOMAIN)
Даже отсутствие ответа от DNS-сервера (например, если домен не существует) может кэшироваться. Это называется негативным кэшированием и описано в RFC 2308. Время хранения NXDOMAIN обычно определяется TTL из SOA-записи зоны или настройками резолвера:
- Unbound: по умолчанию использует SOA.MINIMUM или val-ttl-negative (по умолчанию до 15 минут);
- dnsmasq: хранит негативные ответы 10 секунд;
- systemd-resolved: не кэширует NXDOMAIN вообще (время жизни = 0);
- BIND кеширует NXDOMAIN, используя TTL из SOA (поле Minimum TTL) и настройку max-negative-cache-ttl.
Это поведение критично при отладке: если домен недавно добавили, но он всё ещё возвращает NXDOMAIN — возможно, причина в негативном кеше.
Важно: негативный кеш может сохраняться даже после появления записи в DNS. В некоторых случаях сброс возможен только перезапуском резолвера или его кеша — это стоит учитывать при отладке.
Stale DNS (устаревшие ответы)
Некоторые DNS-резолверы поддерживают режим “serve expired” (RFC 8767) — возврат устаревших (stale) ответов из кеша, если свежий ответ от upstream-серверов недоступен.
Такое поведение полезно для повышения устойчивости: при кратковременных сетевых сбоях система продолжает работать, используя последние известные данные.
Когда это может случиться:
- upstream-сервер недоступен или не отвечает вовремя;
- текущий ответ устарел (TTL истёк), но в кеше осталась старая копия;
- режим “serve-expired” включён явно (например, в unbound, dnsmasq, BIND).
Недостаток такого поведения — потенциальный риск работы с недействительными или уже изменившимися записями.
Диагностика: как проверить, откуда приходит DNS-ответ
Чтобы понять, кэшируется ли DNS-ответ, и на каком уровне, можно сравнить результаты запросов через разные инструменты. Ниже — примеры команд:
1. Запрос через системный резолвер (libc):
getent hosts example.com
Этот способ использует конфигурацию nsswitch.conf и может задействовать systemd-resolved, dnsmasq или другие локальные DNS-сервисы, если они настроены.
2. Запрос напрямую к локальному systemd-resolved (loopback):
dig @127.0.0.53 example.com
Позволяет обратиться напрямую к systemd-resolved, минуя nsswitch.conf и libc. Это поможет проверить, есть ли ответ в его собственном кэше. Для этой же цели можно использовать команду:
resolvectl query example.com
3. Запрос напрямую к внешнему DNS-серверу (например, Google DNS):
dig @8.8.8.8 example.com
Гарантированно минует все локальные уровни кэширования. Такой запрос можно использовать для сравнения с локальными ответами.
4. Просмотр TTL в ответе:
dig +nocmd +noall +answer example.com
Показывает только секцию ответа (ANSWER) с указанием оставшегося TTL. Полезно для оценки свежести кэша.
Если ответы на один и тот же домен отличаются в зависимости от используемой команды — например, getent
, dig @127.0.0.53
или dig @8.8.8.8
— это может указывать на наличие кэша на каком-то уровне. Отличия в IP-адресах или в значениях TTL особенно показательны: они помогают понять, на каком этапе возвращаются устаревшие или закешированные данные. Такие сравнения позволяют локализовать источник кэширования и уточнить, какой компонент системы дает неожиданный ответ.
Отслеживание сетевого трафика
Для анализа DNS-запросов можно использовать такую команду:
tcpdump -i any udp port 53 -n -X -w dns_dump.pcap
-n — отключает преобразование IP в имена (уменьшает шум).
-X — показывает пакеты в hex и ASCII (удобнее для DNS, чем -A).
-w — сохраняет дамп в файл (можно открыть в Wireshark).
Пример вывода:
13:37:45.123 IP 10.0.0.1.4321 > 8.8.8.8.53: 12345+ A? google.com. (28)
13:37:45.456 IP 8.8.8.8.53 > 10.0.0.1.4321: 12345 1/0/0 A 142.250.185.174 (44)
A? google.com — запрос типа "A" для домена google.com.
A 142.250.185.174 — ответ с IP-адресом.
12345 — ID запроса (полезно для сопоставления вопросов и ответов).
Также можно использовать утилиту dig, которая инициирует запрос и сразу перехватывает его, предоставляя много сопутствующей информации:
dig example.com & tcpdump -i any udp port 53 -n
Использование tcpdump позволяет отличить кэш от реального сетевого запроса: если трафика нет, скорее всего, ответ был из кэша.
Трассировка системных вызовов
С помощью этой команды можно выполнить трассировку системных вызовов и отслеживать обращения к DNS.
strace -e trace=network curl example.com
Фрагмент вывода:
sendto(3, "\264\372\1\0\0\1\0\0\0\0\0\0\7example\3com\0\0\1\0\1", 33, 0,
{sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.1.1")}, 16) = 33
recvfrom(3, "\264\372\201\200\0\1\0\1\0\0\0\0\7example\3com\0\0\1\0\1"..., 512, 0, ..., ...) = 49
Здесь sendto() отправляет DNS-запрос на порт 53, а recvfrom() получает ответ от DNS-сервера. Это позволяет убедиться, что разрешение действительно идёт через сеть, а не из кэша.
Варианты решений для типичных ситуаций
Для полноты картины приведу несколько типовых ситуаций с основными вариантами решения.
“Сайт открылся у всех, кроме меня”
Причина: устаревший кэш в браузере или системном резолвере.
Решение: сравнить IP из ping с ожидаемым, сбросить кэш.
“Поменяли A-запись, но трафик идет на старый сервер”
Причина: не был заранее снижен TTL.
Решение: устанавливать короткий TTL (60 сек) за 24-48 часов до смены.
“curl работает, а браузер — нет”
Причина: браузер использует собственный DNS-кэш.
Решение: сбросить кэш браузера.
Chrome:- chrome://net-internals/#dns — просмотр и сброс кэша
- chrome://flags — "Built-in DNS client" — управляет встроенным кэшем
Firefox:- about:networking#dns — список записей
- network.dnsCacheExpiration — TTL кэша (по умолчанию 60 сек)
“Nginx перестал ходить после смены DNS”
Причина: кэш в nginx (параметр valid
в resolver
).
Решение: уменьшить valid=1s
или перезапустить nginx.
“Библиотека использует старый адрес даже после flush”
Причина: язык/библиотека ведёт собственный кэш.
Решение: настроить TTL в коде или перезапустить приложение.
Чек-лист по полной очистке кэша
Для удобства собрал все в одну таблицу:
Категория |
ПО |
Команда / Действие |
Комментарий |
Системный уровень |
systemd-resolved |
resolvectl flush-caches |
Очистка кэша |
nscd |
sudo nscd -i hosts |
Инвалидация кэша hosts в nscd |
|
dnsmasq |
sudo systemctl restart dnsmasq |
Перезапуск dnsmasq — очистка кэша |
|
unbound |
unbound-control flush |
Полная очистка кэша Unbound |
|
unbound |
unbound-control flush_zone example.com |
Очистка кэша конкретной зоны в Unbound |
|
bind |
rndc flush |
Полная очистка кэша BIND |
|
bind |
rndc flushname example.com |
Очистка кэша зоны в BIND |
|
bind |
rndc flushname -type=A example.com |
Очистка кэша зоны с указанием типа записей (A) в BIND |
|
Приложения |
Chrome |
Chrome: chrome://net-internals/#dns |
Очистка DNS-кэша через интерфейс браузера |
Firefox |
Firefox: Настройки → «Очистить кэш DNS» |
Очистка DNS-кэша в Firefox, можно через about:config |
|
Java/Go |
Требуется перезапуск приложений для очистки DNS-кэша |
||
Контейнеры |
docker/podman |
restart <container> |
|
coredns |
kubectl rollout restart deployment/coredns -n kube-system |
При перезапуске CoreDNS создаются новые поды, но клиенты тоже могут кэшировать DNS. Для полной очистки нужно перезапускать и клиентов. |
Как правильно управлять кэшем
Немного практических советов по работе с кэшами.
В разработке
1. Использовать короткие TTL для тестовых доменов (60-120 секунд). Для негативных ответов (NXDOMAIN) устанавливайте ещё меньший TTL (5-30 сек) в конфигурации резолверов (например, cache_neg_ttl в dnsmasq), чтобы быстро тестировать исправления.
2. Знать, как сбросить кэш на каждом используемом уровне.
3. Тестировать изменения DNS в изолированной среде.
В production
1. Планировать изменения DNS: снижать TTL заранее.
2. Мониторить кэширование: логировать stale answers и NXDOMAIN.
3. Использовать централизованные резолверы с контролируемым кэшированием.
4. Настроить правильные TTL:
- Для часто меняющихся сервисов: 60-300 секунд.
- Для статичных данных: 3600+ секунд.
Эффективное управление DNS в продакшене требует непрерывного контроля кэша. Ключевые метрики: hit rate (эффективность кэша), stale answers (устаревшие ответы), NXDOMAIN rate (ошибки резолвинга) и latency (задержка).
Мониторинг системных резолверов
Для анализа работы DNS-кэша и диагностики проблем важно уметь получать статистику резолверов. В таблице ниже собраны ключевые команды для популярных системных DNS-сервисов — от systemd-resolved до BIND.
Резолвер |
Команда / Настройка |
Описание |
systemd-resolved |
resolvectl statistics |
Статистика кэша: хиты, промахи |
nscd |
nscd -g |
Статистика кэша системных вызовов |
dnsmasq |
В конфиг добавить: log-querieslog-facility=/var/log/dnsmasq.log |
Логирование DNS-запросов в файл |
unbound |
unbound-control stats_noreset |
Общая статистика сервера |
unbound |
`unbound-control dump_cache |
анализ содержимого кэша |
bind |
rndc stats |
Общая статистика сервера |
bind |
rndc dumpdb -cache |
анализ содержимого кэша |
Мониторинг в среде Kubernetes
Эффективная работа DNS критична для производительности кластера Kubernetes. CoreDNS, как стандартный резолвер, генерирует метрики, которые помогают выявлять:
эффективность кэширования (снижает ли нагрузку на upstream);
ошибки разрешения имен (например, всплески NXDOMAIN);
аномальные задержки (проблемы с сетью или перегрузку).
Собирая эти данные через Prometheus, вы можете настроить алертинг и предотвратить сбои до их влияния на приложения.
Примеры метрик
- Эффективность кэша:
sum(rate(coredns_cache_hits_total{type="success"}[5m])) / sum(rate(coredns_cache_requests_total[5m]))
- Отслеживание ошибок:
rate(coredns_dns_responses_total{rcode="NXDOMAIN"}[5m])
- Задержки запросов:
histogram_quantile(0.99, rate(coredns_dns_request_duration_seconds_bucket[5m]))
Примеры алертов
- Рост ошибок NXDOMAIN:
rate(coredns_dns_responses_total{rcode="NXDOMAIN"}[5m]) > 10
- Деградация скорости ответа:
histogram_quantile(0.99, rate(coredns_dns_request_duration_seconds_bucket[5m])) > 1
- Снижение эффективности:
rate(coredns_cache_misses_total[15m]) / rate(coredns_cache_requests_total[15m]) > 0.5
Проактивные практики
Автоматизируйте алерты на аномальный рост NXDOMAIN-ответов.
Контролируйте сроки жизни DNS-записей (TTL), чтобы избежать использования устаревших данных.
Визуализируйте hit/miss ratio для контроля эффективности кэширования.
Заключение
Ключевые принципы работы с DNS-кэшем основываются, в первую очередь, на понимании, где именно может кэшироваться DNS в вашей системе, планировании изменений DNS-записей, способности диагностировать и очищать кэш на разных уровнях, а также настройке TTL в соответствии с характером данных. Надеюсь, данный материал помог немного разобраться с этими вопросами.
В следующей части разберём, как взаимодействуют различные резолверы (glibc, systemd-resolved, dnsmasq, NetworkManager), что происходит, когда /etc/resolv.conf
указывает на 127.0.0.53, и как понять, кто реально управляет вашим DNS в системе.