Architektonische Anwendungen für Kubernetes

Einführung

Das Entwerfen und Ausführen von Anwendungen mit Blick auf Skalierbarkeit, Portabilität und Robustheit kann eine Herausforderung sein, insbesondere wenn die Systemkomplexität zunimmt. Die Architektur einer Anwendung oder eines Systems hat erhebliche Auswirkungen darauf, wie sie ausgeführt werden muss, was sie von ihrer Umgebung erwartet und wie eng sie mit verwandten Komponenten verbunden ist. Das Befolgen bestimmter Muster während der Entwurfsphase und das Befolgen bestimmter Betriebspraktiken können dazu beitragen, einige der häufigsten Probleme zu beheben, mit denen Anwendungen bei der Ausführung in stark verteilten Umgebungen konfrontiert sind.

Während Software-Entwurfsmuster und Entwicklungsmethoden Anwendungen mit den richtigen Skalierungseigenschaften erzeugen können, beeinflussen die Infrastruktur und die Umgebung den Betrieb des bereitgestellten Systems. Technologien wieDocker undKubernetes helfen Teams, Software zu verpacken und dann auf Plattformen verteilter Computer zu verteilen, bereitzustellen und zu skalieren. Wenn Sie lernen, wie Sie die Leistung dieser Tools optimal nutzen können, können Sie Anwendungen flexibler, kontrollierter und reaktionsschneller verwalten.

In diesem Handbuch werden einige der Prinzipien und Muster erläutert, die Sie möglicherweise anwenden möchten, um die Skalierung und Verwaltung Ihrer Workloads auf Kubernetes zu unterstützen. Während Kubernetes viele Arten von Workloads ausführen kann, können die von Ihnen getroffenen Entscheidungen die Benutzerfreundlichkeit und die bei der Bereitstellung verfügbaren Möglichkeiten beeinträchtigen. Die Art und Weise, wie Sie Ihre Anwendungen entwerfen und erstellen, Ihre Dienste in Containern verpacken und das Lebenszyklusmanagement sowie das Verhalten in Kubernetes konfigurieren, kann Ihre Erfahrung beeinflussen.

Entwerfen für Anwendungsskalierbarkeit

Bei der Erstellung von Software wirken sich viele Anforderungen auf die Muster und die Architektur aus, die Sie verwenden. Bei Kubernetes ist einer der wichtigsten Faktoren die Fähigkeit zuscale horizontally, die Anzahl der identischen Kopien Ihrer Anwendung anzupassen, um die Last zu verteilen und die Verfügbarkeit zu erhöhen. Dies ist eine Alternative zuvertical scaling, bei der versucht wird, dieselben Faktoren durch Bereitstellung auf Computern mit mehr oder weniger Ressourcen zu manipulieren.

Insbesondere istmicroservices ein Software-Entwurfsmuster, das sich gut für skalierbare Bereitstellungen in Clustern eignet. Entwickler erstellen kleine, zusammensetzbare Anwendungen, die über gut definierte REST-APIs über das Netzwerk kommunizieren, anstatt über größere Verbundprogramme, die über interne Programmiermechanismen kommunizieren. Durch die Zerlegung monolithischer Anwendungen in einzelne Einzelkomponenten kann jede Funktion unabhängig voneinander skaliert werden. Ein Großteil der normalerweise auf Anwendungsebene vorhandenen Komplexität und Zusammensetzung wird in den Betriebsbereich übertragen, wo sie von Plattformen wie Kubernetes verwaltet werden kann.

Über bestimmte Softwaremuster hinaus werdencloud native-Anwendungen unter Berücksichtigung einiger zusätzlicher Überlegungen entwickelt. Native Cloud-Anwendungen sind Programme, die einem Muster der Microservices-Architektur mit integrierter Ausfallsicherheit, Beobachtbarkeit und Verwaltungsfunktionen folgen, um sich an die von Clusterplattformen in der Cloud bereitgestellte Umgebung anzupassen.

Cloud-native Anwendungen werden beispielsweise mit Integritätsberichtsmetriken erstellt, um der Plattform die Verwaltung von Lebenszyklusereignissen zu ermöglichen, wenn eine Instanz fehlerhaft wird. Sie erstellen robuste Telemetriedaten (und stellen sie für den Export zur Verfügung), um Bediener auf Probleme aufmerksam zu machen und fundierte Entscheidungen zu treffen. Anwendungen sind so konzipiert, dass sie regelmäßige Neustarts und Fehler, Änderungen der Back-End-Verfügbarkeit und hohe Auslastung verarbeiten können, ohne Daten zu beschädigen oder nicht mehr zu reagieren.

Folgende 12-Faktoren-Anwendungsphilosophie

Eine beliebte Methode, mit der Sie sich auf die Merkmale konzentrieren können, die beim Erstellen von Cloud-fähigen Webanwendungen am wichtigsten sind, ist die Philosophie vonTwelve-Factor App. Die Prinzipien wurden geschrieben, um Entwicklern und Betriebsteams zu helfen, die Kernqualitäten von Webdiensten zu verstehen, die für die Ausführung in der Cloud entwickelt wurden. Sie gelten sehr gut für Software, die in einer Clusterumgebung wie Kubernetes ausgeführt wird. Während monolithische Anwendungen von der Befolgung dieser Empfehlungen profitieren können, funktionieren Mikrodienstarchitekturen, die auf diesen Prinzipien basieren, besonders gut.

Eine kurze Zusammenfassung der zwölf Faktoren sind:

  1. Codebase: Verwalten Sie den gesamten Code in Versionskontrollsystemen (wie Git oder Mercurial). Die Codebasis gibt umfassend vor, was implementiert wird.

  2. Dependencies: Abhängigkeiten sollten vollständig und explizit von der Codebasis verwaltet werden, entweder verkauft (mit dem Code gespeichert) oder in einem Format, das von einem Paketmanager installiert werden kann.

  3. Config: Trennen Sie die Konfigurationsparameter von der Anwendung und definieren Sie sie in der Bereitstellungsumgebung, anstatt sie in die Anwendung selbst zu integrieren.

  4. Backing services: Lokale und Remote-Dienste werden beide als über das Netzwerk zugängliche Ressourcen abstrahiert, wobei die Verbindungsdetails in der Konfiguration festgelegt werden.

  5. Build, release, run: Die Erstellungsphase Ihrer Anwendung sollte vollständig von Ihren Anwendungsfreigabe- und Betriebsprozessen getrennt sein. In der Erstellungsphase wird ein Bereitstellungsartefakt aus dem Quellcode erstellt, in der Freigabephase werden das Artefakt und die Konfiguration kombiniert und in der Ausführungsphase wird die Freigabe ausgeführt.

  6. Processes: Anwendungen werden als Prozesse implementiert, die nicht auf dem lokalen Speichern des Status beruhen sollten. Der Status sollte an einen Sicherungsdienst ausgelagert werden, wie im vierten Faktor beschrieben.

  7. Port binding: Anwendungen sollten nativ an einen Port gebunden sein und auf Verbindungen warten. Routing und Request Forwarding sollten extern erfolgen.

  8. Concurrency: Anwendungen sollten sich auf die Skalierung durch das Prozessmodell verlassen. Das gleichzeitige Ausführen mehrerer Kopien einer Anwendung, möglicherweise auf mehreren Servern, ermöglicht die Skalierung, ohne dass der Anwendungscode angepasst werden muss.

  9. Disposability: Prozesse sollten in der Lage sein, schnell zu starten und ohne schwerwiegende Nebenwirkungen ordnungsgemäß zu stoppen.

  10. Dev/prod parity: Ihre Test-, Staging- und Produktionsumgebungen sollten genau übereinstimmen und synchron gehalten werden. Unterschiede zwischen Umgebungen können dazu führen, dass Inkompatibilitäten und nicht getestete Konfigurationen auftreten.

  11. Logs: Anwendungen sollten Protokolle auf die Standardausgabe streamen, damit externe Dienste entscheiden können, wie sie am besten behandelt werden.

  12. Admin processes: Einmalige Verwaltungsprozesse sollten für bestimmte Releases ausgeführt und mit dem Hauptprozesscode geliefert werden.

Indem Sie die Richtlinien der Zwölf Faktoren einhalten, können Sie Anwendungen mit einem Modell erstellen und ausführen, das zur Ausführungsumgebung von Kubernetes passt. Die zwölf Faktoren ermutigen Entwickler, sich auf die Hauptverantwortung ihrer Anwendung zu konzentrieren, die Betriebsbedingungen und Schnittstellen zwischen Komponenten zu berücksichtigen und Eingaben, Ausgaben und Standardfunktionen für das Prozessmanagement zu verwenden, um eine vorhersehbare Ausführung in Kubernetes zu gewährleisten.

Containerisierung von Anwendungskomponenten

Kubernetes verwendet Container, um isolierte, gepackte Anwendungen auf seinen Clusterknoten auszuführen. Um auf Kubernetes ausgeführt zu werden, müssen Ihre Anwendungen in einem oder mehreren Container-Images gekapselt und mit einer Container-Laufzeitumgebung wie Docker ausgeführt werden. Die Containerisierung Ihrer Komponenten ist zwar eine Voraussetzung für Kubernetes, hilft aber auch dabei, viele der Prinzipien der oben diskutierten Zwölf-Faktor-App-Methodik zu bekräftigen, was eine einfache Skalierung und Verwaltung ermöglicht.

Beispielsweise stellen Container eine Isolation zwischen der Anwendungsumgebung und dem externen Hostsystem bereit, unterstützen einen vernetzten, serviceorientierten Ansatz für die Kommunikation zwischen Anwendungen und nehmen die Konfiguration in der Regel über Umgebungsvariablen vor und legen Protokolle offen, die in Standardfehler und Standardausgabe geschrieben wurden. Die Container selbst fördern die prozessbasierte Parallelität und tragen zur Aufrechterhaltung der Entwicklungs- / Produktparität bei, indem sie unabhängig skalierbar sind und die Laufzeitumgebung des Prozesses bündeln. Diese Eigenschaften ermöglichen es, Ihre Anwendungen so zu packen, dass sie reibungslos auf Kubernetes laufen.

Richtlinien zur Optimierung von Containern

Die Flexibilität der Containertechnologie ermöglicht viele verschiedene Möglichkeiten, eine Anwendung zu kapseln. Einige Methoden funktionieren jedoch in einer Kubernetes-Umgebung besser als andere.

Die meisten Best Practices für die Container-Erstellung Ihrer Anwendungen beziehen sich auf die Image-Erstellung, bei der Sie definieren, wie Ihre Software innerhalb eines Containers eingerichtet und ausgeführt wird. Im Allgemeinen bietet es eine Reihe von Vorteilen, die Bildgrößen klein und zusammensetzbar zu halten. Größenoptimierte Images können die Zeit und die Ressourcen reduzieren, die zum Starten eines neuen Containers in einem Cluster erforderlich sind, indem der Platzbedarf verwaltet und vorhandene Ebenen zwischen den Image-Aktualisierungen wiederverwendet werden.

Ein guter erster Schritt beim Erstellen von Container-Images besteht darin, Ihre Erstellungsschritte vom endgültigen Image zu trennen, das in der Produktion ausgeführt wird. Das Erstellen von Software erfordert im Allgemeinen zusätzliche Tools, nimmt zusätzliche Zeit in Anspruch und erzeugt Artefakte, die je nach Umgebung von Container zu Container inkonsistent oder für die endgültige Laufzeitumgebung nicht erforderlich sind. Eine Möglichkeit, den Erstellungsprozess sauber von der Laufzeitumgebung zu trennen, ist die Verwendung vonDocker multi-stage builds. Mit mehrstufigen Build-Konfigurationen können Sie ein Basis-Image angeben, das während des Build-Prozesses verwendet werden soll, und ein anderes definieren, das zur Laufzeit verwendet werden soll. Auf diese Weise können Sie Software mit einem Image erstellen, auf dem alle Build-Tools installiert sind, und die resultierenden Artefakte in ein schlankes, optimiertes Image kopieren, das jedes Mal verwendet wird.

Wenn diese Art von Funktionalität verfügbar ist, ist es normalerweise eine gute Idee, Produktionsbilder auf einem minimalen übergeordneten Bild zu erstellen. Wenn Sie das Aufblähen in übergeordneten Ebenen im Distro-Stil wieubuntu:16.04 (einschließlich einer ziemlich vollständigen Ubuntu 16.04-Umgebung) vollständig vermeiden möchten, können Sie Ihre Bilder mitscratch erstellen - Dockers minimalster Basis Bild - als Elternteil. Die Basisschicht vonscratchbietet jedoch keinen Zugriff auf viele Kerntools und verstößt häufig gegen Annahmen über die Umgebung, die einige Software enthält. Als Alternative hat das Image vonAlpine Linuxalpinean Popularität gewonnen, da es eine solide, minimale Basisumgebung ist, die eine winzige, aber voll funktionsfähige Linux-Distribution bietet.

Für interpretierte Sprachen wie Python oder Ruby ändert sich das Paradigma leicht, da es keine Kompilierungsphase gibt und der Interpreter verfügbar sein muss, um den Code in der Produktion auszuführen. Da schlanke Bilder immer noch ideal sind, sind viele sprachspezifische, optimierte Bilder, die auf Alpine Linux basieren, aufDocker Hub verfügbar. Die Vorteile der Verwendung eines kleineren Images für interpretierte Sprachen ähneln denen für kompilierte Sprachen: Kubernetes kann alle erforderlichen Container-Images schnell auf neue Knoten ziehen, um mit der sinnvollen Arbeit zu beginnen.

Festlegung des Umfangs für Container und Hülsen

Während Ihre Anwendungen containerisiert sein müssen, um auf einem Kubernetes-Cluster ausgeführt zu werden, sindpods die kleinste Abstraktionseinheit, die Kubernetes direkt verwalten kann. Ein Pod ist ein Kubernetes-Objekt, das aus einem oder mehreren eng gekoppelten Containern besteht. Container in einem Pod teilen sich einen Lebenszyklus und werden zusammen als eine Einheit verwaltet. Beispielsweise werden die Container immer auf demselben Knoten geplant, gleichzeitig gestartet oder gestoppt und können Ressourcen wie Dateisysteme und IP-Speicher gemeinsam nutzen.

Zunächst kann es schwierig sein, den besten Weg zu finden, um Ihre Anwendungen in Container und Pods zu unterteilen. Daher ist es wichtig zu verstehen, wie Kubernetes mit diesen Komponenten umgeht und was jede Abstraktionsebene für Ihre Systeme bietet. Mit ein paar Überlegungen können Sie einige natürliche Punkte für die Verkapselung Ihrer Anwendung mit jeder dieser Abstraktionen identifizieren.

Eine Möglichkeit, einen effektiven Bereich für Ihre Container zu bestimmen, besteht darin, nach natürlichen Entwicklungsgrenzen zu suchen. Wenn Ihre Systeme mit einer Microservices-Architektur arbeiten, werden häufig gut konzipierte Container erstellt, um einzelne Funktionseinheiten darzustellen, die häufig in einer Vielzahl von Kontexten verwendet werden können. Diese Abstraktionsebene ermöglicht Ihrem Team, Änderungen an Container-Images freizugeben und diese neue Funktionalität dann in jeder Umgebung bereitzustellen, in der diese Images verwendet werden. Anwendungen können erstellt werden, indem einzelne Container zusammengestellt werden, die jeweils eine bestimmte Funktion erfüllen, jedoch möglicherweise nicht den gesamten Prozess alleine ausführen.

Im Gegensatz zu den oben genannten werden Pods normalerweise erstellt, indem Sie überlegen, welche Teile Ihres Systems am meisten von unabhängigenmanagementprofitieren können. Da Kubernetes Pods als kleinste Abstraktion für Benutzer verwendet, sind dies die primitivsten Einheiten, mit denen die Kubernetes-Tools und die API direkt interagieren und sie steuern können. Sie können Pods starten, stoppen und neu starten oder übergeordnete Objekte verwenden, die auf Pods basieren, um Funktionen für Replikation und Lebenszyklusverwaltung einzuführen. In Kubernetes können Sie die Container in einem Pod nicht unabhängig voneinander verwalten. Sie sollten daher keine Container gruppieren, die von einer separaten Verwaltung profitieren könnten.

Da sich viele Funktionen und Abstraktionen von Kubernetes direkt auf Pods beziehen, ist es sinnvoll, Elemente, die in einem einzigen Pod skaliert werden sollen, zu bündeln und diejenigen zu trennen, die unabhängig voneinander skaliert werden sollen. Wenn Sie beispielsweise Ihre Webserver von Ihren Anwendungsservern in verschiedenen Pods trennen, können Sie die einzelnen Ebenen nach Bedarf unabhängig voneinander skalieren. Das Bündeln eines Webservers und eines Datenbankadapters im selben Pod kann jedoch sinnvoll sein, wenn der Adapter wesentliche Funktionen bietet, die der Webserver für die ordnungsgemäße Funktion benötigt.

Verbesserung der Pod-Funktionalität durch Bündelung unterstützender Container

Welche Arten von Behältern sollten in einem einzigen Behälter gebündelt werden? Im Allgemeinen ist ein Primärcontainer für die Erfüllung der Kernfunktionen des Pods verantwortlich. Es können jedoch zusätzliche Container definiert werden, mit denen der Primärcontainer geändert oder erweitert oder eine Verbindung zu einer eindeutigen Bereitstellungsumgebung hergestellt werden kann.

Beispielsweise kann in einem Webserver-Pod ein Nginx-Container auf Anforderungen warten und Inhalte bereitstellen, während ein zugeordneter Container statische Dateien aktualisiert, wenn sich ein Repository ändert. Es mag verlockend sein, diese beiden Komponenten in einem einzigen Container zu verpacken, aber die Implementierung als separate Container bietet erhebliche Vorteile. Sowohl der Webserver-Container als auch der Repository-Puller können unabhängig voneinander in verschiedenen Kontexten verwendet werden. Sie können von verschiedenen Teams verwaltet und jeweils so entwickelt werden, dass ihr Verhalten für die Arbeit mit verschiedenen Companion-Containern verallgemeinert wird.

Brendan Burns und David Oppenheimer identifizierten in ihrem Papier drei Hauptmuster für die Bündelung von Stützbehältern aufdesign patterns for container-based distributed systems. Dies sind einige der häufigsten Anwendungsfälle für das Zusammenpacken von Behältern in einer Hülse:

  • Sidecar: In diesem Muster erweitert und erweitert der sekundäre Container die Kernfunktionalität des primären Containers. Bei diesem Muster werden nicht standardmäßige Funktionen oder Dienstprogramme in einem separaten Container ausgeführt. Beispielsweise kann ein Container, der Protokolle weiterleitet oder nach aktualisierten Konfigurationswerten sucht, die Funktionalität eines Pods erweitern, ohne seinen primären Fokus wesentlich zu ändern.

  • Ambassador: Das Botschaftermuster verwendet einen zusätzlichen Container, um entfernte Ressourcen für den Hauptcontainer zu abstrahieren. Der primäre Container stellt eine direkte Verbindung zum Ambassador-Container her, der wiederum eine Verbindung zu Pools potenziell komplexer externer Ressourcen herstellt und diese abstrahiert, z. B. zu einem verteilten Redis-Cluster. Der primäre Container muss die tatsächliche Bereitstellungsumgebung nicht kennen oder kennen, um eine Verbindung zu externen Diensten herzustellen.

  • Adaptor: Das Adaptermuster wird verwendet, um die Daten, Protokolle oder Schnittstellen des primären Containers so zu übersetzen, dass sie den von externen Parteien erwarteten Standards entsprechen. Adaptercontainer ermöglichen einen einheitlichen Zugriff auf zentrale Dienste, auch wenn die von ihnen bedienten Anwendungen möglicherweise nur inkompatible Schnittstellen unterstützen.

Konfiguration in ConfigMaps und Secrets extrahieren

Während die Anwendungskonfigurationcanin Container-Images eingebettet wird, ist es am besten, Ihre Komponenten zur Laufzeit konfigurierbar zu machen, um die Bereitstellung in mehreren Kontexten zu unterstützen und eine flexiblere Verwaltung zu ermöglichen. Zur Verwaltung der Laufzeitkonfigurationsparameter bietet Kubernetes zwei Objekte mit den NamenConfigMaps undSecrets an.

ConfigMaps sind ein Mechanismus zum Speichern von Daten, die zur Laufzeit Pods und anderen Objekten ausgesetzt werden können. In ConfigMaps gespeicherte Daten können als Umgebungsvariablen dargestellt oder als Dateien im Pod angehängt werden. Durch das Entwerfen Ihrer Anwendungen zum Lesen von diesen Speicherorten können Sie die Konfiguration zur Laufzeit mithilfe von ConfigMaps einfügen und das Verhalten Ihrer Komponenten ändern, ohne das Container-Image neu erstellen zu müssen.

Secrets sind ein ähnlicher Kubernetes-Objekttyp, der zum sicheren Speichern vertraulicher Daten und zum gezielten Zugreifen auf Pods und andere Komponenten nach Bedarf verwendet wird. Geheimnisse sind eine bequeme Möglichkeit, vertrauliches Material an Anwendungen weiterzuleiten, ohne es in Ihrer normalen Konfiguration an leicht zugänglichen Stellen als Klartext zu speichern. Funktionell funktionieren sie ähnlich wie ConfigMaps, sodass Anwendungen mithilfe derselben Mechanismen Daten aus ConfigMaps und Secrets verwenden können.

Mit ConfigMaps und Secrets können Sie vermeiden, dass die Konfiguration direkt in die Kubernetes-Objektdefinitionen eingefügt wird. Sie können den Konfigurationsschlüssel anstelle des Werts zuordnen, sodass Sie die Konfiguration im Handumdrehen aktualisieren können, indem Sie die ConfigMap oder das Secret ändern. Dies gibt Ihnen die Möglichkeit, das aktive Laufzeitverhalten von Pods und anderen Kubernetes-Objekten zu ändern, ohne die Kubernetes-Definitionen der Ressourcen zu ändern.

Bereitschafts- und Verfügbarkeitsprüfungen implementieren

Kubernetes bietet zahlreiche sofort einsatzbereite Funktionen zur Verwaltung der Lebenszyklen von Komponenten und zur Gewährleistung, dass Ihre Anwendungen immer funktionsfähig und verfügbar sind. Um diese Funktionen nutzen zu können, muss Kubernetes jedoch verstehen, wie der Zustand Ihrer Anwendung überwacht und interpretiert werden soll. Zu diesem Zweck können Sie mit Kubernetes die Sondenliveness undreadinessdefinieren.

Mithilfe von Liveness-Tests kann Kubernetes feststellen, ob eine Anwendung in einem Container aktiv ist und ausgeführt wird. Kubernetes kann in regelmäßigen Abständen Befehle im Container ausführen, um das grundlegende Anwendungsverhalten zu überprüfen, oder HTTP- oder TCP-Netzwerkanforderungen an einen bestimmten Speicherort senden, um festzustellen, ob der Prozess verfügbar ist und wie erwartet reagieren kann. Wenn eine Aktivitätsprüfung fehlschlägt, startet Kubernetes den Container neu, um zu versuchen, die Funktionalität innerhalb des Pods wiederherzustellen.

Bereitschaftstests sind ein ähnliches Tool, mit dem ermittelt wird, ob ein Pod für den Verkehr bereit ist. Anwendungen in einem Container müssen möglicherweise Initialisierungsprozeduren ausführen, bevor sie Clientanforderungen annehmen können, oder sie müssen möglicherweise neu geladen werden, wenn sie über eine neue Konfiguration benachrichtigt werden. Wenn ein Readiness-Test fehlschlägt, sendet Kubernetes vorübergehend keine Anforderungen mehr an den Pod, anstatt den Container neu zu starten. Auf diese Weise kann der Pod seine Initialisierungs- oder Wartungsroutinen abschließen, ohne den Zustand der gesamten Gruppe zu beeinträchtigen.

Durch die Kombination von Liveness- und Readiness-Tests können Sie Kubernetes anweisen, Pods automatisch neu zu starten oder sie aus Backend-Gruppen zu entfernen. Wenn Sie Ihre Infrastruktur so konfigurieren, dass diese Funktionen genutzt werden, kann Kubernetes die Verfügbarkeit und den Zustand Ihrer Anwendungen ohne zusätzlichen Arbeitsaufwand verwalten.

Verwenden von Bereitstellungen zum Verwalten von Umfang und Verfügbarkeit

Bei der Erörterung einiger Grundlagen des Pod-Designs haben wir bereits erwähnt, dass andere Kubernetes-Objekte auf diesen Grundelementen aufbauen, um erweiterte Funktionen bereitzustellen. Adeployment, ein solches zusammengesetztes Objekt, ist wahrscheinlich das am häufigsten definierte und manipulierte Kubernetes-Objekt.

Bereitstellungen sind zusammengesetzte Objekte, die auf anderen Kubernetes-Grundfunktionen aufbauen, um zusätzliche Funktionen hinzuzufügen. Sie fügen Zwischenobjekten mit der Bezeichnungreplicasets Funktionen zur Verwaltung des Lebenszyklus hinzu, z. B. die Möglichkeit, fortlaufende Aktualisierungen durchzuführen, auf frühere Versionen zurückzusetzen und zwischen Zuständen zu wechseln. Mit diesen Replikatsätzen können Sie Pod-Vorlagen definieren, um mehrere Kopien eines einzelnen Pod-Designs zu erstellen und zu verwalten. Auf diese Weise können Sie Ihre Infrastruktur einfach skalieren, die Verfügbarkeitsanforderungen verwalten und Pods bei einem Ausfall automatisch neu starten.

Diese zusätzlichen Funktionen bieten einen administrativen Rahmen und Selbstheilungsfunktionen für die relativ einfache Pod-Abstraktion. Während Pods die Einheiten sind, die letztendlich die von Ihnen definierten Workloads ausführen, sind sie nicht die Einheiten, die Sie normalerweise bereitstellen und verwalten sollten. Stellen Sie sich Pods stattdessen als einen Baustein vor, mit dem Anwendungen stabil ausgeführt werden können, wenn sie über übergeordnete Objekte wie Bereitstellungen bereitgestellt werden.

Erstellen von Diensten und Eingangsregeln zum Verwalten des Zugriffs auf Anwendungsebenen

Mithilfe von Bereitstellungen können Sie Gruppen austauschbarer Pods bereitstellen und verwalten, um Ihre Anwendungen zu skalieren und die Anforderungen der Benutzer zu erfüllen. Das Weiterleiten des Datenverkehrs an die bereitgestellten Pods ist jedoch ein gesondertes Problem. Wenn Pods im Rahmen von fortlaufenden Aktualisierungen ausgetauscht, neu gestartet oder aufgrund von Hostfehlern verschoben werden, ändern sich die zuvor mit der ausgeführten Gruppe verknüpften Netzwerkadressen. Mit Kubernetesservices können Sie diese Komplexität verwalten, indem Sie Routing-Informationen für dynamische Pools von Pods verwalten und den Zugriff auf verschiedene Ebenen Ihrer Infrastruktur steuern.

In Kubernetes sind Dienste spezifische Mechanismen, die steuern, wie der Datenverkehr an Pod-Gruppen weitergeleitet wird. Unabhängig davon, ob Sie Datenverkehr von externen Clients weiterleiten oder Verbindungen zwischen mehreren internen Komponenten verwalten, können Sie mithilfe von Diensten steuern, wie der Datenverkehr fließen soll. Kubernetes aktualisiert und verwaltet dann alle Informationen, die zum Weiterleiten von Verbindungen an die entsprechenden Pods erforderlich sind, auch wenn sich die Umgebung ändert und sich die Netzwerklandschaft ändert.

Intern auf Dienste zugreifen

Um Services effektiv nutzen zu können, müssen Sie zunächst die beabsichtigten Verbraucher für jede Gruppe von Pods ermitteln. Wenn Ihr Dienst nur von anderen Anwendungen verwendet wird, die in Ihrem Kubernetes-Cluster bereitgestellt werden, können Sie mit dem DiensttypclusterIPeine Verbindung zu einer Reihe von Pods herstellen, indem Sie eine stabile IP-Adresse verwenden, die nur innerhalb des Clusters routbar ist. Jedes auf dem Cluster bereitgestellte Objekt kann mit der Gruppe replizierter Pods kommunizieren, indem der Datenverkehr direkt an die IP-Adresse des Dienstes gesendet wird. Dies ist der einfachste Diensttyp, der für interne Anwendungsschichten gut geeignet ist.

Mit einem optionalen DNS-Addon können Kubernetes DNS-Namen für Dienste bereitstellen. Auf diese Weise können Pods und andere Objekte nicht über die IP-Adresse, sondern über den Namen mit den Diensten kommunizieren. Durch diesen Mechanismus wird die Dienstnutzung nicht wesentlich geändert, aber durch namensbasierte Bezeichner kann das Anschließen von Komponenten oder Definieren von Interaktionen vereinfacht werden, ohne dass die IP-Adresse des Dienstes im Voraus bekannt ist.

Bereitstellung von Diensten für den öffentlichen Verbrauch

Wenn die Schnittstelle öffentlich zugänglich sein soll, ist Ihre beste Option normalerweise der Diensttypload balancer. Hierbei wird die API Ihres spezifischen Cloud-Anbieters verwendet, um einen Lastenausgleich bereitzustellen, der den Datenverkehr zu den Service-Pods über eine öffentlich zugängliche IP-Adresse bereitstellt. Auf diese Weise können Sie externe Anforderungen an die Pods in Ihrem Dienst weiterleiten und Ihrem internen Clusternetzwerk einen kontrollierten Netzwerkkanal anbieten.

Da der Diensttyp Load Balancer einen Load Balancer für jeden Dienst erstellt, kann es möglicherweise teuer werden, Kubernetes-Dienste mit dieser Methode öffentlich zugänglich zu machen. Um dies zu vermeiden, können die Objekte von Kubernetesingressverwendet werden, um zu beschreiben, wie verschiedene Arten von Anforderungen basierend auf einem vorgegebenen Regelsatz an verschiedene Dienste weitergeleitet werden. Beispielsweise werden Anfragen für "example.com" möglicherweise an Service A weitergeleitet, während Anfragen für "sammytheshark.com" möglicherweise an Service B weitergeleitet werden. Ingress-Objekte bieten eine Möglichkeit zu beschreiben, wie ein gemischter Strom von Anforderungen basierend auf vordefinierten Mustern logisch an ihre Zieldienste weitergeleitet wird.

Eingangsregeln müssen durchingress controller interpretiert werden - normalerweise eine Art Lastausgleich wie Nginx -, der im Cluster als Pod bereitgestellt wird, der die Eingangsregeln implementiert und den Datenverkehr entsprechend an die Kubernetes-Dienste weiterleitet. Gegenwärtig befindet sich der Ingress-Objekttyp in der Beta-Phase, es gibt jedoch mehrere funktionierende Implementierungen, mit denen die Anzahl der externen Load Balancer minimiert werden kann, die Clusterbesitzer ausführen müssen.

Deklarative Syntax zum Verwalten des Kubernetes-Status verwenden

Kubernetes bietet eine große Flexibilität bei der Definition und Steuerung der für Ihren Cluster bereitgestellten Ressourcen. Mit Tools wiekubectl können Sie unbedingt Ad-hoc-Objekte definieren, die sofort in Ihrem Cluster bereitgestellt werden sollen. Während dies für die schnelle Bereitstellung von Ressourcen beim Erlernen von Kubernetes nützlich sein kann, weist dieser Ansatz Nachteile auf, die ihn für eine langfristige Produktionsadministration unerwünscht machen.

Eines der Hauptprobleme bei der zwingenden Verwaltung besteht darin, dass keine Aufzeichnungen über die Änderungen hinterlassen werden, die Sie in Ihrem Cluster implementiert haben. Dies macht es schwierig oder unmöglich, im Falle von Fehlern eine Wiederherstellung durchzuführen oder betriebliche Änderungen zu verfolgen, die auf Ihre Systeme angewendet werden.

Glücklicherweise bietet Kubernetes eine alternative deklarative Syntax, mit der Sie Ressourcen in Textdateien vollständig definieren und dannkubectl verwenden können, um die Konfiguration oder Änderung anzuwenden. Das Speichern dieser Konfigurationsdateien in einem Versionskontroll-Repository ist eine einfache Möglichkeit, Änderungen zu überwachen und in die Überprüfungsprozesse zu integrieren, die für andere Teile Ihrer Organisation verwendet werden. Die dateibasierte Verwaltung macht es auch einfach, vorhandene Muster an neue Ressourcen anzupassen, indem vorhandene Definitionen kopiert und bearbeitet werden. Durch das Speichern Ihrer Kubernetes-Objektdefinitionen in versionierten Verzeichnissen können Sie zu jedem Zeitpunkt eine Momentaufnahme des gewünschten Clusterstatus erstellen. Dies kann bei Wiederherstellungsvorgängen, Migrationen oder beim Aufspüren der Hauptursache unbeabsichtigter Änderungen, die an Ihrem System vorgenommen wurden, von unschätzbarem Wert sein.

Fazit

Die Verwaltung der Infrastruktur, in der Ihre Anwendungen ausgeführt werden, und das Erlernen, wie die Funktionen moderner Orchestrierungsumgebungen optimal genutzt werden können, können entmutigend sein. Viele der Vorteile, die Systeme wie Kubernetes und Technologien wie Container bieten, werden jedoch deutlicher, wenn Ihre Entwicklungs- und Betriebspraktiken an den Konzepten ausgerichtet sind, auf denen die Werkzeuge basieren. Die Systemarchitektur mit den Mustern von Kubernetes zeichnet sich dadurch aus, dass Sie verstehen, wie bestimmte Funktionen einige der mit hochkomplexen Bereitstellungen verbundenen Herausforderungen lindern können, um Ihre Erfahrung mit der Ausführung auf der Plattform zu verbessern.