Căutare DNS în Kubernetes

Nota traducătorului.: Problema DNS în Kubernetes, mai precis - configurarea parametrului Din manualul pentru, - surprinzător de popular, și deja nu este prima an. Într-o notă recentă pe această temă, autorul său - un inginer DevOps de la o mare companie de brokeraj din India - explică într-un mod foarte simplu și concis ce ar trebui să știe colegii care utilizează Kubernetes.

Căutare DNS în Kubernetes

Unul dintre principalele avantaje ale desfășurării aplicațiilor în Kubernetes este descoperirea fără probleme a aplicațiilor. Interacțiunea intra-cluster este foarte simplificată datorită conceptului de serviciu (Serviciu), care reprezintă un IP virtual, susținând un set de adrese IP ale pod-urilor. De exemplu, dacă serviciul vanilla, vrea să se conecteze la serviciul chocolate, acesta poate accesa direct IP-ul virtual pentru chocolate. Întrebarea care apare este: cine va rezolva în acest caz interogarea DNS pentru chocolate și cum?

Rezolvarea numelui DNS este configurată în clusterul Kubernetes folosind CoreDNS. Kubelet scrie pod-ul cu CoreDNS ca server de nume în fișierele /etc/resolv.conf ale tuturor pod-urilor. Dacă privim conținutul /etc/resolv.conf oricărui pod, acesta va arăta aproximativ în felul următor:

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

Această configurație este utilizată de clienții DNS pentru a redirecționa cererile către serverul DNS. În fișierul resolv.conf se găsește următoarea informație:

  • nameserver: serverul către care vor fi direcționate cererile DNS. În cazul nostru, aceasta este adresa serviciului CoreDNS;
  • Există o opțiune: definește calea de căutare a unui anumit domeniu. Este interesant că google.com sau mrkaran.dev nu sunt FQDN (nume de domeniu complet). Conform convenției standard urmate de majoritatea rezolvatorilor DNS, domeniile complete (FDQN) sunt considerate doar cele care se termină cu un punct „.”, reprezentând zona rădăcină. Unii rezolvatori pot adăuga punctul automat. Astfel, mrkaran.dev. este un nume de domeniu complet (FQDN), iar mrkaran.dev nu este;
  • Din manualul pentru: cel mai interesant parametru (această articol este despre el). Din manualul pentru definește numărul prag al punctelor în numele cererii, la atingerea căruia acesta este considerat un „nume de domeniu complet”. Mai multe detalii despre acest lucru vom discuta mai târziu, când vom analiza secvența de căutare DNS.

Căutare DNS în Kubernetes

Să vedem ce se întâmplă când solicităm mrkaran.dev în 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

Pentru acest experiment, am setat nivelul de logare al CoreDNS la all (ceea ce îl face destul de prolix). Să ne uităm la jurnalele pod-ului 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

Uf. Două lucruri aici atrag atenția:

  • Solicitarea trece prin toate etapele de căutare până când răspunsul nu conține codul NOERROR (DNS-clienții îl înțeleg și îl stochează ca rezultat). NXDOMAIN înseamnă că pentru acest nume de domeniu, înregistrarea nu a fost găsită. Deoarece mrkaran.dev nu este un nume FQDN (conform ndots=5), rezolvatorul se uită la calea de căutare și determină ordinea solicitărilor;
  • Înregistrările Un și AAAA sunt procesate simultan. Problema este că solicitările unice în /etc/resolv.conf sunt configurate implicit astfel încât să se efectueze căutări paralele prin protocoalele IPv4 și IPv6. Acest comportament poate fi anulat prin adăugarea opțiunii single-request în resolv.conf.

Notă: glibc poate fi configurat pentru a trimite aceste solicitări în mod secvențial, iar musl — nu, astfel încât utilizatorii Alpine ar trebui să ia în considerare acest lucru.

Experimentăm cu ndots

Hai să experimentăm puțin cu Din manualul pentru și să vedem cum se comportă acest parametru. Ideea este simplă: Din manualul pentru determină dacă clientul DNS va considera domeniul absolut sau relativ. De exemplu, în cazul simplu al google, clientul DNS cum știe dacă acest domeniu este absolut? Dacă se setează Din manualul pentru la 1, clientul va spune: „O, în google nu sunt puncte; probabil ar trebui să parcurg întreaga listă de căutare”. Totuși, dacă se solicită google.com, lista sufixelor va fi complet ignorată, deoarece numele solicitat îndeplinește pragul Din manualul pentru (există cel puțin un punct).

Să ne asigurăm de asta:

$ 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

Jurnalele 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

Deoarece în mrkaran nu există puncte, căutarea s-a efectuat în întreaga listă de sufixe.

Notă: în practică, valoarea maximă Din manualul pentru este limitată la 15; implicit în Kubernetes este 5.

Utilizare în producție

Dacă aplicația efectuează numeroase apeluri externe de rețea, DNS-ul poate deveni un punct slab în cazul unui trafic activ, deoarece la rezolvarea numelui se efectuează multe solicitări suplimentare (înainte ca sistemul să ajungă la cel dorit). Aplicațiile, de obicei, nu adaugă zona rădăcină la numele de domeniu, însă aceasta este o soluție validă. Asta înseamnă că, în loc să solicite api.twitter.com, puteți să-l 'hardcodați' api.twitter.com. (cu punct) în aplicație, ceea ce va determina clienții DNS să efectueze o căutare autoritară direct în domeniul absolut.

De asemenea, începând cu versiunea Kubernetes 1.14, extensiile dnsConfig și ClusterFirst, au primit statut stabil. Astfel, la desfășurarea unui pod, puteți reduce valoarea Din manualul pentru, să zicem, la 3 (și chiar la 1!). Din acest motiv, fiecare mesaj dintr-un nod va trebui să conțină domeniul complet. Acesta este unul dintre compromisul clasic, când trebuie să alegeți între performanță și portabilitate. Cred că merită să vă faceți griji despre acest lucru doar în cazul în care întârzierile extrem de mici sunt esențiale pentru aplicația dumneavoastră, deoarece rezultatele DNS sunt, de asemenea, în cache în interior.

Linkuri

Am aflat pentru prima dată despre această caracteristică la K8s-meetup, care a avut loc pe 25 ianuarie. A fost discutat, printre altele, și această problemă.

Iată câteva linkuri pentru studiu suplimentar:

Notă: Am preferat să nu folosesc dig în acest articol. dig adaugă automat un punct (identificatorul zonei rădăcină), transformând domeniul într-unul «complet» (FQDN), nu trecându-l anterior prin lista de căutare. Am scris despre aceasta în una dintre publicațiile anterioare. Cu toate acestea, este destul de surprinzător faptul că, în general, pentru comportamentul standard trebuie să specificați un steag separat.

O zi bună de DNS! Pe curând!

P.S. de la traducător

Citiți și în blogul nostru:

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster