Прим. прев.: Проблемата с DNS в Kubernetes, а именно — настройването на параметъра ndots, — изненадващо популярна, и то вече . В поредната статия по темата нейният автор — DevOps-инженер от голяма брокерска компания в Индия — по много прост и сбит начин разказва какво е полезно да знаят колегите, експлоатиращи Kubernetes.

Едно от основните предимства на разгръщането на приложения в Kubernetes — безпроблемното откриване на приложения. Вътрешноклъстерната комуникация се опростява значително благодарение на концепцията за услуга (), която представлява виртуален IP, поддържащ набор от IP адреси на pod-ове. Например, ако услугата vanilla желая да се свърже с услугата chocolate, тя може да се обърне директно към виртуалния IP за chocolate. Възниква въпросът: кой в този случай ще разреши DNS запитването към chocolate и как?
Разрешаването на DNS имена се настройва в клъстера Kubernetes с помощта на . Kubelet записва pod с CoreDNS като DNS сървър в файловете на /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 се съдържа следната информация:
- nameserver: сървърът, към който ще бъдат насочвани DNS запитванията. В нашия случай това е адресът на услугата CoreDNS;
- search: определя пътя на търсене на определен домейн. Интересно е, че
google.comилиmrkaran.devне са FQDN (). Според стандартното споразумение, следвано от повечето DNS резолвери, пълните (FDQN) домейни се считат само тези, които завършват с точка «.», представляваща кореновата зона. Някои резолвери могат да добавят точката сами. По този начин,mrkaran.dev.е пълно домейн име (FQDN), аmrkaran.devне е; - ndots: Най-интересният параметър (тази статия е точно за него).
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:
[ИНФО] 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
[ИНФО] 10.1.28.1:34040 - 36853 "A IN mrkaran.dev.svc.cluster.local. udp 47 false 512" NXDOMAIN qr,aa,rd 140 0.000214201s
[ИНФО] 10.1.28.1:33468 - 29482 "A IN mrkaran.dev.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.000156107s
[ИНФО] 10.1.28.1:58471 - 45814 "A IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 56 0.110263459s
[ИНФО] 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), резолверът гледа на пътя за търсене и определя реда на запитванията; - Записите
АиAAAAAпоступват паралелно. Става въпрос, че единичните запитвания в/etc/resolv.confпо подразбиране са настроени по такъв начин, че се извършва парален търсене по протоколите IPv4 и IPv6. Такова поведение може да бъде отменено, добавяйки опцияsingle-requestвresolv.conf.
Бележка: glibc може да бъде настроено за последователно изпращане на тези запитвания, а musl — не, така че потребителите на Alpine трябва да имат предвид.
Експериментираме с ndots
Нека експериментираме още малко с ndots и да видим как се държи този параметър. Идеята е проста: ndots определя, дали DNS клиентът ще счита домена за абсолютен или относителен. Например, как в случай на прост google DNS клиент, той установява, че доменът е абсолютен? Ако зададете ndots равен на 1, клиентът ще каже: „О, в google няма нито една точка; вероятно ще прегледам целия списък за търсене“. Обаче, ако поискате google.com, списъкът с суфикси ще бъде напълно игнориран, тъй като запитаното име удовлетворява прага ndots (има поне една точка).
Нека се уверим в това:
$ cat /etc/resolv.conf
options ndots:1
$ nslookup mrkaran
Сървър: 10.152.183.10
Адрес: 10.152.183.10#53
** сървърът не може да намери mrkaran: NXDOMAINЛогове на CoreDNS:
[ИНФО] 10.1.28.1:52495 - 2606 "A IN mrkaran.hello.svc.cluster.local. udp 49 false 512" NXDOMAIN qr,aa,rd 142 0.000524939s
[ИНФО] 10.1.28.1:59287 - 57522 "A IN mrkaran.svc.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.000368277s
[ИНФО] 10.1.28.1:53086 - 4863 "A IN mrkaran.cluster.local. udp 39 false 512" NXDOMAIN qr,aa,rd 132 0.000355344s
[ИНФО] 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.
Приложение в production
Ако приложението извършва множество външни мрежови извиквания, DNS може да се превърне в тясно място при активен трафик, тъй като при разрешаване на името се извършват множество излишни запитвания (преди системата да стигне до необходимото). Приложенията обикновено не добавят кореновата зона към домейн имената, но това определено е вариант. Тоест вместо да запитвате api.twitter.com, можете да 'hardcode'нете api.twitter.com. (с точка) в приложението, което ще накара DNS клиентите да извършат авторитетно търсене веднага в абсолютния домейн.
Освен това, от версия 1.14 на Kubernetes, разширенията dnsConfig и dnsPolicy получиха статус стабилни. По този начин при разгръщане на pod можете да намалите стойността ndots, да речем, на 3 (даже до 1!). Поради това всяко съобщение в рамките на възела трябва да включва пълния домейн. Това е един от класическите компромиси, когато се налага да избирате между производителност и преносимост. Мисля, че трябва да се притеснявате само в случаи, когато свръхниските закъснения са жизненоважни за вашето приложение, тъй като резултатите от DNS също се кешират вътре.
Връзки
За първи път узнах за тази функция на , проведен на 25 януари. Там беше обсъдено, включително и този проблем.
Ето няколко линка за по-нататъшно проучване:
- , защо ndots=5 в Kubernetes;
- как промените в ndots влияят на производителността на приложението;
- между resolver'ите musl и glibc.
Забележка: Предпочетох да не използвам dig в тази статия. dig автоматично добавя точка (идентификатор на кореновата зона), правейки домейна 'пълен' (FQDN), не пропускайки го първо през списъка за търсене. Писах за това в . Все пак е доста удивително, че за стандартното поведение трябва да се задава отделен флаг.
Хубав DNS! До скоро!
P.S. от преводача
Прочетете също в нашия блог:
- «»;
- «»;
- «Илюстрировано ръководство за структурата на мрежата в Kubernetes»: , .
Източник: habr.com
