- PVSM.RU - https://www.pvsm.ru -
Прим. перев.: Проблема DNS в Kubernetes, а точнее — настройки параметра ndots
, — на удивление популярна, причём уже не первый [1] год [2]. В очередной заметке по этой теме её автор — DevOps-инженер из крупной брокерской компании в Индии — в весьма простой и лаконичной манере рассказывает, о чём полезно знать коллегам, эксплуатирующим Kubernetes.
Одно из главных преимуществ развёртывания приложений в Kubernetes — беспроблемное обнаружение приложений. Внутрикластерное взаимодействие сильно упрощается благодаря концепции сервиса (Service [3]), которая представляет собой виртуальный IP, поддерживающий набор IP-адресов pod'ов. Например, если сервис vanilla
желает связаться с сервисом chocolate
, он может обратиться напрямую к виртуальному IP для chocolate
. Возникает вопрос: кто в данном случае разрешит DNS-запрос к chocolate
и как?
Разрешение имен DNS настраивается в кластере Kubernetes с помощью CoreDNS [4]. Kubelet прописывает pod с CoreDNS в качестве сервера имен в файлах /etc/resolv.conf
всех pod'ов. Если посмотреть на содержимое /etc/resolv.conf
любого pod'а, оно будет выглядеть примерно следующим образом:
search hello.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.152.183.10
options ndots:5
Эта конфигурация используется DNS-клиентами для перенаправления запросов на DNS-сервер. В файле resolv.conf
содержится следующая информация:
google.com
или mrkaran.dev
не являются FQDN (полными доменными именами [5]). Согласно стандартному соглашению, которому следуют большинство resolver'ов DNS, полными (FDQN) доменами считаются только те, которые заканчиваются точкой «.», представляющей корневую зону. Некоторые resolver'ы умеют добавлять точку самостоятельно. Таким образом, mrkaran.dev.
— полное доменное имя (FQDN), а mrkaran.dev
— нет;ndots
задает пороговое число точек в имени запроса, при достижении которого оно рассматривается как «полное» доменное имя. Подробнее об этом мы поговорим позже, когда будем анализировать последовательность DNS-поиска.
Давайте посмотрим, что происходит, когда мы запрашиваем mrkaran.dev
в pod'е:
$ nslookup mrkaran.dev
Server: 10.152.183.10
Address: 10.152.183.10#53
Non-authoritative answer:
Name: mrkaran.dev
Address: 157.230.35.153
Name: mrkaran.dev
Address: 2400:6180:0:d1::519:6001
Для данного эксперимента я установил уровень логирования CoreDNS на all
(что делает его весьма многословным). Посмотрим на логи pod'а coredns
:
[INFO] 10.1.28.1:35998 - 11131 "A IN mrkaran.dev.hello.svc.cluster.local. udp 53 false 512" NXDOMAIN qr,aa,rd 146 0.000263728s
[INFO] 10.1.28.1:34040 - 36853 "A IN mrkaran.dev.svc.cluster.local. udp 47 false 512" NXDOMAIN qr,aa,rd 140 0.000214201s
[INFO] 10.1.28.1:33468 - 29482 "A IN mrkaran.dev.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.000156107s
[INFO] 10.1.28.1:58471 - 45814 "A IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 56 0.110263459s
[INFO] 10.1.28.1:54800 - 2463 "AAAA IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 68 0.145091744s
Фух. Две вещи здесь привлекают внимание:
NOERROR
(DNS-клиенты его понимают и хранят как результат). NXDOMAIN
означает, что для данного доменного имени запись не найдена. Поскольку mrkaran.dev
не является FQDN-именем (в соответствии с ndots=5
), resolver смотрит на поисковый путь и определяет порядок запросов;А
и АААА
поступают параллельно. Дело в том, что разовые запросы в /etc/resolv.conf
по умолчанию настроены таким образом, что производится параллельный поиск по протоколам IPv4 и IPv6. Отменить подобное поведение можно, добавив опцию single-request
в resolv.conf
.
Примечание: glibc
можно настроить на последовательную отправку этих запросов, а musl
— нет, так что пользователям Alpine следует принять это к сведению.
Давайте еще немного поэкспериментируем с ndots
и посмотрим, как себя ведет этот параметр. Идея проста: ndots
определяет, будет ли DNS-клиент считать домен абсолютным или относительным. Например, как в случае простого google DNS-клиент узнает, является ли этот домен абсолютным? Если задать ndots
равным 1, клиент скажет: «О, в google
нет ни одной точки; пожалуй, пробегусь по всему списку поиска». Однако если запросить google.com
, список суффиксов будет целиком проигнорирован, поскольку запрошенное имя удовлетворяет порогу ndots
(имеется хотя бы одна точка).
Давайте убедимся в этом:
$ cat /etc/resolv.conf
options ndots:1
$ nslookup mrkaran
Server: 10.152.183.10
Address: 10.152.183.10#53
** server can't find mrkaran: NXDOMAIN
Логи CoreDNS:
[INFO] 10.1.28.1:52495 - 2606 "A IN mrkaran.hello.svc.cluster.local. udp 49 false 512" NXDOMAIN qr,aa,rd 142 0.000524939s
[INFO] 10.1.28.1:59287 - 57522 "A IN mrkaran.svc.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.000368277s
[INFO] 10.1.28.1:53086 - 4863 "A IN mrkaran.cluster.local. udp 39 false 512" NXDOMAIN qr,aa,rd 132 0.000355344s
[INFO] 10.1.28.1:56863 - 41678 "A IN mrkaran. udp 25 false 512" NXDOMAIN qr,rd,ra 100 0.034629206s
Поскольку в mrkaran
нет ни одной точки, поиск проводился по всему списку суффиксов.
Примечание: на практике максимальное значение ndots
ограничено 15; по умолчанию в Kubernetes оно равно 5.
Если приложение выполняет множество внешних сетевых вызовов, DNS может стать узким местом в случае активного трафика, поскольку при разрешении имени выполняется множество лишних запросов (прежде чем система доберется до нужного). Приложения обычно не добавляют корневую зону к доменным именам, однако это вполне тянет на хак. То есть вместо того, чтобы запрашивать api.twitter.com
, вы можете за'hardcode'ить api.twitter.com.
(с точкой) в приложении, что побудит DNS-клиентов выполнять авторитетный поиск сразу в абсолютном домене.
Кроме того, начиная с версии Kubernetes 1.14, расширения dnsConfig
и dnsPolicy
получили статус стабильных. Таким образом, при развертывании pod'а можно уменьшить значение ndots
, скажем, до 3 (и даже до 1!). Из-за этого каждое сообщение внутри узла должно будет включать полный домен. Это один из классических компромиссов, когда приходится выбирать между производительностью и переносимостью. Мне кажется, что переживать об этом стоит только в случае, если сверхнизкие задержки жизненно важны для вашего приложения, поскольку результаты DNS также кэшируются внутри.
Впервые об этой особенности я узнал на K8s-meetup'е [6], прошедшем 25 января. Там шла речь, в том числе, и об этой проблеме.
Вот несколько ссылок для дальнейшего изучения:
Примечание: Я предпочел не использовать dig
в этой статье. dig
автоматически добавляет точку (идентификатор корневой зоны), делая домен «полным» (FQDN), не прогоняя его предварительно через список поиска. Писал об этом в одной из предыдущих публикаций [9]. Тем не менее, довольно удивителен тот факт, что, в общем-то, для стандартного поведения приходится задавать отдельный флаг.
Хорошего DNS'инга! До скорого!
Читайте также в нашем блоге:
Автор: Юлия Шарафитдинова
Источник [14]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/dns-2/348023
Ссылки в тексте:
[1] не первый: https://pracucci.com/kubernetes-dns-resolution-ndots-options-and-why-it-may-affect-application-performances.html
[2] год: https://medium.com/blocket-engineering/embracing-high-request-loads-on-kubernetes-1c9d4e84c508
[3] Service: https://kubernetes.io/docs/concepts/services-networking/service/
[4] CoreDNS: https://coredns.io/
[5] полными доменными именами: https://ru.wikipedia.org/wiki/FQDN
[6] K8s-meetup'е: https://failuremodes.dev/
[7] Объяснение: https://github.com/kubernetes/kubernetes/issues/33554#issuecomment-266251056
[8] Расхождения: https://www.openwall.com/lists/musl/2017/03/15/3
[9] одной из предыдущих публикаций: https://mrkaran.dev/posts/dig-overview/
[10] Calico для сети в Kubernetes: знакомство и немного из опыта: https://habr.com/ru/company/flant/blog/485716/
[11] CoreDNS — DNS-сервер для мира cloud native и Service Discovery для Kubernetes: https://habr.com/ru/company/flant/blog/331872/
[12] части 1 и 2 (сетевая модель, оверлейные сети): https://habr.com/ru/company/flant/blog/346304/
[13] часть 3 (сервисы и обработка трафика): https://habr.com/ru/company/flant/blog/433382/
[14] Источник: https://habr.com/ru/post/490174/?utm_source=habrahabr&utm_medium=rss&utm_campaign=490174
Нажмите здесь для печати.