DNS в Kubernetes отвечает медленно: проверяем CoreDNS, search и ndots
HTTP-запрос зависает ещё до соединения с сервером. При повторе иногда всё быстро, а IP-адрес напрямую отвечает без задержки. Это повод измерить разрешение имени отдельно. В Kubernetes приложение получает собственные настройки DNS, поэтому быстрый nslookup на ноутбуке не описывает путь запроса из Pod.
Проверяем именно проблемный Pod
kubectl -n demo exec api-example -- cat /etc/resolv.conf
kubectl -n demo get pod api-example -o yamlВ resolv.conf посмотрите nameserver, search и options. В Pod сопоставьте их с dnsPolicy, dnsConfig и hostNetwork. Обычный Pod с ClusterFirst и hostNetwork-приложение могут получать разные условия. Диагностический контейнер должен иметь такой же контекст, иначе проверка легко уйдёт по другой сети и с другим resolver.
Типичный search содержит demo.svc.cluster.local, svc.cluster.local и cluster.local. Параметр ndots:5 влияет на порядок поиска: имя с меньшим числом точек resolver может сначала дополнять search-суффиксами. Поэтому внешний api.example.com способен породить запросы к api.example.com.demo.svc.cluster.local и другим несуществующим именам, прежде чем будет проверен внешний адрес. Точное поведение зависит от resolver приложения.
Сравниваем короткое имя и абсолютное
В существующем диагностическом Pod с dig выполните запросы. Имена api.example.com здесь нужно заменить вашим внешним доменом. Конечная точка обозначает абсолютное DNS-имя и исключает добавление search-суффиксов при нормальной обработке resolver:
kubectl -n demo exec dnsutils -- dig +search +stats api.example.com kubectl -n demo exec dnsutils -- dig +stats api.example.com. kubectl -n demo exec dnsutils -- dig +stats api.demo.svc.cluster.local.
Сравните Query time, статус ответа и отправленные имена. Единичное измерение может попасть в кэш; повторите серию и отдельно посмотрите холодный случай. dig +search нужен для явного включения search-поведения самого dig. Приложение на Go, Java или libc может иначе кэшировать и повторять запросы, поэтому окончательное подтверждение даёт измерение в его реальном DNS-клиенте.
Полное имя с точкой полезно для диагностики, но механически добавлять точку к URL приложения нельзя: сервер, TLS-проверка имени и прокси могут обрабатывать такой адрес иначе. Сначала убедитесь, что библиотека и endpoint поддерживают выбранную запись. Если приложение позволяет отдельно задать имя для DNS-поиска, задача решается точнее, чем массовой заменой HTTP URL.
Когда тормозит сам DNS-сервис
kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide kubectl -n kube-system get service kube-dns kubectl -n kube-system get endpointslice -l kubernetes.io/service-name=kube-dns kubectl -n kube-system logs -l k8s-app=kube-dns --tail=100
Это распространённые имена и метки CoreDNS; в вашем кластере они могут отличаться. Проверьте готовые адреса, перезапуски, ошибки upstream и задержки на отдельных узлах. Если внутренние имена быстрые, а внешние дают тайм-аут, исследуйте forwarding к upstream и его доступность. Если ответы не доходят только из выбранного namespace, проверьте NetworkPolicy для UDP и TCP 53, а не увеличивайте replicas CoreDNS вслепую.
Меняем ndots локально и измеряем эффект
Для приложения с большим числом внешних запросов можно проверить собственную настройку Pod. Фрагмент добавляется в spec.template.spec Deployment. Он сохраняет обычную dnsPolicy и переопределяет нужную option:
dnsPolicy: ClusterFirst
dnsConfig:
options:
- name: ndots
value: "2"После изменения пересоздаётся Pod по новому шаблону; проверьте его resolv.conf повторно. Уменьшение ndots меняет порядок поиска и для некоторых внутренних имён, поэтому сравните обе группы запросов. В частности, имя с двумя точками может сначала проверяться как абсолютное. Настройка должна улучшать ваш набор обращений, а не только один искусственно выбранный внешний домен.
Сохраните измерения до и после: какое имя, из какого Pod, каким resolver, с кэшем или без него. Закончить расследование стоит подтверждённым сокращением задержки в самом приложении.
Ещё по теме
- Service в Kubernetes не отвечает: проверяем selector и EndpointSlice
- Forbidden в Kubernetes: проверяем ServiceAccount, Role и RoleBinding
Продолжить изучение
Хотите увереннее разворачивать приложения и разбирать сбои в кластере? Сети, конфигурация, хранилища и обновления входят в программу «Kubernetes с нуля до PRO».
Продолжить на практике
- Kubernetes с нуля до PRO ↗
Разворачивайте и сопровождайте приложения в Kubernetes: от первого Pod до релизов, сетей, хранилищ, масштабирования и диагностики. Итоговый проект — сервис с базой данных, мониторингом и проверенным откатом.
