Nota di traduzione.: questo articolo, scritto da un ingegnere SRE di LinkedIn, descrive nei dettagli quella «magia interna» in Kubernetes — più precisamente, l'interazione tra CRI, CNI e kube-apiserver, — che avviene quando a un pod viene richiesto di ottenere un indirizzo IP.
Una delle richieste di base è che ogni pod deve avere un proprio indirizzo IP e qualsiasi altro pod nel cluster deve essere in grado di comunicare con esso tramite questo indirizzo. Ci sono molti «provider» di rete (Flannel, Calico, Canal, ecc.) che aiutano a implementare questo modello di rete.
Quando ho appena iniziato a lavorare con Kubernetes, non mi era molto chiaro come i pod ottenessero i loro indirizzi IP. Anche avendo compreso come funzionano i singoli componenti, era difficile immaginare come lavorassero insieme. Ad esempio, sapevo a cosa servivano i plugin CNI, ma non capivo come venissero chiamati. Quindi ho deciso di scrivere questo articolo per condividere le mie conoscenze sui diversi componenti di rete e sulla loro interazione all'interno del cluster Kubernetes, che consentono a ciascun pod di ottenere il proprio indirizzo IP unico.
Esistono diversi modi per organizzare l'interazione di rete in Kubernetes — analogamente ai vari ambienti di esecuzione (runtime) per i contenitori. In questa pubblicazione verrà utilizzato per organizzare la rete nel cluster, e come ambiente di esecuzione — . Inoltre, presumo che sappiate come funziona l'interazione di rete tra i contenitori, quindi ne tratterò brevemente, esclusivamente per contesto.
Alcuni concetti di base
Contenitori e rete: panoramica sintetica
Ci sono molte ottime pubblicazioni online che spiegano come i contenitori si connettano tra loro in rete. Pertanto, fornirò solo una panoramica generale dei concetti principali e mi limiterò a un approccio che implica la creazione di un bridge Linux e l'incapsulazione dei pacchetti. I dettagli sono omessi, poiché l'argomento dell'interazione di rete tra contenitori meriterebbe un articolo a parte. Di seguito verranno forniti collegamenti ad alcune pubblicazioni particolarmente sostanziose e istruttive.
Contenitori su un host
Uno dei modi per organizzare la comunicazione tramite indirizzi IP tra i container che lavorano sulla stessa host prevede la creazione di un bridge Linux. Per questo in Kubernetes (e Docker) vengono creati dispositivi virtuali . Un'estremità del dispositivo veth è collegata allo spazio dei nomi di rete del container, l'altra è collegata a nella rete dell'host.
Tutti i container su un host hanno una delle estremità veth collegata al bridge, attraverso il quale possono comunicare tra loro tramite indirizzi IP. Il bridge Linux ha anche un indirizzo IP e funge da gateway per il traffico in uscita (egress) dai pod destinati ad altri nodi.

Container su host diversi
L'incapsulazione dei pacchetti è uno dei modi che consentono ai container su nodi diversi di comunicare tra loro tramite indirizzi IP. In Flannel, questa funzionalità è gestita dalla tecnologia , che "imballa" il pacchetto originale in un pacchetto UDP e poi lo invia alla sua destinazione.
Nel cluster Kubernetes, Flannel crea un dispositivo vxlan e completa opportunamente la tabella di routing su ciascun nodo. Ogni pacchetto destinato a un container su un altro host passa attraverso il dispositivo vxlan e viene incapsulato in un pacchetto UDP. Alla destinazione, il pacchetto incapsulato viene estratto e reindirizzato al pod corretto.

Nota: Questo è solo uno dei modi per organizzare l'interazione di rete tra i container.
Che cos'è il CRI?
è un plugin che consente a kubelet di utilizzare diversi ambienti di esecuzione dei container. L'API CRI è integrata in vari ambienti di esecuzione, consentendo agli utenti di scegliere il runtime secondo le loro esigenze.
Che cos'è il CNI?
rappresenta per fornire una soluzione di rete universale per i container Linux. Inoltre, include , responsabili di varie funzioni durante la configurazione della rete del pod. Un plugin CNI è un file eseguibile, conforme alla specifica (alcuni plugin di cui parleremo di seguito).
Assegnazione di subnet ai nodi per l'assegnazione degli indirizzi IP ai pod
Poiché ogni pod del cluster deve avere un indirizzo IP, è fondamentale assicurarsi che tale indirizzo sia unico. Questo viene raggiunto assegnando a ciascun nodo una subnet unica, da cui vengono poi assegnati gli indirizzi IP ai pod su quel nodo.
Controller IPAM del nodo
Quando nodeipam viene passato come parametro del flag --controllers , assegna a ciascun nodo una sottorete separata (podCIDR) dall'intervallo CIDR del cluster (cioè l'intervallo degli indirizzi IP per la rete del cluster). Poiché questi podCIDR non si sovrappongono, è possibile assegnare a ciascun pod un indirizzo IP unico.
Al nodo Kubernetes viene assegnato un podCIDR al momento della sua registrazione iniziale nel cluster. Per modificare il podCIDR dei nodi, è necessario deregistrali e poi registrali nuovamente, apportando nel frattempo le modifiche appropriate nella configurazione del piano di controllo di Kubernetes. È possibile visualizzare il podCIDR di un nodo utilizzando il seguente comando:
$ kubectl get no -o json | jq '.spec.podCIDR'
10.244.0.0/24
Kubelet, ambiente di esecuzione dei container e plugin CNI: come funziona tutto questo
La pianificazione di un pod su un nodo è legata all'esecuzione di numerose azioni preparatorie. In questa sezione mi concentrerò solo su quelle direttamente correlate alla configurazione della rete del pod.
La pianificazione di un pod su un nodo avvia la seguente catena di eventi:

Aiuto: .
Interazione tra l'ambiente di esecuzione dei container e i plugin CNI
Ogni fornitore di rete ha il proprio plugin CNI. Il runtime del container lo avvia per configurare la rete per il pod durante il processo di avvio. Nel caso di containerd, l'avvio del plugin CNI è gestito dal plugin .
In questo caso, ogni fornitore ha il proprio agente. Viene installato su tutti i nodi Kubernetes e si occupa della configurazione della rete dei pod. Questo agente è fornito insieme alla configurazione CNI o viene creato autonomamente nel nodo. La configurazione aiuta il plugin CRI a stabilire quale plugin CNI chiamare.
La posizione della configurazione CNI è configurabile; per impostazione predefinita si trova in /etc/cni/net.d/<config-file>. Gli amministratori del cluster sono anche responsabili della installazione dei plugin CNI su ogni nodo del cluster. Anche la loro posizione è configurabile; la directory predefinita è /opt/cni/bin.
Quando si utilizza containerd, i percorsi per la configurazione e i binari del plugin possono essere specificati nella sezione [plugins."io.containerd.grpc.v1.cri".cni] in .
Poiché stiamo utilizzando Flannel come fornitore di rete, parliamo un po' della sua configurazione:
- Flanneld (il demone di Flannel) viene solitamente installato nel cluster come DaemonSet con
install-cnicome . Install-cnicrea (/etc/cni/net.d/10-flannel.conflist) su ogni nodo.- Flannel crea un dispositivo vxlan, estrae i metadati di rete dall'API server e tiene traccia degli aggiornamenti dei pod. Man mano che questi vengono creati, diffonde le rotte per tutti i pod in tutto il cluster.
- Queste rotte consentono ai pod di comunicare tra loro attraverso indirizzi IP.
Per ulteriori informazioni sul funzionamento di Flannel, ti consiglio di consultare i collegamenti presenti alla fine dell'articolo.
Ecco lo schema di interazione tra il plugin Containerd CRI e i plugin CNI:

Come si può vedere sopra, kubelet chiama il plugin Containerd CRI per creare un pod, il quale a sua volta chiama il plugin CNI per configurare la rete del pod. In questo processo, il plugin CNI del fornitore di rete chiama altri plugin CNI di base per configurare vari aspetti della rete.
Interazione tra i plugin CNI
Esistono diversi plugin CNI la cui funzione è quella di aiutare a configurare l'interazione di rete tra i contenitori sull'host. In questo articolo parleremo di tre di essi.
Plugin CNI Flannel
Quando si utilizza Flannel come fornitore di rete, il componente Containerd CRI chiama , utilizzando il file di configurazione 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
}
}
]
}
Il plugin CNI Flannel opera in collaborazione con Flanneld. Durante l'avvio, Flanneld estrae podCIDR e altri dettagli relativi alla rete dall'API server e li salva in un file /run/flannel/subnet.env.
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false
Il plugin CNI Flannel utilizza i dati di /run/flannel/subnet.env per configurare e chiamare il plugin CNI bridge.
Plugin CNI Bridge
Questo plugin viene chiamato con la seguente configurazione:
{
"name": "cni0",
"type": "bridge",
"mtu": 1450,
"ipMasq": false,
"isGateway": true,
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24"
}
}
Alla prima chiamata, crea un bridge Linux con "name": "cni0", che è specificato nella configurazione. Quindi, per ogni pod viene creata una coppia veth. Un'estremità di essa è collegata allo spazio dei nomi di rete del contenitore, mentre l'altra entra nel bridge Linux nella rete dell'host. collega tutti i contenitori dell'host al bridge Linux nella rete dell'host.
Completata la configurazione della coppia veth, il plugin Bridge chiama il plugin IPAM locale per l'host (host-local) CNI. Il tipo di plugin IPAM può essere configurato nel file di configurazione CNI, che il plugin CRI utilizza per chiamare il plugin CNI Flannel.
Plugin IPAM locali per l'host CNI
Il Bridge CNI chiama con la seguente configurazione:
{
"name": "cni0",
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24",
"dataDir": "/var/lib/cni/networks"
}
}
Plugin IPAM host-local (IP Aindirizzo Mgestione — gestione degli indirizzi IP) restituisce un indirizzo IP per il contenitore dalla subnet e conserva l'IP allocato sull'host nella directory specificata nella sezione dataDir — /var/lib/cni/networks/<network-name=cni0>/<ip>. Questo file contiene l'ID del contenitore a cui è stato assegnato questo indirizzo IP.
Quando si chiama il plugin IPAM host-local, restituisce i seguenti dati:
{
"ip4": {
"ip": "10.244.4.2",
"gateway": "10.244.4.3"
},
"dns": {}
}
Riepilogo
Kube-controller-manager assegna un podCIDR a ciascun nodo. I pod di ogni nodo ricevono indirizzi IP dallo spazio degli indirizzi nell'intervallo assegnato podCIDR. Poiché i podCIDR dei nodi non si sovrappongono, tutti i pod ricevono indirizzi IP unici.
L'amministratore del cluster Kubernetes configura e installa kubelet, l'ambiente di runtime dei contenitori, l'agente del provider di rete e copia i plugin CNI su ogni nodo. Durante l'avvio, l'agente del provider di rete genera la configurazione CNI. Quando un pod viene pianificato su un nodo, kubelet chiama il plugin CRI per crearlo. Successivamente, se viene utilizzato containerd, il plugin Containerd CRI chiama il plugin CNI specificato nella configurazione CNI per configurare la rete del pod. Di conseguenza, il pod riceve un indirizzo IP.
Mi ci è voluto del tempo per capire tutte le sottigliezze e le complessità di tutte queste interazioni. Spero che l'esperienza acquisita possa aiutarti a comprendere meglio come funziona Kubernetes. Se ho commesso un errore, ti prego di contattarmi a o all'indirizzo . Non esitare a contattarmi se vuoi discutere gli aspetti di questo articolo o qualsiasi altra cosa. Sarò felice di chiacchierare con te!
Link
Contenitori e rete
Come funziona Flannel
CRI e CNI
P.S. dal traduttore
Leggi anche nel nostro blog:
- «»;
- «Guida illustrata alla configurazione della rete in Kubernetes»: , ;
- «».
Fonte: habr.com
