Wie ein Pod in Kubernetes eine IP-Adresse erhält

Hinweis.: Dieser Artikel, verfasst von einem SRE-Ingenieur aus LinkedIn, erläutert detailliert die „interne Magie“ in Kubernetes – genauer gesagt, das Zusammenspiel von CRI, CNI und kube-apiserver – was passiert, wenn ein neuer Pod eine IP-Adresse zugewiesen bekommen muss.

Eine der grundlegenden Anforderungen des Netzwerkmodells von Kubernetes besteht darin, dass jeder Pod seine eigene IP-Adresse haben muss und jeder andere Pod im Cluster in der Lage sein sollte, über diese Adresse mit ihm zu kommunizieren. Es gibt viele Netzwerk-„Provider“ (Flannel, Calico, Canal usw.), die helfen, dieses Netzwerkmodell zu implementieren.

Als ich anfing, mit Kubernetes zu arbeiten, war mir nicht ganz klar, wie Pods genau ihre IP-Adressen erhalten. Selbst mit dem Verständnis, wie die einzelnen Komponenten funktionieren, war es schwierig, ihre Zusammenarbeit vorzustellen. Zum Beispiel wusste ich, wozu CNI-Plugins benötigt werden, aber ich konnte mir nicht vorstellen, wie sie genau aufgerufen werden. Daher beschloss ich, diesen Artikel zu schreiben, um mein Wissen über die verschiedenen Netzwerkkomponenten und ihre Zusammenarbeit im Kubernetes-Cluster zu teilen, die es jedem Pod ermöglichen, seine eigene einzigartige IP-Adresse zu erhalten.

Es gibt verschiedene Möglichkeiten, die Netzwerkkommunikation in Kubernetes zu organisieren – ähnlich wie es verschiedene Optionen für die Ausführungsumgebungen (runtime) für Container gibt. In diesem Beitrag wird verwendet Flannel. um das Netzwerk im Cluster zu organisieren, während als Ausführungsumgebung – Containerd. Zudem gehe ich davon aus, dass Sie wissen, wie die Netzwerkkommunikation zwischen Containern funktioniert, daher werde ich nur kurz darauf eingehen, ausschließlich für den Kontext.

Einige grundlegende Konzepte

Container und Netzwerk: eine kurze Übersicht

Im Internet gibt es viele ausgezeichnete Publikationen, die erklären, wie Container miteinander vernetzt sind. Daher werde ich nur einen allgemeinen Überblick über die grundlegenden Konzepte geben und mich auf einen Ansatz konzentrieren, der die Erstellung eines Linux-Bridge und die Kapselung von Paketen beinhaltet. Einzelheiten werden weggelassen, da das Thema der Netzwerkkommunikation zwischen Containern einen eigenen Artikel verdient. Weiter unten sind einige besonders gehaltvolle und erkenntnisreiche Publikationen verlinkt.

Container auf demselben Host

Eine Möglichkeit, die IP-Kommunikation zwischen Containern, die auf demselben Host arbeiten, zu organisieren, besteht darin, einen Linux-Brücke zu erstellen. Dazu werden in Kubernetes (und Docker) virtuelle Geräte veth (virtuelles Ethernet). Ein Ende des veth-Geräts wird mit dem Netzwerk-Namensraum des Containers verbunden, das andere Ende mit der Linux-Brücke im Netzwerk des Hosts.

Alle Container auf einem Host haben ein Ende des veth mit der Brücke verbunden, über die sie miteinander über IP-Adressen kommunizieren können. Die Linux-Brücke hat ebenfalls eine IP-Adresse und fungiert als Gateway für ausgehenden (egress) Datenverkehr aus Pods, der für andere Knoten bestimmt ist.

Wie ein Pod in Kubernetes eine IP-Adresse erhält

Container auf verschiedenen Hosts

Die Kapselung von Paketen ist eine der Methoden, die es Containern auf verschiedenen Knoten ermöglicht, über IP-Adressen miteinander zu kommunizieren. In Flannel wird diese Funktion durch die Technologie vxlanbereitgestellt, die das ursprüngliche Paket in ein UDP-Paket «verpackt» und dann an sein Ziel sendet.

Im Kubernetes-Cluster erstellt Flannel ein vxlan-Gerät und ergänzt entsprechend die Routing-Tabelle auf jedem der Knoten. Jedes Paket, das für einen Container auf einem anderen Host bestimmt ist, wird über das vxlan-Gerät geleitet und in ein UDP-Paket eingekapselt. Am Zielort wird das eingekapselte Paket extrahiert und an das entsprechende Pod weitergeleitet.

Wie ein Pod in Kubernetes eine IP-Adresse erhält
Hinweis: Dies ist nur eine von vielen Möglichkeiten zur Organisation der Netzwerkkommunikation zwischen Containern.

Was ist CRI?

CRI (Container Runtime Interface) ist ein Plugin, das es kubelet ermöglicht, verschiedene Container-Laufzeitumgebungen zu nutzen. Die API CRI ist in verschiedene Laufzeitumgebungen integriert, sodass Benutzer die Laufzeit nach ihren Wünschen wählen können.

Was ist CNI?

Das CNI-Projekt stellt dar die Spezifikation stellt eine universelle Netzwerk-Lösung für Linux-Container bereit. Darüber hinaus umfasst es Plugins, die für verschiedene Funktionen bei der Netzwerkkonfiguration des Pods verantwortlich sind. Ein CNI-Plugin ist eine ausführbare Datei, die der Spezifikation entspricht (einige Plugins werden wir weiter unten besprechen).

Zuweisung von Subnetzen an Knoten zur Vergabe von IP-Adressen an Pods

Da jeder Pod im Cluster eine IP-Adresse benötigt, ist es wichtig sicherzustellen, dass diese Adresse eindeutig ist. Dies wird erreicht, indem jedem Knoten ein einzigartiges Subnetz zugewiesen wird, aus dem dann den Pods auf diesem Knoten IP-Adressen zugeordnet werden.

IPAM-Controller des Knotens

Wenn nodeipam wird als Parameterflagge übergeben --controllers des kube-controller-managers, weist er jedem Knoten ein separates Subnetz (podCIDR) aus dem CIDR des Clusters (d.h. dem IP-Adressbereich für das Netzwerk des Clusters) zu. Da diese podCIDRs sich nicht überschneiden, ist es möglich, jedem Pod eine einzigartige IP-Adresse zuzuweisen.

Einem Kubernetes-Knoten wird podCIDR zum Zeitpunkt seiner initialen Registrierung im Cluster zugewiesen. Um podCIDR bei den Knoten zu ändern, müssen sie deregistriert und anschließend erneut registriert werden, wobei in der Zwischenzeit die entsprechenden Änderungen in der Konfiguration der Kubernetes-Managementschicht vorgenommen werden müssen. Den podCIDR eines Knotens kann man mit dem folgenden Befehl ausgeben:

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

Kubelet, die Container-Laufzeitumgebung und CNI-Plugins: wie das alles funktioniert

Die Planung eines Pods auf einem Node ist mit einer Reihe von vorbereitenden Maßnahmen verbunden. In diesem Abschnitt konzentriere ich mich nur auf die Aspekte, die direkt mit der Netzwerkkonfiguration des Pods zu tun haben.

Die Planung eines Pods auf einem bestimmten Node löst die folgende Kette von Ereignissen aus:

Wie ein Pod in Kubernetes eine IP-Adresse erhält

Hilfe: Architektur der CRI-Plugins für Containerd.

Interaktion der Containerlaufzeitumgebung mit CNI-Plugins

Jeder Netzwerkprovider hat sein eigenes CNI-Plugin. Die Containerlaufzeit ruft es auf, um das Netzwerk für den Pod während seiner Startphase zu konfigurieren. Im Falle von containerd wird der CNI-Plugin von dem Plugin Containerd CRI.

Jeder Provider hat jedoch seinen eigenen Agenten. Dieser wird auf allen Kubernetes-Nodes installiert und ist für die Netzwerkkonfiguration der Pods verantwortlich. Dieser Agent wird entweder zusammen mit dem CNI-Config geliefert oder erstellt ihn eigenständig auf dem Node. Die Konfiguration hilft dem CRI-Plugin zu bestimmen, welches CNI-Plugin aufgerufen werden soll.

Der Speicherort des CNI-Configs kann konfiguriert werden; standardmäßig befindet es sich in /etc/cni/net.d/<config-file>. Die Clusteradministratoren sind ebenfalls verantwortlich für die Installation der CNI-Plugins auf jedem Node des Clusters. Auch deren Speicherort ist konfigurierbar; das Standardverzeichnis ist /opt/cni/bin.

Bei der Verwendung von containerd können die Pfade für die Konfiguration und die Binärdateien des Plugins im Abschnitt angegeben werden [plugins.«io.containerd.grpc.v1.cri».cni] in in der Konfigurationsdatei von containerd.

Da wir Flannel als Netzwerkprovider verwenden, lassen Sie uns ein wenig über dessen Konfiguration sprechen:

  • Flanneld (der Daemon von Flannel) wird normalerweise als DaemonSet im Cluster installiert mit install-cni als Init-Container.
  • Install-cni erstellt eine CNI-Konfigurationsdatei (/etc/cni/net.d/10-flannel.conflist) auf jedem Knoten.
  • Flanneld erstellt ein vxlan-Gerät, extrahiert Netzwerkmetadata vom API-Server und verfolgt die Updates der Pods. Während sie erstellt werden, verteilt es Routen für alle Pods im gesamten Cluster.
  • Diese Routen ermöglichen es Pods, über IP-Adressen miteinander zu kommunizieren.

Für detailliertere Informationen zur Funktionsweise von Flannel empfehle ich, die Links am Ende des Artikels zu nutzen.

Hier ist ein Diagramm der Interaktion zwischen dem Containerd CRI-Plugin und den CNI-Plugins:

Wie ein Pod in Kubernetes eine IP-Adresse erhält

Wie oben zu sehen, ruft kubelet das Containerd CRI-Plugin auf, um einen Pod zu erstellen, und dieses wiederum ruft das CNI-Plugin zur Konfiguration des Pod-Netzwerks auf. Dabei ruft der CNI-Plugin des Netzwerkproviders andere zugrunde liegende CNI-Plugins auf, um verschiedene Aspekte des Netzwerks zu konfigurieren.

Interaktion zwischen den CNI-Plugins

Es gibt verschiedene CNI-Plugins, die darauf abzielen, die Netzwerkinteraktion zwischen Containern auf dem Host einzurichten. In diesem Artikel werden drei davon behandelt.

CNI-Plugin Flannel

Bei der Verwendung von Flannel als Netzwerkprovider wird das Containerd CRI-Komponente aufgerufen CNI-Plugin Flannel, indem die CNI-Konfigurationsdatei verwendet wird. /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
      }
    }
  ]
}

Das CNI-Plugin Flannel arbeitet zusammen mit Flanneld. Beim Start extrahiert Flanneld podCIDR und andere netzwerkbezogene Details vom API-Server und speichert sie in einer Datei. /run/flannel/subnet.env.

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

Das CNI-Plugin Flannel nutzt Daten aus /run/flannel/subnet.env um das CNI-Bridge-Plugin einzurichten und aufzurufen.

CNI-Plugin Bridge

Dieses Plugin wird mit folgender Konfiguration aufgerufen:

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

Beim ersten Aufruf wird ein Linux-Bridge mit "name": "cni0", das im Konfigurationsfile angegeben ist, erstellt. Dann wird für jedes Pod ein Paar veth erstellt. Ein Ende wird mit dem Netzwerk-Namespace des Containers verbunden, das andere Ende geht in die Linux-Bridge im Host-Netzwerk. CNI-Plugin Bridge verbindet alle Host-Container mit dem Linux-Bridge-Netzwerk.

Nachdem das Paar veth konfiguriert ist, ruft das Bridge-Plugin den lokalen CNI-Plugin IPAM (host-local) auf. Der Typ des IPAM-Plugins kann in der CNI-Konfiguration festgelegt werden, die das CRI-Plugin verwendet, um den Flannel-CNI-Plugin aufzurufen.

Lokale Host-IPAM-Plugins CNI

Das Bridge CNI ruft das host-lokale IPAM-Plugin CNI mit folgender Konfiguration auf:

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

Host-lokales IPAM-Plugin (IP AAdresse MManagement — Verwaltung von IP-Adressen) gibt die IP-Adresse für den Container aus dem Subnetz zurück und speichert die zugewiesene IP auf dem Host im Verzeichnis, das im Abschnitt dataDir/var/lib/cni/networks/<network-name=cni0>/<ip>angegeben ist. In dieser Datei befindet sich die ID des Containers, dem diese IP-Adresse zugewiesen wurde.

Beim Aufruf des host-lokalen IPAM-Plugins gibt es folgende Daten zurück:

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

Zusammenfassung

Der Kube-controller-manager weist jedem Knoten ein podCIDR zu. Pods jedes Knotens erhalten IP-Adressen aus dem Adressraum im zugewiesenen Bereich podCIDR. Da die podCIDRs der Knoten nicht überschneiden, erhalten alle Pods eindeutige IP-Adressen.

Der Kubernetes-Cluster-Administrator konfiguriert und installiert kubelet, die Container-Laufzeitumgebung, den Agenten für den Netzwerkprovider und kopiert CNI-Plugins auf jeden Knoten. Während des Starts generiert der Agent des Netzwerkproviders die CNI-Konfiguration. Wenn ein Pod auf einem Knoten geplant wird, ruft kubelet das CRI-Plugin zu dessen Erstellung auf. Wenn containerd verwendet wird, ruft das Containerd-CRI-Plugin das im CNI-Config angegebene CNI-Plugin auf, um das Netzwerk des Pods einzurichten. Infolgedessen erhält der Pod eine IP-Adresse.

Es hat eine Weile gedauert, bis ich alle Feinheiten und Nuancen dieser Interaktionen verstanden habe. Ich hoffe, dass die gesammelten Erfahrungen auch Ihnen helfen, besser zu verstehen, wie Kubernetes funktioniert. Wenn ich in irgendetwas falsch liege, kontaktieren Sie mich bitte unter Twitter oder unter der Adresse hello@ronaknathani.com. Zögern Sie nicht, mich zu kontaktieren, wenn Sie Aspekte dieses Artikels oder etwas anderes besprechen möchten. Ich freue mich darauf, mit Ihnen zu sprechen!

Links

Container und Netzwerk

Wie Flannel funktioniert

CRI und CNI

P.S. vom Übersetzer

Lesen Sie auch in unserem Blog:

Quelle: habr.com

Erwerben Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster