Nota del traduttore.: questo articolo, scritto da un ingegnere SRE di LinkedIn, descrive in dettaglio la «magia interna» di Kubernetes — in particolare, l'interazione tra CRI, CNI e kube-apiserver — e cosa succede quando a un pod viene richiesto di assegnare un indirizzo IP.
Uno dei requisiti fondamentali è che ogni pod deve avere un proprio indirizzo IP e qualsiasi altro pod nel cluster deve essere in grado di comunicare con esso a questo indirizzo. Ci sono diversi «fornitori» di rete (Flannel, Calico, Canal, ecc.) che aiutano a implementare questo modello di rete.
Quando ho iniziato a lavorare con Kubernetes, non era chiaro come i pod ottenessero i loro indirizzi IP. Anche comprendendo il funzionamento dei singoli componenti, era difficile immaginare come lavorassero insieme. Ad esempio, sapevo a cosa servono i plugin CNI, ma non capivo come venissero richiamati. Così ho deciso di scrivere questo articolo per condividere la mia conoscenza sui vari componenti di rete e sul loro funzionamento in un cluster Kubernetes, che consente a ogni pod di ricevere il proprio indirizzo IP unico.
Ci sono diversi modi per organizzare la comunicazione di rete in Kubernetes, proprio come ci sono diverse opzioni di ambienti di esecuzione (runtime) per i container. In questa pubblicazione verrà utilizzato per organizzare la rete nel cluster, mentre l'ambiente di esecuzione sarà . Inoltre, presumo che sappiate come funziona la comunicazione di rete tra i container, quindi tratterò brevemente questo argomento solo per fornire contesto.
Alcuni concetti di base
Container e rete: una panoramica breve
Ci sono molte pubblicazioni online eccellenti che spiegano come i container comunicano tra loro attraverso la rete. Pertanto, farò solo una panoramica generale dei concetti fondamentali e mi limiterò a un approccio che implica la creazione di un ponte Linux e l'incapsulamento dei pacchetti. I dettagli sono omessi, poiché il tema della comunicazione di rete tra container meriterebbe un articolo a parte. Di seguito sono forniti collegamenti a alcune pubblicazioni particolarmente informative e interessanti.
Container su un host
Uno dei modi per organizzare la comunicazione tramite indirizzi IP tra i container in esecuzione sulla stessa host, prevede la creazione di un bridge Linux. A tal fine, 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 al nella rete host.
Tutti i container su un host hanno un'estremità del veth collegata al bridge, tramite 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 destinato ad altri nodi.

Container su host diversi
L'incapsulamento dei pacchetti è un modo che consente 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 a destinazione.
Nel cluster Kubernetes, Flannel crea un dispositivo vxlan e integra di conseguenza 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 inviato al pod desiderato.

Nota: Questo è solo uno dei modi per organizzare la comunicazione di rete tra i container.
Che cos'è il CRI?
è un plugin che consente a kubelet di utilizzare diverse ambienti di esecuzione dei container. L'API CRI è integrata in vari ambienti di esecuzione, quindi gli utenti possono scegliere il runtime a loro piacimento.
Che cos'è il CNI?
è rappresentato da fornisce una soluzione di rete universale per i container Linux. Inoltre, include , responsabili di diverse funzioni durante la configurazione della rete del pod. Un plugin CNI è un file eseguibile che soddisfa le specifiche (alcuni plugin di cui parleremo di seguito).
Assegnazione di subnet ai nodi per l'assegnazione degli indirizzi IP ai pod.
Poiché ogni pod di un cluster deve avere un indirizzo IP, è importante assicurarsi che questo indirizzo sia unico. Questo viene realizzato assegnando a ciascun nodo una subnet unica, da cui poi vengono assegnati indirizzi IP ai pod su quel nodo.
Controller IPAM del nodo
Quando nodeipam viene passato come parametro dell'opzione --controllers , esso assegna a ciascun nodo una subnet separata (podCIDR) dal CIDR del cluster (cioè l'intervallo di indirizzi IP per la rete del cluster). Poiché queste podCIDR non si sovrappongono, è possibile assegnare a ciascun pod un indirizzo IP unico.
Un nodo Kubernetes riceve un podCIDR al momento della sua registrazione iniziale nel cluster. Per modificare il podCIDR nei nodi, è necessario disregistrarli e poi registrarli nuovamente, apportando nel mentre le opportune modifiche alla configurazione del piano di controllo di Kubernetes. Per visualizzare il podCIDR di un nodo, è possibile utilizzare il seguente comando:
$ kubectl get no <nodeName> -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 del pod su un nodo comporta una serie di preparativi. In questa sezione mi concentrerò solo su quelli direttamente legati alla configurazione della rete del pod.
La pianificazione del pod su un nodo avvia la seguente sequenza di eventi:

Guida: .
Interazione tra l'ambiente di esecuzione dei contenitori e i plugin CNI
Ogni fornitore di rete ha il proprio plugin CNI. Il runtime del contenitore lo attiva per configurare la rete del pod durante il suo avvio. Nel caso di containerd, l'attivazione del plugin CNI è gestita dal plugin .
Ogni fornitore ha un proprio agente. Questo agente è installato su tutti i nodi di Kubernetes e si occupa della configurazione di rete dei pod. Questo agente viene fornito con il config CNI o crea autonomamente il file di configurazione sul nodo. La configurazione aiuta al plugin CRI a stabilire quale plugin CNI invocare.
La posizione del file di configurazione CNI è configurabile; per impostazione predefinita si trova in /etc/cni/net.d/<config-file>. Anche gli amministratori del cluster sono responsabili dell'installazione dei plugin CNI su ogni nodo del cluster. La loro posizione è anche configurabile; la directory predefinita è /opt/cni/bin.
Utilizzando containerd, puoi specificare i percorsi per la configurazione e i binari del plugin nella sezione [plugins."io.containerd.grpc.v1.cri".cni] in .
Poiché utilizziamo Flannel come provider di rete, parliamo un po' della sua configurazione:
- Flanneld (il demone di Flannel) viene generalmente installato nel cluster come DaemonSet con
install-cnicome . Install-cnicrea (/etc/cni/net.d/10-flannel.conflist) su ogni nodo.- Flanneld crea un dispositivo vxlan, estrae i metadati di rete dall'API server e tiene traccia degli aggiornamenti dei pod. Man mano che vengono creati, distribuisce le rotte per tutti i pod in tutto il cluster.
- Queste rotte consentono ai pod di comunicare tra loro tramite indirizzi IP.
Per ulteriori dettagli sul funzionamento di Flannel, ti consiglio di consultare i link alla fine dell'articolo.
Ecco uno schema di interazione tra il plugin Containerd CRI e i plugin CNI:

Come mostrato sopra, kubelet chiama il plugin Containerd CRI per creare un pod, il quale chiama il plugin CNI per configurare la rete del pod. Durante questo processo, il plugin CNI del provider di rete chiama altri plugin CNI di base per impostare vari aspetti della rete.
Interazione tra i plugin CNI
Esistono diversi plugin CNI, il cui scopo è aiutare a configurare l'interazione di rete tra i container 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 lavora insieme a Flanneld. Durante l'avvio, Flanneld estrae podCIDR e altri dettagli di rete dal server API e li memorizza 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 richiamare il plugin CNI bridge.
Plugin CNI Bridge
Questo plugin viene richiamato 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", come specificato nella configurazione. Poi per ogni pod viene creata una coppia veth. Un'estremità viene collegata allo spazio di nomi di rete del container, l'altra entra nel bridge Linux nella rete dell'host. collegano tutti i contenitori dell'host a un bridge Linux nella rete dell'host.
Una volta completata la configurazione della coppia veth, il plugin Bridge chiama il plugin IPAM locale per l'host (host-local). 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 locale per l'host CNI
Il plugin 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 locale per l'host (IP Address Mgestione — gestione degli indirizzi IP restituisce un indirizzo IP per il contenitore dalla sottorete e conserva l'IP assegnato sull'host nella directory specificata nella sezione dataDir — /var/lib/cni/networks/<network-name=cni0>/<ip>. In questo file è presente l'ID del contenitore a cui è stato assegnato l'indirizzo IP.
Quando viene chiamato il plugin IPAM locale per l'host, restituisce i seguenti dati:
{
"ip4": {
"ip": "10.244.4.2",
"gateway": "10.244.4.3"
},
"dns": {}
}
Riepilogo
Il kube-controller-manager assegna a ciascun nodo un podCIDR. I pod di ogni nodo ricevono indirizzi IP dallo spazio indirizzi nel range podCIDR assegnato. 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. Inoltre, se si utilizza containerd, il plugin Containerd CRI chiama il plugin CNI specificato nella configurazione CNI per impostare la rete del pod. Di conseguenza, il pod riceve un indirizzo IP.
Ci è voluto un po' di tempo per comprendere tutte le complessità e le sfumature di tutte queste interazioni. Spero che l'esperienza acquisita possa aiutarti a capire meglio come funziona Kubernetes. Se commetto errori, ti prego di contattarmi a o all'indirizzo . Non esitare a contattarmi se vuoi discutere di aspetti di questo articolo o di qualsiasi altra cosa. Sarò felice di parlare con te!
Link
Contenitori e rete
Come funziona Flannel
CRI e CNI
P.S. dal traduttore
Leggete anche nel nostro blog:
- «»;
- «Guida illustrata alla rete in Kubernetes»: , ;
- «».
Fonte: habr.com
