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ă 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 pentru a organiza o rețea într-un cluster și ca mediu executabil - . 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 online care explică modul în care containerele comunică între ele printr-o rețea. Prin urmare, voi oferi doar o prezentare generală a principalelor concepte și mă voi limita la o singură abordare, care implică crearea Linux- bridging și încapsulare de pachete. Detaliile sunt omise, deoarece subiectul rețelelor de containere în sine merită un articol separat. Linkuri către unele publicații deosebit de informative și pertinente sunt furnizate mai jos.
Containere pe o singură gazdă
O modalitate de a organiza comunicarea prin adrese IP între containere care rulează pe aceeași gazdă implică crearea Linux-bridge. Pentru aceasta, dispozitivele virtuale sunt create în Kubernetes (și Docker) . Un capăt al dispozitivului veth se conectează la spațiul de nume de rețea al containerului, celălalt la pe rețeaua gazdă.
Toate containerele de pe o singură gazdă au un capăt al veth conectat la o punte prin care pot comunica între ele prin adrese IP. Linux-bridge-ul are și o adresă IP și acționează ca o poartă de acces pentru traficul de ieșire (egress) de la pod-uri destinate altor noduri.

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. , 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.

Notă: aceasta este doar o modalitate de a organiza comunicarea în rețea între containere.
Ce este CRI?
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?
este a să organizeze o soluție de rețea universală pentru Linux-containere. În plus, include , 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 , 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:

Ajutor: .
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 .
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] в .
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-cnila fel de . Install-cnicreează (/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:

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ă folosind 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"
}
}
La primul apel creează Linux-pod cu «name»: «cni0», care este specificat în configurație. Apoi, se creează o pereche a veche pentru fiecare pod. Un capăt este conectat la spațiul de nume de rețea al containerului, celălalt este inclus în Linux-bridge în rețeaua gazdă. conectează toate containerele gazdă la Linux-bridge în 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 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 sau la adresa . 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:
- «»;
- „Un ghid ilustrat pentru crearea de rețele în Kubernetes”: , ;
- «".
Sursa: www.habr.com
