De ce podurile GKE nu ajung la gazdele locale prin VPN
Nodul ajunge la rețeaua locală, podul nu. Excepțiile de masquerade din GKE lasă adresele podurilor netraduse pentru destinațiile 10.x.
Pingul funcționează de pe nod și eșuează de pe pod, iar local nu ajunge nimic. Tunelul și ruta sunt în regulă; adresa sursă de pe fir nu. Ceea ce diferențiază cele două cazuri este ce declară pachetul că este atunci când părăsește clusterul, iar GKE are o părere despre asta. Mecanismul este o listă de excepții de masquerade, iar citirea ei cere o singură comandă.
Citiți lista efectivă înainte de a schimba ceva
GKE livrează un agent care decide, pentru fiecare interval de destinație, dacă traficul podurilor este rescris la adresa nodului la ieșire. Configurația livrată numește cele trei blocuri RFC1918, 10.0.0.0/8, 172.16.0.0/12 și 192.168.0.0/16, ca destinații exceptate. De aceea tot ce trimiți dintr-un pod către o gazdă 10.x locală părăsește nodul cu adresa podului încă atașată. Traficul nodului însuși nu este rescris, și exact de aceea pingul lui funcționează.
Citiți configurația dorită și regulile instalate, pentru că pot să nu fie de acord. kubectl -n kube-system get configmap ip-masq-agent -o yaml arată ce i s-a spus agentului, iar kubectl -n kube-system get pods -l k8s-app=ip-masq-agent arată dacă rulează ceva care să aplice asta. Pe un nod, iptables-save | grep -i masq arată regulile care există cu adevărat în kernel. Când ConfigMap spune una și regulile alta, suspectul este agentul, nu rețeaua.
Confirmați adresa sursă cu o captură
Faceți o captură înainte de a schimba o listă. Un filtru pe singura destinație menține ieșirea lizibilă: tcpdump -ni any host 10.20.30.40.
Comparați cu ce raportează cealaltă parte. O captură locală care arată adresa podului și niciun răspuns închide cercul: lista de excepții explică asimetria fără nicio defecțiune a tunelului. Două observații ale aceleiași adrese sursă sunt suficiente pentru a nu mai specula despre CNI.
Îngustați excepția la CIDR-ul podurilor
Reparația acceptată îngustează exceptarea în loc să o elimine: păstrați CIDR-ul podurilor exceptat și renunțați la restul spațiului 10.x. Acea listă se află în ConfigMap-ul agentului sub nonMasqueradeCIDRs, iar modificarea ei este o editare urmată de o implementare. Înlocuiți intrarea largă cu intervalul real de poduri al clusterului, păstrați celelalte blocuri private dacă traficul din interiorul clusterului încă le necesită, și lăsați resyncInterval în pace dacă nu aveți un motiv. Aplicați, confirmați că podurile agentului s-au repornit și confirmați că regulile din kernel s-au schimbat.
Aceasta este o schimbare la nivelul întregului cluster cu o rază de impact reală. După ce se aplică, traficul care înainte își păstra sursa podului ajunge acum rescris pe nod, așa că tot ce se baza pe acele adrese de pod vede un alt expeditor. Victimele sunt jurnalele, listele de permisiuni și regulile de firewall locale care numesc adrese de pod, și eșuează în tăcere. Anunțați schimbarea ca schimbare de comportament, nu ca remediere.
Într-un cluster cu mai multe pool-uri de noduri, verificați că agentul este programat pe nodurile unde rulează cu adevărat podurile afectate. Un pool fără DaemonSet își păstrează regulile vechi, iar nimic din ConfigMap nu va arăta asta.
Alternativa și costul ei
Cealaltă opțiune păstrează adresele podurilor intacte și învață calea despre ele. CIDR-ul podurilor intră în selectorii de trafic Cloud VPN, iar partea locală are nevoie de o rută de întoarcere pentru el, ca răspunsurile să știe unde să meargă. Asta păstrează identitatea podului, pe care unele modele de securitate o vor, și lărgește atât sfera de rutare, cât și sfera de firewall pe care cealaltă parte trebuie să o accepte.
Schimbul este lizibilitate contra amploare. Traducerea face partea locală să vadă o adresă pe nod, ceea ce e ușor de pus pe o listă de permisiuni și ascunde care pod a trimis ce. Fără traducere, adresa podului este păstrată cap-coadă, ceea ce e mai bun pentru atribuire și mai rău pentru fiecare dispozitiv de pe cale care trebuie să învețe un interval nou. Niciuna dintre opțiuni nu este un defect Docker sau CNI; ambele sunt decizii de rutare cu o factură operațională. Alegeți-o pe cea a cărei factură poate fi plătită de echipa voastră și scrieți de ce.
Verificați și reveniți
Rulați aceeași captură din nou. O captură la nivel de nod care încă afișează adresa podului după editarea voastră înseamnă că regulile nu s-au schimbat niciodată, orice ar spune ConfigMap. Firul este faptul; restul este inferență.
Apoi verificați direcția inversă, pentru că jumătate din aceste schimbări sunt verificate doar la ieșire. Confirmați că răspunsul ajunge la nodul sau podul care a trimis cererea și confirmați că aplicația s-a terminat, nu doar a primit un SYN. O captură care arată o cerere fără răspuns este o problemă de rutare pe cealaltă parte, nu o problemă de masquerade pe aceasta.
Revenirea este ConfigMap-ul anterior, aplicat la fel, cu aceeași confirmare că agentul s-a repornit și regulile s-au schimbat. Păstrați adresa sursă înainte și după pentru o cerere cunoscută în registrul de modificări, fiindcă exact acea singură linie dovedește că schimbarea a făcut ce ați spus. Ghidul GKE pentru agentul de masquerade IP documentează valorile implicite și câmpurile ConfigMap. Dacă adresa sursă este neschimbată după implementare, agentul nu rulează pe acel nod și nicio editare YAML nu va rezolva asta.