Wyszukiwanie DNS w Kubernetes

Notatka. przeł.: Problem z DNS w Kubernetesie, a dokładniej z ustawieniami parametrów ndots, jest zaskakująco popularny i już Nie pierwszy rok. W innej notatce na ten temat jej autor, inżynier DevOps z dużej firmy brokerskiej w Indiach, w bardzo prosty i zwięzły sposób opowiada o tym, co przyda się współpracownikom obsługującym Kubernetes.

Wyszukiwanie DNS w Kubernetes

Jedną z głównych korzyści wdrażania aplikacji na Kubernetesie jest płynne odkrywanie aplikacji. Interakcja wewnątrz klastra jest znacznie uproszczona dzięki koncepcji usług (Usługi), który jest wirtualnym adresem IP obsługującym zestaw adresów IP pod. Na przykład, jeśli usługa vanilla chce skontaktować się z serwisem chocolate, może uzyskać bezpośredni dostęp do wirtualnego adresu IP chocolate. Powstaje pytanie: kto w tym przypadku rozwiąże żądanie DNS chocolate I jak?

Rozpoznawanie nazw DNS jest konfigurowane w klastrze Kubernetes przy użyciu CoreDNS. Kubelet rejestruje pod w CoreDNS jako serwer nazw w plikach /etc/resolv.conf wszystkie strąki. Jeśli spojrzysz na treść /etc/resolv.conf dowolny pod, będzie wyglądać mniej więcej tak:

search hello.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.152.183.10
options ndots:5

Ta konfiguracja jest używana przez klientów DNS do przekazywania żądań do serwera DNS. W pliku resolv.conf zawiera następujące informacje:

  • serwer nazw: serwer, do którego będą wysyłane żądania DNS. W naszym przypadku jest to adres usługi CoreDNS;
  • szukanie: Określa ścieżkę wyszukiwania dla określonej domeny. To ciekawe google.com lub mrkaran.dev nie są nazwami FQDN (w pełni kwalifikowane nazwy domen). Zgodnie ze standardową konwencją stosowaną przez większość programów rozpoznawania nazw DNS, tylko te domeny zakończone kropką „.”, reprezentującą strefę główną, są uważane za domeny w pełni kwalifikowane (FDQN). Niektóre rozwiązania mogą samodzielnie dodać punkt. Zatem, mrkaran.dev. to w pełni kwalifikowana nazwa domeny (FQDN), oraz mrkaran.dev - NIE;
  • kropki: Najciekawszy parametr (o tym jest ten artykuł). ndots określa próg liczby kropek w nazwie żądania, zanim zostanie ona uznana za „w pełni kwalifikowaną” nazwę domeny. Porozmawiamy o tym więcej później, gdy przeanalizujemy sekwencję wyszukiwania DNS.

Wyszukiwanie DNS w Kubernetes

Zobaczmy, co się stanie, gdy zapytamy mrkaran.dev w kapsule:

$ 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

Na potrzeby tego eksperymentu ustawiłem poziom rejestrowania CoreDNS na all (co czyni go dość gadatliwym). Spójrzmy na logi kapsuły 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

Uff. Dwie rzeczy przykuwają tutaj twoją uwagę:

  • Żądanie przechodzi przez wszystkie etapy wyszukiwania, aż w odpowiedzi znajdzie się kod NOERROR (Klienci DNS to rozumieją i w rezultacie przechowują). NXDOMAIN oznacza, że ​​dla podanej nazwy domeny nie odnaleziono żadnego rekordu. Ponieważ mrkaran.dev nie jest nazwą FQDN (wg ndots=5), resolwer sprawdza ścieżkę wyszukiwania i określa kolejność żądań;
  • Nagrania А и АААА przybyć równolegle. Faktem jest, że jednorazowe prośby /etc/resolv.conf Domyślnie są one skonfigurowane w taki sposób, że wyszukiwania równoległe realizowane są z wykorzystaniem protokołów IPv4 i IPv6. Możesz anulować to zachowanie, dodając opcję single-request в resolv.conf.

Uwaga: glibc można skonfigurować tak, aby wysyłać te żądania sekwencyjnie, oraz musl - nie, więc użytkownicy Alpine powinni wziąć to pod uwagę.

Eksperymentowanie z ndotami

Poeksperymentujmy jeszcze trochę ndots i zobaczmy jak zachowuje się ten parametr. Pomysł jest prosty: ndots określa, czy klient DNS będzie traktować domenę jako bezwzględną czy względną. Na przykład w przypadku prostego klienta DNS Google, skąd wie, czy ta domena jest absolutna? Jeśli ustawisz ndots równy 1, klient powie: „Och, w google nie ma ani jednego punktu; Chyba przejrzę całą listę wyszukiwania. Jeśli jednak zapytasz google.com, lista przyrostków zostanie całkowicie zignorowana, ponieważ żądana nazwa spełnia próg ndots (jest co najmniej jeden punkt).

Upewnijmy się co do tego:

$ 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

Dzienniki 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

Ponieważ w mrkaran nie ma ani jednego punktu, przeszukanie przeprowadzono po całej liście przyrostków.

Uwaga: w praktyce wartość maksymalna ndots ograniczona do 15; domyślnie w Kubernetes jest to 5.

Zastosowanie w produkcji

Jeśli aplikacja wykonuje dużo połączeń do sieci zewnętrznej, DNS może stać się wąskim gardłem w przypadku aktywnego ruchu, ponieważ rozpoznawanie nazw generuje wiele niepotrzebnych zapytań (zanim system trafi na właściwe). Aplikacje zwykle nie dodają strefy głównej do nazw domen, ale to brzmi jak hack. To znaczy, zamiast pytać api.twitter.com, możesz go „kodować na stałe”. api.twitter.com. (z kropką) w aplikacji, co poprosi klientów DNS o wykonanie autorytatywnych wyszukiwań bezpośrednio w domenie bezwzględnej.

Dodatkowo począwszy od wersji Kubernetes 1.14, rozszerzenia dnsConfig и dnsPolicy otrzymał status stabilny. Dlatego wdrażając moduł, możesz zmniejszyć tę wartość ndotspowiedzmy do 3 (a nawet do 1!). Z tego powodu każda wiadomość w węźle będzie musiała zawierać pełną domenę. Jest to jeden z klasycznych kompromisów, gdy trzeba wybierać pomiędzy wydajnością a przenośnością. Wydaje mi się, że powinieneś się tym martwić tylko wtedy, gdy dla Twojej aplikacji istotne jest bardzo małe opóźnienie, ponieważ wyniki DNS są również wewnętrznie buforowane.

referencje

Po raz pierwszy dowiedziałem się o tej funkcji na Spotkanie K8s, która odbyła się 25 stycznia. Dyskutowano m.in. na temat tego problemu.

Oto kilka linków do dalszej eksploracji:

Uwaga: zdecydowałem się nie używać dig w tym artykule. dig automatycznie dodaje kropkę (identyfikator strefy root), czyniąc domenę „w pełni kwalifikowaną” (FQDN), nie najpierw przeglądając listę wyszukiwania. Pisałem o tym w jedna z poprzednich publikacji. Jednak dość zaskakujące jest to, że ogólnie rzecz biorąc, dla standardowego zachowania należy określić oddzielną flagę.

Miłego DNSingu! Do zobaczenia później!

PS od tłumacza

Przeczytaj także na naszym blogu:

Źródło: www.habr.com

Dodaj komentarz