Cum obține un pod Kubernetes o adresă IP?

Notă. transl.: Acest articol, scris de un inginer SRE de la LinkedIn, intră în detaliu despre magia interioară din Kubernetes - mai precis, interacțiunea dintre CRI, CNI și kube-apiserver - care se întâmplă atunci când următorului pod trebuie să i se atribuie o adresă IP.

Una dintre cerințele de bază Modelul de rețea Kubernetes este că fiecare pod trebuie să aibă propria sa adresă IP și orice alt pod din cluster trebuie să îl poată contacta la acea adresă. Există mulți „furnizori” de rețea (Flannel, Calico, Canal etc.) care ajută la implementarea acestui model de rețea.

Când am început să lucrez cu Kubernetes, nu mi-a fost complet clar cum își obțin adresele IP exact pod-urile. Chiar și cu o înțelegere a modului în care funcționau componentele individuale, era dificil să ne imaginăm că acestea lucrează împreună. De exemplu, știam pentru ce sunt pluginurile CNI, dar nu aveam idee cum se numesc exact. Prin urmare, am decis să scriu acest articol pentru a împărtăși cunoștințele despre diferitele componente ale rețelei și despre modul în care acestea funcționează împreună într-un cluster Kubernetes, ceea ce permite fiecărui pod să obțină propria sa adresă IP unică.

Există diferite moduri de a organiza rețelele în Kubernetes, la fel cum există diferite opțiuni de rulare pentru containere. Această publicație va folosi Flanel pentru a organiza o rețea într-un cluster și ca mediu executabil - Containerd. De asemenea, presupun că știți cum funcționează rețeaua dintre containere, așa că voi atinge pe scurt, doar pentru context.

Câteva concepte de bază

Containerele și rețeaua: o scurtă prezentare

Există o mulțime de publicații excelente pe Internet care explică modul în care containerele comunică între ele prin rețea. Prin urmare, voi oferi doar o privire de ansamblu asupra conceptelor de bază și mă voi limita la o singură abordare, care implică crearea unui bridge Linux și încapsularea pachetelor. Detaliile sunt omise, deoarece subiectul rețelei de containere în sine merită un articol separat. Link-uri către câteva publicații deosebit de perspicace și educaționale vor fi furnizate mai jos.

Containere pe o singură gazdă

O modalitate de a organiza comunicarea prin adrese IP între containerele care rulează pe aceeași gazdă implică crearea unui bridge Linux. În acest scop, dispozitivele virtuale sunt create în Kubernetes (și Docker) veth (ethernet virtual). Un capăt al dispozitivului veth se conectează la spațiul de nume de rețea al containerului, celălalt la Puntea Linux pe rețeaua gazdă.

Toate containerele de pe aceeași gazdă au un capăt al Vet-ului conectat la o punte prin care pot comunica între ei prin adrese IP. Puntea Linux are, de asemenea, o adresă IP și acționează ca o poartă pentru traficul de ieșire din podurile destinate altor noduri.

Cum obține un pod Kubernetes o adresă IP?

Containere pe diferite gazde

Încapsularea pachetelor este o metodă care permite containerelor de pe diferite noduri să comunice între ele folosind adrese IP. La Flannel, tehnologia este responsabilă pentru această oportunitate. vxlan, care „împachetează” pachetul original într-un pachet UDP și apoi îl trimite la destinație.

Într-un cluster Kubernetes, Flannel creează un dispozitiv vxlan și actualizează tabelul de rute pe fiecare nod în consecință. Fiecare pachet destinat unui container pe o gazdă diferită trece prin dispozitivul vxlan și este încapsulat într-un pachet UDP. La destinație, pachetul imbricat este extras și redirecționat către podul dorit.

Cum obține un pod Kubernetes o adresă IP?
Notă: aceasta este doar o modalitate de a organiza comunicarea în rețea între containere.

Ce este CRI?

CRI (Interfață de rulare a containerului) este un plugin care permite kubelet să utilizeze diferite medii de rulare a containerelor. API-ul CRI este încorporat în diferite timpi de execuție, astfel încât utilizatorii pot alege timpul de execuție la alegere.

Ce este CNI?

Proiect CNI este a specificație pentru a organiza o soluție de rețea universală pentru containerele Linux. În plus, include pluginuri, responsabil pentru diferite funcții la configurarea unei rețele de pod. Pluginul CNI este un fișier executabil care respectă specificația (vom discuta mai jos despre câteva pluginuri).

Alocarea subrețelelor către noduri pentru alocarea adreselor IP pod-urilor

Deoarece fiecare pod dintr-un cluster trebuie să aibă o adresă IP, este important să vă asigurați că această adresă este unică. Acest lucru se realizează prin atribuirea fiecărui nod a unei subrețea unice, de la care pod-urilor de pe acel nod li se atribuie apoi adrese IP.

Controller IPAM nod

Când nodeipam transmis ca parametru flag --controllers kube-controller-manager, alocă o subrețea separată (podCIDR) fiecărui nod din CIDR de cluster (adică, intervalul de adrese IP pentru rețeaua de cluster). Deoarece aceste podCIDR nu se suprapun, devine posibil ca fiecărui pod să i se aloce o adresă IP unică.

Un nod Kubernetes primește un podCIDR atunci când este înregistrat inițial în cluster. Pentru a modifica podCIDR-ul nodurilor, trebuie să le anulați și apoi să le reînregistrați, făcând modificări corespunzătoare în configurația stratului de control Kubernetes între ele. Puteți afișa podCIDR-ul unui nod folosind următoarea comandă:

$ kubectl get no <nodeName> -o json | jq '.spec.podCIDR'
10.244.0.0/24

Kubelet, container runtime și pluginuri CNI: cum funcționează totul

Programarea unui pod per nod implică o mulțime de pași pregătitori. În această secțiune, mă voi concentra numai asupra celor care au legătură directă cu configurarea unei rețele de pod.

Programarea unui pod la un anumit nod declanșează următorul lanț de evenimente:

Cum obține un pod Kubernetes o adresă IP?

Ajutor: Arhitectura pluginurilor Containerd CRI.

Interacțiunea între rularea containerului și pluginurile CNI

Fiecare furnizor de rețea are propriul plugin CNI. Timpul de rulare al containerului îl rulează pentru a configura rețeaua pentru pod pe măsură ce acesta pornește. În cazul containerd, pluginul CNI este lansat de plugin Containerd CRI.

Mai mult, fiecare furnizor are propriul agent. Este instalat pe toate nodurile Kubernetes și este responsabil pentru configurarea rețelei a pod-urilor. Acest agent fie este inclus cu configurația CNI, fie îl creează independent pe nod. Configurația ajută pluginul CRI să stabilească ce plugin CNI să apeleze.

Locația configurației CNI poate fi personalizată; implicit este în /etc/cni/net.d/<config-file>. Administratorii clusterului sunt, de asemenea, responsabili pentru instalarea pluginurilor CNI pe fiecare nod de cluster. Locația lor este, de asemenea, personalizabilă; director implicit - /opt/cni/bin.

Când utilizați containerd, căile pentru configurația pluginului și binarele pot fi setate în secțiune [plugins.«io.containerd.grpc.v1.cri».cni] в fișierul de configurare containerd.

Deoarece folosim Flannel ca furnizor de rețea, să vorbim puțin despre configurarea acestuia:

  • Flanneld (demonul lui Flannel) este de obicei instalat într-un cluster ca un DaemonSet cu install-cni la fel de container init.
  • Install-cni creează Fișierul de configurare CNI (/etc/cni/net.d/10-flannel.conflist) pe fiecare nod.
  • Flanneld creează un dispozitiv vxlan, preia metadatele rețelei de pe serverul API și monitorizează actualizările podului. Pe măsură ce sunt create, acesta distribuie rute către toate podurile din cluster.
  • Aceste rute permit podurilor să comunice între ele prin adrese IP.

Pentru informații mai detaliate despre munca Flannel, vă recomand să folosiți linkurile de la sfârșitul articolului.

Iată o diagramă a interacțiunii dintre pluginul Containerd CRI și pluginurile CNI:

Cum obține un pod Kubernetes o adresă IP?

După cum puteți vedea mai sus, kubelet apelează pluginul Containerd CRI pentru a crea podul, care apoi apelează pluginul CNI pentru a configura rețeaua podului. Procedând astfel, pluginul CNI al furnizorului de rețea apelează alte plugin-uri CNI de bază pentru a configura diverse aspecte ale rețelei.

Interacțiunea dintre pluginurile CNI

Există diverse plugin-uri CNI a căror sarcină este de a ajuta la configurarea comunicării în rețea între containerele de pe gazdă. Acest articol va discuta trei dintre ele.

Plugin CNI Flanel

Când utilizați Flannel ca furnizor de rețea, componenta Containerd CRI apelează Plugin CNI Flanelfolosind fișierul de configurare CNI /etc/cni/net.d/10-flannel.conflist.

$ cat /etc/cni/net.d/10-flannel.conflist
{
  "name": "cni0",
  "plugins": [
    {
      "type": "flannel",
      "delegate": {
         "ipMasq": false,
        "hairpinMode": true,
        "isDefaultGateway": true
      }
    }
  ]
}

Pluginul Flannel CNI funcționează împreună cu Flanneld. În timpul pornirii, Flanneld preia podCIDR și alte detalii legate de rețea de pe serverul API și le salvează într-un fișier /run/flannel/subnet.env.

FLANNEL_NETWORK=10.244.0.0/16 
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450 
FLANNEL_IPMASQ=false

Pluginul Flannel CNI utilizează date de la /run/flannel/subnet.env pentru a configura și a apela pluginul CNI bridge.

Pluginul CNI Bridge

Acest plugin este apelat cu următoarea configurație:

{
  "name": "cni0",
  "type": "bridge",
  "mtu": 1450,
  "ipMasq": false,
  "isGateway": true,
  "ipam": {
    "type": "host-local",
    "subnet": "10.244.0.0/24"
  }
}

Când este apelat pentru prima dată, creează o punte Linux cu «name»: «cni0», care este indicat în config. Apoi se creează o pereche veth pentru fiecare pod. Un capăt al acestuia este conectat la spațiul de nume de rețea al containerului, celălalt este inclus în puntea Linux din rețeaua gazdă. Pluginul CNI Bridge conectează toate containerele gazdă la o punte Linux din rețeaua gazdă.

După ce a terminat de configurat perechea veth, pluginul Bridge apelează plugin-ul CNI IPAM local gazdă. Tipul de plugin IPAM poate fi configurat în configurația CNI pe care pluginul CRI îl folosește pentru a apela pluginul Flannel CNI.

Pluginuri CNI IPAM locale gazdă

Bridge CNI apeluri plugin IPAM local pentru gazdă CNI cu următoarea configurație:

{
  "name": "cni0",
  "ipam": {
    "type": "host-local",
    "subnet": "10.244.0.0/24",
    "dataDir": "/var/lib/cni/networks"
  }
}

Plugin IPAM local pentru gazdă (IP Address Mmanagement - gestionarea adresei IP) returnează adresa IP pentru container din subrețea și stochează IP-ul alocat pe gazdă în directorul specificat în secțiunea dataDir - /var/lib/cni/networks/<network-name=cni0>/<ip>. Acest fișier conține ID-ul containerului căruia îi este atribuită această adresă IP.

Când apelați pluginul IPAM local de gazdă, acesta returnează următoarele date:

{
  "ip4": {
    "ip": "10.244.4.2",
    "gateway": "10.244.4.3"
  },
  "dns": {}
}

Rezumat

Kube-controller-manager atribuie un podCIDR fiecărui nod. Pod-urile fiecărui nod primesc adrese IP din spațiul de adrese din intervalul podCIDR alocat. Deoarece podCIDR-urile nodurilor nu se suprapun, toate pod-urile primesc adrese IP unice.

Administratorul clusterului Kubernetes configurează și instalează kubelet, rularea containerului, agentul furnizorului de rețea și copiază pluginurile CNI în fiecare nod. În timpul pornirii, agentul furnizorului de rețea generează o configurație CNI. Când un pod este programat la un nod, kubelet apelează pluginul CRI pentru a-l crea. Apoi, dacă se folosește containerd, pluginul Containerd CRI apelează pluginul CNI specificat în configurația CNI pentru a configura rețeaua podului. Ca rezultat, podul primește o adresă IP.

Mi-a luat ceva timp să înțeleg toate subtilitățile și nuanțele tuturor acestor interacțiuni. Sper că această experiență vă va ajuta să înțelegeți mai bine cum funcționează Kubernetes. Daca gresesc cu ceva, va rog sa ma contactati la Twitter sau la adresa [e-mail protejat]. Simțiți-vă liber să contactați dacă doriți să discutați aspecte ale acestui articol sau orice altceva. Mi-ar plăcea să discut cu tine!

referințe

Containere și rețea

Cum funcționează Flannel?

CRI și CNI

PS de la traducator

Citește și pe blogul nostru:

Sursa: www.habr.com

Adauga un comentariu