In che modo un pod Kubernetes ottiene un indirizzo IP?

Nota. trad.: Questo articolo, scritto da un ingegnere SRE di LinkedIn, descrive nel dettaglio la "magia interna" di Kubernetes, più specificamente l'interazione tra CRI, CNI e kube-apiserver, che si verifica quando è necessario assegnare un indirizzo IP a un pod.

Uno dei requisiti di base Modelli di rete Kubernetes è che ogni pod deve avere il proprio indirizzo IP e qualsiasi altro pod nel cluster deve essere in grado di contattarlo a questo indirizzo. Esistono molti "provider" di rete (Flannel, Calico, Canal, ecc.) che aiutano a implementare questo modello di rete.

Quando ho iniziato a lavorare con Kubernetes, non mi era del tutto chiaro come esattamente i pod ottenessero i loro indirizzi IP. Pur comprendendo il funzionamento dei singoli componenti, era difficile visualizzare come interagissero. Ad esempio, sapevo a cosa servissero i plugin CNI, ma non avevo idea di come si chiamassero esattamente. Così ho deciso di scrivere questo articolo per condividere le mie conoscenze sui vari componenti di rete e su come interagiscono in un cluster Kubernetes per assegnare a ciascun pod il suo indirizzo IP univoco.

Esistono diversi modi per gestire il networking in Kubernetes, così come esistono diversi runtime per i container. Questo post utilizzerà Flanella per organizzare una rete in un cluster e come ambiente eseguibile - contenitore. Presumo anche che tu sappia come funziona la rete tra container, quindi ne parlerò solo brevemente per contestualizzare.

Alcuni concetti di base

Contenitori e Web: una breve panoramica

Esistono numerose pubblicazioni online che spiegano come i container comunicano tra loro in rete. Pertanto, mi limiterò a fornire una panoramica generale dei concetti principali e a un approccio specifico, che prevede la creazione di un bridge Linux e l'incapsulamento dei pacchetti. Ometterò i dettagli, poiché l'argomento del networking dei container merita un articolo a parte. Di seguito troverete i link ad alcune pubblicazioni particolarmente informative e divulgative.

Contenitori su un singolo host

Un modo per organizzare la comunicazione tramite indirizzo IP tra container in esecuzione sullo stesso host prevede la creazione di un bridge Linux. A questo scopo, i dispositivi virtuali vengono creati in Kubernetes (e Docker). veth (ethernet virtuale)Un'estremità del dispositivo veth si connette allo spazio dei nomi di rete del contenitore, l'altra a Ponte Linux sulla rete host.

Tutti i container su un singolo host hanno un'estremità del veth collegata a un bridge, attraverso il quale possono comunicare tra loro tramite indirizzi IP. Anche il bridge Linux ha un indirizzo IP e funge da gateway per il traffico in uscita dai pod destinati ad altri nodi.

In che modo un pod Kubernetes ottiene un indirizzo IP?

Contenitori su host diversi

L'incapsulamento dei pacchetti è un modo in cui i container su nodi diversi possono comunicare tra loro tramite indirizzi IP. In Flannel, questa capacità è abilitata da una tecnologia chiamata vxlan, che "impacchetta" il pacchetto originale in un pacchetto UDP e poi lo invia alla sua destinazione.

In un cluster Kubernetes, Flannel crea un dispositivo vxlan e amplia 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. A destinazione, il pacchetto incapsulato viene estratto e inoltrato al pod corretto.

In che modo un pod Kubernetes ottiene un indirizzo IP?
Nota: questo è solo uno dei modi per organizzare la comunicazione di rete tra i container.

Che cosa è il CRI?

CRI (interfaccia di runtime del contenitore) — è un plugin che consente a kubelet di utilizzare diversi runtime di container. L'API CRI è integrata in vari runtime, quindi gli utenti possono scegliere quello che preferiscono.

Che cosa è il CNI?

Progetto CNI Rappresenta specifica per organizzare una soluzione di rete universale per i container Linux. Inoltre, include plugins, responsabile di varie funzioni durante la configurazione della rete di un pod. Un plugin CNI è un file eseguibile conforme alle specifiche (di seguito parleremo di alcuni plugin).

Assegnazione di subnet ai nodi per assegnare indirizzi IP ai pod

Poiché ogni pod in un cluster deve avere un indirizzo IP, è importante assicurarsi che questo indirizzo sia univoco. Questo si ottiene assegnando a ciascun nodo una subnet univoca, da cui vengono poi assegnati gli indirizzi IP ai pod su quel nodo.

Controllore del nodo IPAM

Quando nodeipam passato come parametro flag --controllers kube-controller-manager'а, assegna una subnet separata (podCIDR) dal CIDR del cluster (ovvero l'intervallo di indirizzi IP per la rete del cluster) a ciascun nodo. Poiché questi podCIDR non si sovrappongono, diventa possibile assegnare un indirizzo IP univoco a ciascun pod.

A un nodo Kubernetes viene assegnato un podCIDR quando viene inizialmente registrato nel cluster. Per modificare il podCIDR dei nodi, è necessario annullarne la registrazione e poi registrarli nuovamente, apportando nel frattempo le modifiche appropriate alla configurazione del piano di controllo Kubernetes. È possibile visualizzare il podCIDR di un nodo utilizzando il seguente comando:

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

Kubelet, Container Runtime e plugin CNI: come funzionano

La pianificazione di un pod su un nodo richiede molta preparazione. In questa sezione, mi concentrerò solo sui passaggi direttamente correlati alla configurazione della rete del pod.

La pianificazione di un pod su un nodo innesca la seguente catena di eventi:

In che modo un pod Kubernetes ottiene un indirizzo IP?

Informazioni: Architettura dei plugin CRI di Containerd.

Interazione tra il runtime del contenitore e i plugin CNI

Ogni provider di rete ha il proprio plugin CNI. Il runtime del container lo avvia per configurare la rete per il pod all'avvio. Nel caso di containerd, il plugin CNI viene avviato da CRI in contenitore.

Ogni provider ha il proprio agente. È installato su tutti i nodi Kubernetes ed è responsabile della configurazione di rete dei pod. Questo agente viene fornito con la configurazione CNI o la crea direttamente sul nodo. La configurazione aiuta il plugin CRI a determinare 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 dell'installazione dei plugin CNI su ciascun nodo del cluster. Anche la loro posizione è configurabile; la directory predefinita è /opt/cni/bin.

Quando si utilizza containerd, i percorsi per la configurazione del plugin e i binari possono essere specificati nella sezione [plugins.«io.containerd.grpc.v1.cri».cni] в file di configurazione containerd.

Poiché utilizziamo Flannel come provider di rete, parliamo un po' di come configurarlo:

  • Flanneld (il demone di Flanneld) è in genere installato in un cluster come DaemonSet con install-cni come contenitore di inizializzazione.
  • Install-cni crea File di configurazione CNI (/etc/cni/net.d/10-flannel.conflist) su ogni nodo.
  • Flanneld crea il dispositivo vxlan, recupera i metadati di rete dal server API e monitora gli aggiornamenti dei pod. Man mano che vengono creati, propaga le rotte a tutti i pod del cluster.
  • Questi percorsi consentono ai pod di comunicare tra loro tramite indirizzi IP.

Per informazioni più dettagliate sul funzionamento di Flannel, consiglio di utilizzare i link alla fine dell'articolo.

Ecco un diagramma dell'interazione tra il plugin Containerd CRI e i plugin CNI:

In che modo un pod Kubernetes ottiene un indirizzo IP?

Come potete vedere sopra, il kubelet richiama il plugin CRI di Containerd per creare un pod, che a sua volta richiama il plugin CNI per configurare la rete del pod. Il plugin CNI del provider di rete richiama quindi altri plugin CNI sottostanti per configurare vari aspetti della rete.

Interazione tra i plugin CNI

Esistono diversi plugin CNI progettati per aiutare a configurare la rete tra container su un host. Questo articolo ne tratterà tre.

Plugin CNI Flannel

Quando si utilizza Flannel come provider di rete, il componente CRI di Containerd chiama Plugin CNI Flannel, 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 Flannel CNI funziona in combinazione con Flanneld. All'avvio, Flanneld recupera il podCIDR e altri dettagli relativi alla 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 Flannel CNI utilizza i dati da /run/flannel/subnet.env per configurare e chiamare il plugin bridge CNI.

CNI Plugin 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», specificato nella configurazione. Viene quindi creata una coppia veth per ogni pod. Un'estremità è connessa allo spazio dei nomi di rete del container, l'altra è inclusa nel bridge Linux nella rete host. CNI Plugin Bridge collega tutti i contenitori host a un bridge Linux sulla rete host.

Una volta configurata la coppia veth, il plugin Bridge richiama il plugin IPAM CNI host-locale. Il tipo di plugin IPAM può essere configurato nella configurazione CNI, che il plugin CRI utilizza per richiamare il plugin Flannel CNI.

Plugin IPAM CNI host-local

Chiamate CNI Bridge plugin IPAM host-local CNI con la seguente configurazione:

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

Plugin IPAM host-locale (IP Andirizzo Mgestione - gestione degli indirizzi IP) restituisce l'indirizzo IP per il contenitore dalla subnet e memorizza l'IP assegnato 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 è assegnato questo indirizzo IP.

Quando viene chiamato il plugin IPAM host-local, vengono restituiti i seguenti dati:

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

Riassunto

Kube-controller-manager assegna un podCIDR a ciascun nodo. I pod di ciascun nodo ricevono indirizzi IP dallo spazio degli indirizzi nell'intervallo podCIDR assegnato. Poiché i podCIDR dei nodi non si sovrappongono, tutti i pod ricevono indirizzi IP univoci.

L'amministratore del cluster Kubernetes configura e installa il kubelet, il runtime del container, l'agente del provider di rete e copia i plugin CNI su ciascun nodo. Durante l'avvio, l'agente del provider di rete genera una configurazione CNI. Quando un pod viene pianificato per un nodo, il kubelet chiama il plugin CRI per crearlo. Quindi, se si utilizza containerd, il plugin CRI di Containerd chiama il plugin CNI specificato nella configurazione CNI per configurare la rete del pod. Ciò fa sì che il pod riceva un indirizzo IP.

Mi ci è voluto un po' di tempo per comprendere tutte le complessità e le sfumature di tutte queste interazioni. Spero che questa esperienza vi aiuti a capire meglio come funziona Kubernetes. Se sbaglio qualcosa, contattatemi a Twitter o per indirizzo hello@ronaknathani.comNon esitate a contattarmi se desiderate discutere di aspetti di questo articolo o di qualsiasi altra cosa. Sarò felice di chiacchierare con voi!

riferimenti

Contenitori e rete

Come funziona la flanella

CRI e CNI

PS da traduttore

Leggi anche sul nostro blog:

Fonte: habr.com