Hur får en Kubernetes-pod en IP-adress?

Notera. transl.: Den här artikeln, skriven av en SRE-ingenjör från LinkedIn, går in i detalj om den inre magin i Kubernetes - närmare bestämt interaktionen mellan CRI, CNI och kube-apiserver - som händer när nästa pod måste tilldelas en IP-adress.

Ett av grundkraven Kubernetes nätverksmodell är att varje pod måste ha sin egen IP-adress och alla andra pod i klustret måste kunna kontakta den på den adressen. Det finns många "nätverksleverantörer" (Flannel, Calico, Canal, etc.) som hjälper till att implementera denna nätverksmodell.

När jag först började arbeta med Kubernetes var det inte helt klart för mig hur exakt pods får sina IP-adresser. Även med en förståelse för hur de enskilda komponenterna fungerade var det svårt att föreställa sig att de skulle fungera tillsammans. Till exempel visste jag vad CNI-plugins var till för, men jag hade ingen aning om exakt hur de hette. Därför bestämde jag mig för att skriva den här artikeln för att dela kunskap om de olika nätverkskomponenterna och hur de fungerar tillsammans i ett Kubernetes-kluster, vilket gör att varje pod kan få sin egen unika IP-adress.

Det finns olika sätt att organisera nätverk i Kubernetes, precis som det finns olika körtidsalternativ för behållare. Denna publikation kommer att använda Flanell att organisera ett nätverk i ett kluster och som en körbar miljö - Containerd. Jag utgår också från att du vet hur nätverkande mellan behållare fungerar, så jag ska bara beröra det kort, bara för sammanhanget.

Några grundläggande begrepp

Behållare och nätverket: en kort översikt

Det finns gott om utmärkta publikationer på Internet som förklarar hur containrar kommunicerar med varandra över nätverket. Därför kommer jag bara att ge en allmän översikt över de grundläggande koncepten och begränsa mig till ett tillvägagångssätt, vilket innebär att skapa en Linux-brygga och kapsla in paket. Detaljer utelämnas eftersom själva ämnet containernätverk förtjänar en separat artikel. Länkar till några särskilt insiktsfulla och pedagogiska publikationer kommer att tillhandahållas nedan.

Behållare på en värd

Ett sätt att organisera kommunikation via IP-adresser mellan behållare som körs på samma värd är att skapa en Linux-brygga. För detta ändamål skapas virtuella enheter i Kubernetes (och Docker) veth (virtuell ethernet). Ena änden av veth-enheten ansluter till containerns nätverksnamnområde, den andra till Linux-brygga på värdnätverket.

Alla containrar på samma värd har ena änden av veth ansluten till en brygga genom vilken de kan kommunicera med varandra via IP-adresser. Linux-bryggan har också en IP-adress och fungerar som en gateway för utgående trafik från poddarna som är avsedda för andra noder.

Hur får en Kubernetes-pod en IP-adress?

Behållare på olika värdar

Paketinkapsling är en metod som gör att behållare på olika noder kan kommunicera med varandra med hjälp av IP-adresser. På Flannel är tekniken ansvarig för denna möjlighet. vxlan, som "paketerar" originalpaketet till ett UDP-paket och sedan skickar det till sin destination.

I ett Kubernetes-kluster skapar Flannel en vxlan-enhet och uppdaterar rutttabellen på varje nod därefter. Varje paket som är avsett för en behållare på en annan värd passerar genom vxlan-enheten och är inkapslat i ett UDP-paket. Vid destinationen extraheras det kapslade paketet och vidarebefordras till önskad pod.

Hur får en Kubernetes-pod en IP-adress?
Obs: Detta är bara ett sätt att organisera nätverkskommunikation mellan behållare.

Vad är CRI?

CRI (Container Runtime Interface) är en plugin som tillåter kubelet att använda olika containerruntime-miljöer. CRI API är inbyggt i olika körtider, så användare kan välja vilken körtid de vill.

Vad är CNI?

Projekt CNI är en Specifikation att organisera en universell nätverkslösning för Linux-containrar. Dessutom ingår plugins, ansvarig för olika funktioner när man sätter upp ett podnätverk. CNI-plugin är en körbar fil som överensstämmer med specifikationen (vi kommer att diskutera några plugins nedan).

Tilldelning av subnät till noder för att tilldela IP-adresser till pods

Eftersom varje pod i ett kluster måste ha en IP-adress är det viktigt att se till att denna adress är unik. Detta uppnås genom att tilldela varje nod ett unikt subnät, från vilket poddarna på den noden sedan tilldelas IP-adresser.

Nod IPAM Controller

När nodeipam skickas som en flaggparameter --controllers kube-controller-hanterare, allokerar den ett separat subnät (podCIDR) till varje nod från kluster-CIDR (dvs. intervallet av IP-adresser för klusternätverket). Eftersom dessa podCIDR:er inte överlappar varandra, blir det möjligt för varje pod att tilldelas en unik IP-adress.

En Kubernetes-nod tilldelas en podCIDR när den initialt registreras i klustret. För att ändra podCIDR för noder måste du avregistrera dem och sedan omregistrera dem och göra lämpliga ändringar i Kubernetes kontrolllagerkonfiguration däremellan. Du kan visa podCIDR för en nod med följande kommando:

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

Kubelet, container runtime och CNI-plugins: hur det hela fungerar

Att schemalägga en pod per nod innebär många förberedande steg. I det här avsnittet kommer jag bara att fokusera på de som är direkt relaterade till att sätta upp ett podnätverk.

Att schemalägga en pod till en viss nod utlöser följande händelsekedja:

Hur får en Kubernetes-pod en IP-adress?

Hjälp: Arkitektur för Containerd CRI-plugins.

Interaktion mellan containerruntime och CNI-plugins

Varje nätverksleverantör har sin egen CNI-plugin. Behållarens körtid kör den för att konfigurera nätverket för podden när den startar. När det gäller containerd, startas CNI-pluginen av plugin Containerd CRI.

Dessutom har varje leverantör sin egen agent. Den är installerad på alla Kubernetes-noder och ansvarar för nätverkskonfigurationen av poddar. Denna agent ingår antingen i CNI-konfigurationen eller skapar den självständigt på noden. Konfigurationen hjälper CRI-pluginen att ställa in vilken CNI-plugin som ska anropas.

Platsen för CNI-konfigurationen kan anpassas; som standard är den i /etc/cni/net.d/<config-file>. Klusteradministratörer är också ansvariga för att installera CNI-plugins på varje klusternod. Deras plats är också anpassningsbar; standardkatalog - /opt/cni/bin.

När du använder containerd kan sökvägarna för plugin-konfigurationen och binärfilerna ställas in i sektionen [plugins.«io.containerd.grpc.v1.cri».cni] в containerd konfigurationsfil.

Eftersom vi använder Flannel som vår nätverksleverantör, låt oss prata lite om att ställa in det:

  • Flanneld (Flannels demon) installeras vanligtvis i ett kluster som en DaemonSet med install-cni som init behållare.
  • Install-cni skapar CNI-konfigurationsfil (/etc/cni/net.d/10-flannel.conflist) på varje nod.
  • Flanneld skapar en vxlan-enhet, hämtar nätverksmetadata från API-servern och övervakar poduppdateringar. När de skapas distribuerar den rutter till alla poddar i hela klustret.
  • Dessa rutter tillåter pods att kommunicera med varandra via IP-adresser.

För mer detaljerad information om Flannels arbete rekommenderar jag att du använder länkarna i slutet av artikeln.

Här är ett diagram över interaktionen mellan Containerd CRI-plugin och CNI-plugin:

Hur får en Kubernetes-pod en IP-adress?

Som du kan se ovan anropar kubelet Containerd CRI-plugin för att skapa podden, som sedan anropar CNI-plugin för att konfigurera poddens nätverk. Genom att göra det anropar nätverksleverantörens CNI-plugin andra kärn-CNI-plugins för att konfigurera olika aspekter av nätverket.

Interaktion mellan CNI-plugins

Det finns olika CNI-plugins vars jobb är att hjälpa till att sätta upp nätverkskommunikation mellan behållare på värden. Den här artikeln kommer att diskutera tre av dem.

CNI-plugin Flanell

När du använder Flannel som nätverksleverantör anropar Containerd CRI-komponenten CNI-plugin Flanellmed CNI-konfigurationsfilen /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
      }
    }
  ]
}

Flannel CNI-plugin fungerar tillsammans med Flannel. Under uppstart hämtar Flanneld podCIDR och andra nätverksrelaterade detaljer från API-servern och sparar dem i en fil /run/flannel/subnet.env.

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

Flannel CNI-pluginen använder data från /run/flannel/subnet.env för att konfigurera och anropa CNI bridge plugin.

CNI plugin Bridge

Denna plugin anropas med följande konfiguration:

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

När den anropas för första gången skapar den en Linux-brygga med «name»: «cni0», som anges i konfigurationen. Sedan skapas ett veth-par för varje pod. Ena änden av den är ansluten till containerns nätverksnamnområde, den andra ingår i Linux-bryggan på värdnätverket. CNI plugin Bridge ansluter alla värdbehållare till en Linux-brygga på värdnätverket.

Efter att ha ställt in veth-paret, anropar Bridge-plugin den värdlokala IPAM CNI-plugin. IPAM-plugintypen kan konfigureras i CNI-konfigurationen som CRI-pluginen använder för att anropa Flannel CNI-plugin.

Värdlokala IPAM CNI-plugins

Överbrygga CNI-anrop värdlokal IPAM-plugin CNI med följande konfiguration:

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

Värdlokal IPAM-plugin (IP Adress Management - IP-adresshantering) returnerar IP-adressen för behållaren från subnätet och lagrar den tilldelade IP-adressen på värden i den katalog som anges i avsnittet dataDir - /var/lib/cni/networks/<network-name=cni0>/<ip>. Den här filen innehåller ID:t för den behållare som denna IP-adress är tilldelad till.

När du anropar den värdlokala IPAM-pluginen returnerar den följande data:

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

Sammanfattning

Kube-controller-manager tilldelar en podCIDR till varje nod. Varje nods poddar tar emot IP-adresser från adressutrymmet i det tilldelade podCIDR-intervallet. Eftersom nodernas podCIDR inte överlappar varandra får alla pods unika IP-adresser.

Kubernetes-klusteradministratören konfigurerar och installerar kubelet, containerruntime, nätverksleverantörsagenten och kopierar CNI-insticksprogram till varje nod. Under uppstart genererar nätverksleverantörsagenten en CNI-konfiguration. När en pod är schemalagd till en nod, anropar kubelet CRI-plugin för att skapa den. Därefter, om containerd används, anropar Containerd CRI-plugin CNI-plugin som specificeras i CNI-konfigurationen för att konfigurera poddens nätverk. Som ett resultat får podden en IP-adress.

Det tog mig lite tid att förstå alla subtiliteter och nyanser i alla dessa interaktioner. Jag hoppas att den här upplevelsen hjälper dig att bättre förstå hur Kubernetes fungerar. Om jag har fel i något, vänligen kontakta mig på Twitter eller på adressen [e-postskyddad]. Hör gärna av dig om du vill diskutera aspekter av den här artikeln eller något annat. Jag vill gärna chatta med dig!

referenser

Containers och nätverk

Hur fungerar Flanell?

CRI och CNI

PS från översättaren

Läs även på vår blogg:

Källa: will.com

Lägg en kommentar