Kubernetes Networks: Pods

Das Material, dessen Übersetzung wir heute veröffentlichen, ist den Merkmalen der Netzwerkinteraktion von Kubernetes-Herden gewidmet. Es ist für diejenigen gedacht, die bereits Erfahrung mit Kubernetes haben. Wenn Sie sich mit Kubernetes nicht sehr gut auskennen, lohnt es sich wahrscheinlich, dieses Kubernetes-Tutorial zu lesen, bevor Sie dieses Material lesen, in dem die Arbeit mit dieser Plattform für Anfänger in Betracht gezogen wird.



Pods


Was ist unter (pod) Kubernetes? Sub ist eine Entität, die aus einem oder mehreren Containern besteht, die auf demselben Host gehostet und für die gemeinsame Nutzung von Netzwerkstapelressourcen und anderen Ressourcen wie Volumes konfiguriert sind. Pods sind die Grundbausteine ​​für Anwendungen, die auf der Kubernetes-Plattform ausgeführt werden. Pods teilen sich einen Netzwerkstapel. In der Praxis bedeutet dies, dass alle Container, aus denen der Herd besteht, über localhost miteinander kommunizieren können. Wenn sich im Herd ein Container befindet, in dem Nginx auf Port 80 überwacht wird, und ein anderer Container, in dem Scrapyd ausgeführt wird, kann dieser Container unter http://localhost:80 auf den ersten Container zugreifen. Es sieht nicht so schwierig aus. Fragen wir uns nun, wie das tatsächlich funktioniert. Schauen wir uns eine typische Situation an, in der der Docker-Container auf dem lokalen Computer gestartet wird.


Docker-Container, der auf dem lokalen Computer ausgeführt wird

Wenn Sie dieses Schema von oben nach unten betrachten, stellt sich heraus, dass es eine physische Netzwerkschnittstelle eth0 . Die docker0 Bridge ist daran docker0 , und die virtuelle Netzwerkschnittstelle von docker0 ist veth0 der Bridge verbunden. Beachten Sie, dass sich die veth0 docker0 und veth0 im selben Netzwerk befinden. In diesem Beispiel ist dies 172.17.0.0/24 . In diesem Netzwerk wird der docker0 Schnittstelle die IP-Adresse 172.17.0.1 . Diese Schnittstelle ist das Standard-Gateway für die veth0 Schnittstelle, der die Adresse 172.17.0.2 zugewiesen ist. Aufgrund der Besonderheiten beim Einrichten von Netzwerk-Namespaces beim Starten des Containers sehen die Prozesse im Container nur die veth0 Schnittstelle und interagieren mit der Außenwelt über die docker0 und eth0 Schnittstellen. Führen Sie nun den zweiten Container aus.


Zwei Docker-Container, die auf dem lokalen Computer ausgeführt werden

Wie Sie im obigen Diagramm sehen können, wird die neue virtuelle Netzwerkschnittstelle veth1 dem zweiten Container zugewiesen, der mit derselben Bridge wie der erste Container verbunden ist - mit docker0 . Dies ist eine ziemlich präzise Beschreibung dessen, was tatsächlich passiert. Darüber hinaus ist zu beachten, dass die Verbindung zwischen dem Container und der Bridge dank eines Paares verbundener virtueller Ethernet-Schnittstellen hergestellt wird, von denen sich eine im Container-Namespace und die andere im Root-Netzwerk-Namespace befindet. Details dazu finden Sie hier .

All dies ist gut, aber es beschreibt noch nicht, was wir in Bezug auf Kubernetes-Pods als "Shared Network Stack" bezeichnen. Glücklicherweise sind Namespaces sehr flexibel. Docker kann einen Container starten und anstelle einer neuen virtuellen Netzwerkschnittstelle die vorhandene Schnittstelle zusammen mit anderen Containern verwenden. Bei diesem Ansatz müssen wir das obige Schema wie unten gezeigt ändern.


Container verwenden eine gemeinsame Netzwerkschnittstelle

Jetzt interagiert der zweite Container mit der bereits vorhandenen veth0 Schnittstelle und nicht wie im vorherigen Beispiel mit seiner eigenen veth1 Schnittstelle. Die Verwendung eines solchen Schemas führt zu mehreren Konsequenzen. Zunächst können wir nun sagen, dass beide Container extern unter derselben Adresse ( 172.17.0.2 sichtbar sind und in jedem von ihnen auf die Ports auf localhost zugreifen können, die von einem anderen Container geöffnet wurden. Dies bedeutet außerdem, dass diese Container nicht dieselben Ports öffnen können. Dies ist natürlich eine Einschränkung, unterscheidet sich jedoch nicht von einer ähnlichen Einschränkung in der Situation, in der mehrere Prozesse Ports auf demselben Host öffnen. Mit diesem Ansatz erhalten eine Reihe von Prozessen alle Vorteile, die mit der Ausführung dieser Prozesse in Containern verbunden sind, z. B. schlechte Konnektivität und Isolation. Gleichzeitig können Prozesse die Zusammenarbeit in der einfachsten vorhandenen Netzwerkumgebung organisieren.

Kubernetes implementiert dieses Muster, indem für jeden Herd ein spezieller Container erstellt wird, dessen einziger Zweck darin besteht, eine Netzwerkschnittstelle für andere Herdcontainer bereitzustellen. Wenn Sie eine Verbindung zu dem Knoten des Kubernetes-Clusters herstellen, dem von ssh ein bestimmtes Sub zugewiesen wurde, und den docker ps ausführen, wird mindestens ein Container mit dem Befehl pause ausgeführt. Dieser Befehl unterbricht den aktuellen Prozess, bis ein SIGTERM Signal eintrifft. Solche Container tun absolut nichts, sie befinden sich in einem "Schlaf" -Zustand und warten auf dieses Signal. Trotz der Tatsache, dass „suspendierte“ Container nichts bewirken, sind sie sozusagen das „Herz“ des Herdes und bieten anderen Containern eine virtuelle Netzwerkschnittstelle, über die sie miteinander oder mit der Außenwelt interagieren können. Infolgedessen stellt sich heraus, dass in einer hypothetischen Umgebung, die unter ähnelt, unser vorheriges Schema wie das unten gezeigte aussehen würde.


Hypothetische Container

Herd Netzwerk


Einer unter, voller Container, ist der Baustein eines bestimmten Systems, aber bisher nicht dieses System selbst. Die Kubernetes-Architektur basiert auf der Anforderung, dass Herde mit anderen Herden interagieren können müssen, unabhängig davon, ob sie auf demselben Computer oder auf verschiedenen Computern ausgeführt werden. Um zu erfahren, wie dies alles funktioniert, müssen wir auf eine höhere Abstraktionsebene gehen und darüber sprechen, wie Knoten im Kubernetes-Cluster funktionieren. Hier werden wir das Thema Netzwerkrouting und Routen behandeln. Dieses Thema wird in solchen Materialien häufig vermieden, da es zu komplex ist. Es ist nicht einfach, eine verständliche und nicht zu lange Anleitung zum IP-Routing zu finden. Wenn Sie sich jedoch einen kurzen Überblick über dieses Problem verschaffen möchten, können Sie sich dieses Material ansehen.

Der Kubernetes-Cluster besteht aus einem oder mehreren Knoten. Ein Knoten ist ein physisches oder virtuelles Hostsystem, das verschiedene Softwaretools und deren Abhängigkeiten (hauptsächlich Docker) sowie mehrere Kubernetes-Systemkomponenten enthält. Der Knoten ist mit dem Netzwerk verbunden, sodass er Daten mit anderen Knoten im Cluster austauschen kann. So könnte ein einfacher Cluster mit zwei Knoten aussehen.


Ein einfacher Cluster mit zwei Knoten

Wenn der betreffende Cluster in einer Cloud-Umgebung wie GCP oder AWS ausgeführt wird, vermittelt dieses Schema die Essenz der Standardnetzwerkarchitektur für einzelne Projekte ziemlich genau. Zu Demonstrationszwecken 10.100.0.0/24 in diesem Beispiel das private Netzwerk 10.100.0.0/24 verwendet. Infolgedessen 10.100.0.1 dem 10.100.0.1 die Adresse 10.100.0.1 zugewiesen, und die Adressen 10.100.0.2 und 10.100.0.3 zwei Knoten 10.100.0.3 . Mit dieser Architektur kann jeder der Knoten über seine eth0 Netzwerkschnittstelle miteinander eth0 . Erinnern wir uns jetzt daran, dass sich under, das auf dem Host ausgeführt wird, nicht in diesem privaten Netzwerk befindet. Es ist in einem völlig anderen Netzwerk mit der Brücke verbunden. Dies ist ein virtuelles Netzwerk, das nur innerhalb eines bestimmten Knotens existiert. Um es klarer zu machen, lassen Sie uns das vorherige Schema neu zeichnen und das hinzufügen, was wir oben als hypothetischen Herd bezeichnet haben.


Pods und Knoten

Der Host links in diesem Diagramm verfügt über eine eht0 Schnittstelle mit der Adresse 10.100.0.2 , deren Standard-Gateway der Router mit der Adresse 10.100.0.1 . Die docker0 Brücke mit der Adresse 172.17.0.1 mit dieser Schnittstelle verbunden, und über die virtuelle Schnittstelle veth0 mit der Adresse 172.17.0.2 ist mit ihr verbunden, was wir hier den Herd nennen. Die veth0 Schnittstelle wurde in einem angehaltenen Container erstellt. Es ist in allen drei Containern über einen gemeinsam genutzten Netzwerkstapel sichtbar. Aufgrund der Tatsache, dass beim Erstellen der Bridge lokale Routing-Regeln konfiguriert werden, wird jedes Paket, das bei eth0 und die Zieladresse 172.17.0.2 hat, an die Bridge umgeleitet, die es an die virtuelle Schnittstelle veth0 . Während das alles ziemlich anständig aussieht. Wenn bekannt ist, dass der von uns diskutierte Host die Adresse 172.17.0.2 , können wir den Router-Einstellungen eine Regel hinzufügen, die beschreibt, dass der nächste Übergang für diese Adresse 10.100.0.2 ist. veth0 sollten Pakete von dort an veth0 umgeleitet veth0 . Hervorragend. Schauen wir uns jetzt einen anderen Host an.

Der im Diagramm rechts gezeigte Host hat eine physikalische Schnittstelle eth0 mit der Adresse 10.100.0.3 . Es verwendet dasselbe Standard-Gateway - 10.100.0.1 - und ist erneut mit der docker0 Bridge mit der Adresse 172.17.0.1 . Es besteht das Gefühl, dass nicht alles so gut läuft. Diese Adresse kann tatsächlich von der auf dem Host auf der linken Seite verwendeten abweichen. Die Adressen der Bridges hier werden gleich gemacht, um das schlimmste Szenario zu demonstrieren, das beispielsweise auftreten kann, wenn Sie Docker gerade installiert haben und es nach Ihren Wünschen arbeiten lassen. Aber selbst wenn die fraglichen Netzwerke unterschiedlich sind, zeigt unser Beispiel ein tieferes Problem, nämlich dass Knoten normalerweise nichts darüber wissen, welche privaten Adressen Bridges zugewiesen sind, die sich an anderen Knoten befinden. Und wir müssen darüber Bescheid wissen - um Pakete an diese Bridges senden zu können und um sicher zu sein, dass sie dort ankommen, wo sie gebraucht werden. Offensichtlich benötigen wir hier eine Art Entität, die es uns ermöglicht, die korrekte Konfiguration von Adressen in verschiedenen Knoten sicherzustellen.

Die Kubernetes-Plattform bietet uns eine zweistufige Lösung für dieses Problem. Diese Plattform weist zunächst einen gemeinsamen Adressraum für Bridges in jedem Knoten zu und weist Bridges dann die Adressen in diesem Raum zu, basierend darauf, in welchem ​​Knoten sich die Bridge befindet. Zweitens fügt Kubernetes dem Gateway Routing-Regeln hinzu, das sich in unserem Fall um 10.100.0.1 . Diese Regeln definieren die Regeln für das Weiterleiten von Paketen, die für jede der Bridges bestimmt sind. Das heißt, sie beschreiben, über welche physikalische Schnittstelle eth0 mit jeder der Brücken kontaktiert werden kann. Diese Kombination aus virtuellen Netzwerkschnittstellen, Bridges und Routing-Regeln wird üblicherweise als Overlay-Netzwerk bezeichnet . Apropos Kubernetes, ich nenne dieses Netzwerk normalerweise ein "Herdnetzwerk", da es sich um ein Overlay-Netzwerk handelt, mit dem Pods an verschiedenen Knoten miteinander kommunizieren können. So sieht das vorherige Diagramm aus, nachdem die Kubernetes-Mechanismen zur Sache gekommen sind.


Herd Netzwerk

Es fällt sofort auf, dass die Brückennamen von docker0 in cbr0 . Kubernetes verwendet keine Standard-Docker-Bridges. Was wir cbr ist eine Abkürzung für "benutzerdefinierte Brücke", das heißt, wir sprechen über einige spezielle Brücken. Ich bin nicht bereit, eine vollständige Liste der Unterschiede zwischen dem Starten von Docker-Containern in Pods und dem Ausführen auf normalen Computern zu geben, aber wir sprechen hier von einem der wichtigen ähnlichen Unterschiede. Außerdem müssen Sie darauf achten, dass der in diesem Beispiel Bridges zugewiesene Adressraum 10.0.0.0/14 . Diese Adresse stammt aus einem unserer Staging-Cluster, die auf der Google Cloud-Plattform bereitgestellt werden. Das obige ist also ein sehr reales Beispiel für ein Herdnetzwerk. Ihrem Cluster kann ein völlig anderer Adressbereich zugewiesen werden. Leider gibt es derzeit keine Möglichkeit, Informationen über diese Adressen mit dem Dienstprogramm kubectl Wenn Sie jedoch beispielsweise GCP verwenden, können Sie einen Befehl wie gcloud container clusters describe <cluster> clusterIpv4Cidr Eigenschaft clusterIpv4Cidr .

Im Allgemeinen kann festgestellt werden, dass Sie normalerweise nicht über die Funktionsweise des Herdnetzwerks nachdenken müssen. Wenn ein Sub Daten mit einem anderen Herd austauscht, geschieht dies meistens über Kubernetes-Dienste. Dies ist ein bisschen ein softwaredefinierter Proxy. Die Netzwerkadressen der Herde werden jedoch in den Protokollen angezeigt. In einigen Situationen, insbesondere während des Debuggens, müssen Sie möglicherweise explizit Routing-Regeln in Herdnetzwerken festlegen. Beispielsweise wird Datenverkehr, bei dem Kubernetes an eine Adresse im Bereich 10.0.0.0/8 gebunden bleibt, standardmäßig nicht mit NAT verarbeitet. Wenn Sie mit Diensten interagieren, die sich in einem anderen privaten Netzwerk mit demselben Adressbereich befinden, müssen Sie möglicherweise Routing-Regeln konfigurieren, mit denen Sie die korrekte Paketzustellung organisieren können.

Zusammenfassung


Heute haben wir über Kubernetes Pods und die Funktionen ihrer Vernetzung gesprochen. Wir hoffen, dass dieses Material Ihnen hilft, die richtigen Schritte zur Implementierung komplexer Herdinteraktionsszenarien in Kubernetes-Netzwerken zu unternehmen.

Liebe Leser! Dieser Artikel ist der erste in einer Reihe von Kubernetes-Netzwerken. Der zweite Teil dieses Zyklus wurde bereits übersetzt . Wir überlegen, ob wir den dritten Teil übersetzen sollen. Wir bitten Sie, dies in den Kommentaren zu kommentieren.

Source: https://habr.com/ru/post/de441576/


All Articles