Привет, Хабр! И вновь на связи Анатолий Кохан, 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 в системе.

Комментарии (0)