Hilfestellung für die Migration mit Mesh-Netzwerkerweiterung von Istio: Konzept

Dieser Artikel ist der erste Teil einer Reihe, in der die Verwendung eines Service Mesh erläutert wird, das dazu dient, eine Legacy-Umgebung Feature für Feature zu Google Kubernetes Engine (GKE) zu migrieren. Eine solche Umgebung könnte beispielsweise ein lokales Rechenzentrum sein, in dem Anwendungen auf virtuellen Maschinen ausgeführt werden.

Die Reihe setzt sich aus diesem konzeptionellen Artikel und der zugehörigen Anleitung zusammen. Im Artikel werden die Grundprinzipien und allgemeinen Schritte der Migration erläutert. Die Anleitung führt Sie durch ein Beispiel für eine Migration.

Einleitung

Dieser Artikel richtet sich an IT-Experten mit Verantwortung für eine komplexe Infrastruktur, die sukzessive migriert und modernisiert werden soll, wobei Folgendes zu minimieren ist:

  • Ausfallzeit
  • Refaktorierungsaufwand
  • Operative Komplexität des eigenen Netzwerks

Da die erläuterten Konzepte für jede beliebige Cloud gelten, wird hier angenommen, dass Sie mit Cloudtechnologien, Containern und Mikrodiensten vertraut sind.

Wie unter Hybrid- und Multi-Cloud-Muster und -Praktiken beschrieben, gibt es drei Hauptmuster für die Migration in die Cloud: Lift-and-Shift, Improve-and-Move und Rip-and-Replace. In diesem Artikel wird ein Improve-and-Move-Muster beschrieben, das auf die einzelnen Features der Anwendung angewendet wird statt in einem einzigen Arbeitsschritt auf die gesamte Anwendung.

Während der Migration hat die Anwendung eine Hybridarchitektur, bei der sich einige Features in Google Cloud und andere noch in der Legacy-Umgebung befinden. Nach abgeschlossener Migration wird die gesamte Anwendung in Google Cloud gehostet.

Terminologie

Anwendung
In diesem Artikel bezeichnet der Begriff Anwendung ein komplettes Softwaresystem mit vielen Features. Nutzer nehmen eine Anwendung als eine Einheit wahr. Beispielsweise ist eine Website, auf der Bücher verkauft werden, eine Anwendung.
Feature

Ein Feature ist eine Funktionseinheit einer Anwendung. Ein Beispiel ist das Buchrezensionsfeature einer Buchhandlungsanwendung. Features setzen sich aus Mikrodiensten zusammen.

Features können entweder zustandslos oder zustandsorientiert sein. Zustandslose Features sind von keinerlei Daten abhängig, während zustandsorientierte Features eine Datenabhängigkeit haben.

Mikrodienst

Ein Mikrodienst ist eine eigenständige Komponente, die für ein Anwendungsfeature entwickelt wurde. In diesem Artikel geht es um Anwendungen aus verschiedenen Mikrodiensten, die für Nutzer nicht zu unterscheiden sind. Beispielsweise ist eine Komponente, die Buchrezensionen verarbeitet, ein Mikrodienst.

Anwendungen, die in Form von Mikrodiensten entwickelt wurden, bestehen aus mehreren Mikrodiensten, die jeweils ein bestimmtes Ziel verfolgen. Zum Beispiel könnte ein Mikrodienst für Buchbewertungen zuständig sein und ein anderer für Buchrezensionen. Diese Mikrodienste sollten lose miteinander verknüpft sein und klar definierte APIs als Schnittstellen haben. Sie können in verschiedenen Sprachen und Frameworks geschrieben sein (wie in mehrsprachigen Anwendungen) und unterschiedliche Lebenszyklen haben.

Wenn Sie die Grenzen der einzelnen Mikrodienste genauer definieren möchten, können Sie sie mit folgenden Tools containerisieren:

Service Mesh

Ein Service Mesh ist eine Software, die verschiedene Dienste miteinander verknüpft und wichtige Netzwerkfeatures wie Diensterkennung, sichere Kommunikation, Load-Balancing, Trafficverwaltung, Monitoring und Sichtbarkeit bietet.

Bei einer typischen Service-Mesh-Implementierung wird jeder Dienst mit einem Proxy gekoppelt, der diese Features bereitstellt. Der Dienstproxy wird meist als Sidecar bezeichnet. Die Rolle des Sidecars besteht darin, die mit ihm verknüpfte Anwendung zu erweitern und zu verbessern, oft ohne Wissen der Anwendung.

Migration

Eine Migration ist ein Vorgang zum Verschieben von Features einer oder mehrerer Anwendungen, die in einer Legacy-Umgebung ausgeführt werden, in eine Zielumgebung wie etwa Google Cloud. Dieser Artikel bezieht sich auf folgende Arten der Migration:

  • Big-Bang-Migration: Sie migrieren alle Features einer Anwendung auf einmal.
  • Graduelle Feature-für-Feature-Migration: Sie migrieren jeweils nur ein Feature.
Compliance-Testsuite

Eine Compliance-Testsuite besteht aus einer Reihe von Tests, die Sie für eine Umgebung ausführen können. So lässt sich überprüfen, ob die Umgebung bestimmten Anforderungen genügt. Wenn die Umgebung validiert ist, erfüllt sie die Anforderungen. Beispielsweise lässt sich validieren, ob die Antwort auf eine Testanfrage korrekt ist oder die Abhängigkeiten der Anwendung installiert sind.

Sie können zuerst eine manuelle Validierung mit Tools für Monitoring, Tracing und Service-Mesh-Visualisierung ausführen. Später können Sie dann die Testsuite implementieren und diese im Laufe der Zeit weiterentwickeln:

  • Lasttest: Zum Weiterentwickeln der Testsuite können Sie automatisch Testtraffic an die Umgebung senden und die Ergebnisse auswerten.
  • Compliance-Testtool: Mithilfe eines speziellen Tools können Sie selbst eine Testsuite entwerfen und entwickeln.

Vorteile einer graduellen Migrationsstrategie

Eine Big-Bang-Migration ist ein schwieriges Unterfangen, da sich beim Migrieren einer oder mehrerer Anwendungen in nur einem Arbeitsgang verschiedene Herausforderungen und Risiken ergeben. Wenn Zeit und Budget knapp bemessen sind und Sie sich ganz auf eine Big-Bang-Migration konzentrieren, bleibt nicht viel Kapazität, um an neuen Anwendungsfeatures zu arbeiten.

Im Gegensatz dazu ist die Komplexität einer graduellen Feature-für-Feature-Migration insgesamt geringer, da die jeweils zu migrierende Arbeitslast kleiner ist: Ein einzelnes Feature ist im Vergleich zu einer kompletten Anwendung schlanker strukturiert. Bei einer graduellen Migration lässt sich das Risiko auf kleinere Migrationsereignisse verteilen, sodass es nicht auf einem einzigen risikobehafteten Vorgang lastet. Außerdem kann das Migrationsteam bei einer graduellen Migration mehrere Migrationsstrategien planen, entwerfen und entwickeln, um unterschiedlichen Arten von Features Rechnung zu tragen.

Im Artikel Von einer monolithischen Anwendung zu Mikrodiensten in Google Kubernetes Engine migrieren finden Sie Informationen dazu, welche Features zuerst migriert werden sollten und wie zustandsorientierte Features zu verschieben sind.

Vorteile eines Service Mesh

Ein Service Mesh entkoppelt Dienstfunktionen (d. h. die Implementierung der Geschäftslogik) von Netzwerkfunktionen (die regeln, wie und wann Traffic an Dienstfunktionen weiterzuleiten ist).

In der Legacy-Umgebung ist das Netzwerk an den meisten Dienstaufrufen nicht beteiligt, da diese auf einer monolithischen Plattform ausgeführt werden. Bei Mikrodienstarchitekturen erfolgt die Kommunikation zwischen Diensten über ein Netzwerk und die Dienste müssen mit diesem andersartigen Modell zurechtkommen. Ein Service Mesh übernimmt die Funktionen zur Verarbeitung der Netzwerkkommunikation, sodass Sie diese nicht in jeder Anwendung implementieren müssen. Außerdem reduziert ein Service Mesh die operative Komplexität des Netzwerks, da es Features für sichere Kommunikationskanäle, Load-Balancing, Trafficverwaltung, Monitoring und Sichtbarkeit bietet, die sofort verfügbar sind.

In der zugehörigen Anleitung verwenden Sie Istio als Service Mesh. Zu den Features von Istio gehören:

  • Trafficverwaltung: Detaillierte Steuerung des Traffics mit umfangreichen Routingregeln für HTTP-, gRPC-, WebSocket- und TCP-Traffic
  • Anforderung von Resilienzfeatures: Wiederholungsversuche, Failovers, Unterbrechungen der Netzwerkverbindung und Fehlerinjektion
  • Eine modulare Richtlinienschicht und Konfigurations-API, die Zugriffssteuerung und Ratenbegrenzung unterstützt
  • Automatische Messwerte, Logs und Traces für den gesamten Traffic innerhalb eines Clusters, einschließlich des ein- und ausgehenden Traffics des Clusters
  • Sichere Dienst-zu-Dienst-Kommunikation mit Authentifizierung und Autorisierung auf Basis von Dienstkonten
  • Unterstützung von Test- und Entwicklungsaufgaben wie A/B-Tests, Canary-Einführungen, Fehlerinjektion und Ratenbegrenzung

Sie können Ihr Service Mesh auch visualisieren. Durch die Einbindung von Tools wie Kiali in Istio sehen Sie, welche Dienste zu einem Service Mesh gehören und wie sie miteinander verbunden sind.

Der folgende Screenshot zeigt ein Beispiel für ein Kiali-Dienstdiagramm, das ein Istio-Mesh darstellt.

Diagramm: Kiali-Dienstdiagramm, das ein Istio-Mesh darstellt

Durch die Bereitstellung und Konfiguration eines Service Mesh können Sie Traffic entweder an die Legacy-Umgebung oder die Zielumgebung dynamisch weiterleiten. Sie brauchen die Konfiguration der Anwendung für Ihre Migration nicht zu ändern, da die Dienste im Mesh von der Trafficverwaltung unberührt bleiben.

Obwohl sich dieser Ansatz für zustandslose Features gut eignet, erfordert die Migration von Features, die zustandsorientiert, latenzempfindlich oder mit anderen Features stark gekoppelt sind, zusätzliche Planung und Refaktorierung:

  • Zustandsorientiert: Bei der Migration von zustandsorientierten Features müssen Sie auch Daten migrieren, um während der Migration Ausfallzeiten zu minimieren und Synchronisierungs- und Integritätsprobleme zu vermeiden. Weitere Informationen zu Datenmigrationsstrategien finden Sie im Artikel Von einer monolithischen Anwendung zu Mikrodiensten in Google Kubernetes Engine migrieren.
  • Latenzempfindlich: Wenn ein Feature bei der Kommunikation mit anderen Features latenzempfindlich ist, müssen Sie während des Migrationsprozesses unter Umständen zusätzliche Komponenten bereitstellen. Zur Verringerung dieser Empfindlichkeit werden häufig Proxys verwendet, die Daten vorab abrufen oder Ebenen im Cache speichern können.
  • Stark mit anderen Features gekoppelt: Wenn zwei oder mehr Features stark miteinander gekoppelt sind, müssen Sie sie möglicherweise gleichzeitig migrieren. Dieser Ansatz ist zwar einfacher als die Migration einer ganzen Anwendung, eventuell aber schwieriger als die Migration eines einzelnen Features.

Migrationsplan

In diesem Abschnitt wird ein Plan für die graduelle Feature-für-Feature-Migration mithilfe eines Service Mesh vorgestellt. Der Plan setzt sich aus folgenden Phasen zusammen:

  1. Legacy-Umgebung bewerten
  2. Grundlage in der Zielumgebung schaffen
  3. Dienste in der Zielumgebung bereitstellen und mit dem Routing von Traffic an die Zielumgebung beginnen
  4. Routing von Traffic an die Legacy-Umgebung stoppen
  5. Legacy-Umgebung deaktivieren

Legacy-Umgebung bewerten

Bevor Sie den Entwurf oder die Implementierung der Migration angehen, bewerten Sie die Legacy-Umgebung. Dabei sammeln Sie Informationen und legen eine Reihe von Anforderungen für die Zielumgebung sowie eine Grundlage für Test- und Validierungsvorgänge fest. Zuerst erstellen Sie einen Katalog mit allen zu migrierenden Anwendungsfeatures. Für jedes Feature sollten Sie die Fragen in der folgenden (nicht abschließenden) Liste beantworten können:

  • Welche Anforderungen werden an die Laufzeitumgebung und Leistung gestellt?
  • Gibt es Abhängigkeiten von anderen Features?
  • Ist dieses Feature geschäftskritisch?
  • Ist dieses Feature zustandslos oder zustandsorientiert?
  • Wie groß ist der voraussichtliche Refaktorierungsaufwand für dessen Migration?
  • Ist ein Umstellungsfenster für dieses Feature tragbar?

Lesen Sie bei Bedarf weitere Informationen über den Bewertungsprozess und die zu migrierenden Features. Führen Sie dann die Compliance-Testsuite für die Legacy-Umgebung aus, um einen Vergleichswert zu haben. Anschließend führen Sie die Suite auch für die Zielumgebung aus, und zwar während und nach der Migration.

Zur Validierung während der Migration sollte der Schwerpunkt Ihrer Testsuite auf folgenden Aspekten liegen:

  • Bereitstellung: Stellen Sie die nötigen Ressourcen für Ihre Umgebung bereit, bevor Sie sie konfigurieren.
  • Konfiguration: Nachdem Sie Ressourcen in der Umgebung bereitgestellt haben, konfigurieren Sie sie entsprechend den Anforderungen Ihrer Anwendung. Mit einer Konfigurations-Testsuite können Sie gewährleisten, dass die Umgebung zum Hosten Ihrer Anwendung bereit ist.
  • Geschäftslogik: Überprüfen Sie nach dem Validieren der Bereitstellung und der Umgebungskonfiguration die Geschäftslogik Ihrer Anwendung. Beispielsweise können Sie die Antworten auf Anfragen validieren.

InSpec, RSpec und Serverspec sind Tools zum Entwickeln automatisierter Compliance-Testsuiten. Sie sind plattformunabhängig und erweiterbar, sodass Sie die integrierten Kontrollen um Ihre eigenen ergänzen können.

Das folgende Diagramm zeigt ein Beispiel für eine Legacy-Umgebung:

Diagramm: Legacy-Umgebung

Zielumgebung bereitstellen

Nachdem Sie jetzt genügend Informationen über die Umgebungen und die zu migrierenden Anwendungen haben, können Sie die Zielumgebung gemäß den Anforderungen bereitstellen, die Sie während der Bewertung festgelegt haben.

In dieser Phase lässt sich die Zielumgebung mithilfe der Compliance-Testsuite validieren. Möglicherweise müssen Sie die Testsuite aktualisieren, um eventuelle Unterschiede zwischen der Legacy- und der Zielumgebung wie Hardware und Netzwerktopologie zu berücksichtigen. Bedenken Sie, dass die Umstellung von einer lokalen Umgebung, in der Sie die volle Kontrolle haben, auf eine öffentliche Cloudumgebung erfolgt, in der Sie normalerweise keinen Vollzugriff auf den gesamten Stack haben.

Da Sie eine neue Umgebung bereitstellen, empfiehlt es sich, nach einer Infrastruktur-als-Code-Methode vorzugehen. Damit machen Sie Ihre Infrastruktur prüfbar, wiederholbar und automatisch bereitstellbar.

Das folgende Diagramm zeigt die Legacy-Umgebung und die neu bereitgestellte – noch leere – Zielumgebung.

Diagramm: Legacy-Umgebung und (leere) Zielumgebung

Service Mesh konfigurieren

Als Nächstes richten Sie ein Service Mesh ein, das die Legacy- und die Zielumgebung umfasst. Das Service Mesh sorgt für die Verbindung der verschiedenen Mikrodienste, die in der Legacy-Umgebung ausgeführt werden und in die Zielumgebung zu migrieren sind. Das Service Mesh ist in dieser Phase leer und wartet auf die Registrierung der Dienste. Es empfängt noch keinen Produktionstraffic.

Das folgende Diagramm zeigt die Legacy-Umgebung und das leere Service Mesh in der Zielumgebung.

Diagramm: Legacy-Umgebung und leeres Service Mesh

Dienste aus der Legacy-Umgebung in das Mesh aufnehmen

In diesem Beispiel ist die Legacy-Umgebung nicht direkt in das Service Mesh eingebunden. Zu diesem Zweck müssen Sie alle Dienste, die in der Legacy-Umgebung ausgeführt werden, manuell beim Service Mesh registrieren. Wenn Ihre Umgebung bereits in Kubernetes ausgeführt wird, können Sie die Registrierung dank der nativen Einbindung in die Service Mesh APIs automatisieren.

In dieser Phase greifen Clients weiterhin über die Schnittstellen der Legacy-Umgebung auf die Mikrodienste zu, die migriert werden sollen. Das Service Mesh empfängt noch keinen Produktionstraffic.

Das folgende Diagramm zeigt, wie Dienste, die in der Legacy-Umgebung ausgeführt werden, in das Service Mesh aufgenommen werden.

Diagramm: In der Legacy-Umgebung ausgeführte Dienste werden in das Service Mesh aufgenommen

Dienste über das Service Mesh freigeben

Nach dem Registrieren der Legacy-Umgebung geben Sie die Mikrodienste, die in der Legacy-Umgebung ausgeführt werden, über das Service Mesh frei. In dieser Phase leiten Sie auch Traffic für Mikrodienste sukzessive von den Schnittstellen der Legacy-Umgebung an die Schnittstellen der Zielumgebung weiter.

Clients nehmen keine Dienstunterbrechung wahr, da sie über eine Load-Balancing-Schicht auf die Schnittstellen der beiden Umgebungen zugreifen. Außerdem bleiben Clients vom Routing des Traffics innerhalb des Service Mesh unberührt. Clients bemerken nicht, dass die Routingkonfiguration geändert wurde.

Das folgende Diagramm zeigt, wie die in der Legacy-Umgebung ausgeführten Dienste über das Service Mesh freigegeben werden.

Diagramm: In der Legacy-Umgebung ausgeführte Dienste werden über das Service Mesh freigegeben

Dienste in der Zielumgebung bereitstellen

In dieser Phase stellen Sie Mikrodienste in der Zielumgebung bereit. Hier wird davon ausgegangen, dass Sie diese Mikrodienste bereits containerisiert haben. Wenn dieser Prozess abgeschlossen ist, können Sie eine Bereitstellungsstrategie zum Initialisieren der Arbeitslast auswählen, die in die Zielumgebung zu migrieren ist:

  • Bulk-Bereitstellung: Sie stellen alle Mikrodienstinstanzen gleichzeitig bereit.
  • Graduelle Bereitstellung: Sie stellen jeweils einen Mikrodienst bereit.

Die Mikrodienstinstanzen in der Zielumgebung empfangen noch keinen Produktionstraffic.

Bei der Migration von zustandsorientierten Mikrodiensten müssen Sie auch zugehörige Daten migrieren, um Ausfallzeiten zu minimieren und Synchronisations- und Integritätsprobleme zu vermeiden. Weitere Informationen zu Datenmigrationsstrategien finden Sie hier.

In der Zielumgebung ausgeführte Mikrodienste werden dank der nativen Einbindung in Kubernetes und Istio automatisch im Service Mesh registriert. In dieser Phase verwenden Clients weiterhin die Mikrodienste, die in der Legacy-Umgebung ausgeführt und über das Service Mesh freigegeben werden. Die in der Zielumgebung ausgeführten Mikrodienste empfangen noch immer keinen Produktionstraffic.

Das folgende Diagramm zeigt die erweiterten Dienste, die keinen Produktionstraffic empfangen, sowie die Dienste in der Legacy-Umgebung, die über das Service Mesh freigegeben werden.

Diagramm: Erweiterte Dienste, die keinen Produktionstraffic empfangen, und die Dienste in der Legacy-Umgebung, die über das Service Mesh freigegeben werden

Routingregeln zum Aufteilen des Traffics einrichten

Sie richten nun Routingregeln ein, um den Produktionstraffic auf die Dienste in der Legacy-Umgebung und in der Zielumgebung mithilfe des Service Mesh aufzuteilen. Sie können zuerst einen kleinen Teil des Produktionstraffics an Mikrodienstinstanzen weiterleiten, die in der Zielumgebung ausgeführt werden. Wenn Ihr Vertrauen in die Zielumgebung durch die Testsuite und konsequentes Monitoring steigt, können Sie diesen Anteil am gesamten Traffic im Laufe der Zeit erhöhen.

Da Clientanfragen in beide Umgebungen weitergeleitet werden, fallen für zustandsorientierte Mikrodienste zusätzliche Planungs- und Koordinierungsschritte an, da auch zugehörige Daten migriert werden müssen und eine Übergangsphase mit mehreren "Sources of Truth" während der Migration auftreten kann.

Das folgende Diagramm zeigt, wie Traffic auf die Mikrodienste in der Zielumgebung und in der Legacy-Umgebung aufgeteilt wird.

Diagramm: Auf die Mikrodienste in der Zielumgebung und der Legacy-Umgebung aufgeteilter Traffic

Außerdem empfiehlt es sich, die Routingregeln so zu verfeinern, dass umgebungsübergreifende Anfragen nicht zugelassen werden. Wenn also eine Clientanfrage in einer Umgebung (Legacy- oder Zielumgebung) eingeht, verbleibt sie in dieser Umgebung.

Regeln zum Weiterleiten des Traffics an die Zielumgebung einrichten

In dieser Phase aktualisieren Sie die Routingregeln, um Traffic sukzessive an Dienste weiterzuleiten, die ausschließlich in der Zielumgebung ausgeführt werden.

Das folgende Diagramm zeigt, wie Traffic jetzt nur an die Zielumgebung weitergeleitet wird, während die Legacy-Umgebung als Sicherungsoption beibehalten wird.

Diagramm: Traffic, der jetzt nur an die Zielumgebung weitergeleitet wird, während die Legacy-Umgebung als Sicherungsoption beibehalten wird

Legacy-Umgebung deaktivieren

In dieser Phase deaktivieren Sie die Legacy-Umgebung.

Davor muss Folgendes gewährleistet sein:

  • Es wird kein Traffic an Mikrodienstinstanzen weitergeleitet, die in der Legacy-Umgebung ausgeführt werden.
  • Über die Schnittstellen der Legacy-Umgebung geht kein Traffic ein.
  • Die Zielumgebung wurde vollständig validiert.

Wenn diese Bedingungen erfüllt sind, können Sie Ihre DNS-Einträge so aktualisieren, dass sie auf den Load-Balancer verweisen, den Sie in der Bereitstellungsphase der Zielumgebung eingerichtet haben.

Das folgende Diagramm zeigt nur die Zielumgebung, da die Legacy-Umgebung deaktiviert wurde.

Diagramm: Zielumgebung (mit deaktivierter Legacy-Umgebung)

Weitere Informationen