CI/CD für MicroservicearchitekturenCI/CD for microservices architectures

Einer der wichtigsten Vorteile von Microservicearchitekturen sind kürzere Versionszyklen.Faster release cycles are one of the major advantages of microservices architectures. Die Agilität, die von Microservices erwartet wird, lässt sich aber nur mit einem zuverlässigen CI/CD-Prozess erreichen.But without a good CI/CD process, you won't achieve the agility that microservices promise. In diesem Artikel werden die Herausforderungen und einige Lösungsansätze für das Problem beschrieben.This article describes the challenges and recommends some approaches to the problem.

Was ist CI/CD?What is CI/CD?

CI/CD umfasst eigentlich mehrere verwandte Prozesse: Continuous Integration, Continuous Delivery und Continuous Deployment.When we talk about CI/CD, we're really talking about several related processes: Continuous integration, continuous delivery, and continuous deployment.

  • Continuous Integration.Continuous integration. Codeänderungen werden häufig in den Hauptbranch zusammengeführt.Code changes are frequently merged into the main branch. Mithilfe von automatisierten Build- und Testprozessen wird sichergestellt, dass der Code im Hauptbranch immer Produktionsqualität aufweist.Automated build and test processes ensure that code in the main branch is always production-quality.

  • Continuous Delivery.Continuous delivery. Alle Codeänderungen, die den CI-Prozess durchlaufen, werden automatisch in einer produktionsähnlichen Umgebung veröffentlicht.Any code changes that pass the CI process are automatically published to a production-like environment. Für die Bereitstellung in der aktiven Produktionsumgebung ist unter Umständen eine manuelle Freigabe erforderlich, ansonsten ist der Prozess jedoch automatisiert.Deployment into the live production environment may require manual approval, but is otherwise automated. Dadurch soll erreicht werden, dass Ihr Code stets für die Bereitstellung in der Produktionsumgebung bereit ist.The goal is that your code should always be ready to deploy into production.

  • Kontinuierliche Bereitstellung:Continuous deployment. Codeänderungen, die die zwei vorhergehenden Schritte durchlaufen haben, werden automatisch in der Produktionsumgebung bereitgestellt.Code changes that pass the previous two steps are automatically deployed into production.

Hier sind einige Ziele eines stabilen CI/CD-Prozesses für eine Microservicearchitektur aufgeführt:Here are some goals of a robust CI/CD process for a microservices architecture:

  • Jedes Team kann die eigenen Dienste unabhängig erstellen und bereitstellen, ohne dass andere Teams hierdurch beeinträchtigt oder gestört werden.Each team can build and deploy the services that it owns independently, without affecting or disrupting other teams.

  • Bevor eine neue Version eines Diensts für die Produktion bereitgestellt wird, wird sie zunächst zur Überprüfung in Umgebungen für die Entwicklung, Tests und Qualitätssicherung bereitgestellt.Before a new version of a service is deployed to production, it gets deployed to dev/test/QA environments for validation. Jede Phase verfügt über so genannte „Quality Gates“.Quality gates are enforced at each stage.

  • Eine neue Version eines Diensts kann parallel zur vorherigen Version bereitgestellt werden.A new version of a service can be deployed side by side with the previous version.

  • Es sind ausreichende Richtlinien für die Zugriffssteuerung vorhanden.Sufficient access control policies are in place.

  • Bei Workloads in Containern können Sie den Containerimages vertrauen, die für die Produktion bereitgestellt werden.For containerized workloads, you can trust the container images that are deployed to production.

Wichtigkeit einer robusten CI/CD-PipelineWhy a robust CI/CD pipeline matters

In einer herkömmlichen monolithischen Anwendung gibt es eine einzelne Buildpipeline, die die ausführbare Datei der Anwendung ausgibt.In a traditional monolithic application, there is a single build pipeline whose output is the application executable. Sämtliche Entwicklungsarbeiten werden dieser Pipeline zugeführt.All development work feeds into this pipeline. Bei einem Fehler mit hoher Priorität muss eine Korrektur integriert, getestet und veröffentlicht werden, was die Veröffentlichung neuer Features verzögern kann.If a high-priority bug is found, a fix must be integrated, tested, and published, which can delay the release of new features. Diese Probleme lassen sich durch eine sorgfältige Modulgestaltung sowie durch die Verwendung von Featurebranches behandeln, die die Auswirkungen von Codeänderungen minimieren.You can mitigate these problems by having well-factored modules and using feature branches to minimize the impact of code changes. Mit zunehmender Komplexität und wachsendem Funktionsumfang einer monolithischen Anwendung nimmt jedoch häufig auch die Fehleranfälligkeit des Releaseprozesses zu.But as the application grows more complex, and more features are added, the release process for a monolith tends to become more brittle and likely to break.

Die Microservices-Philosophie sieht kein langwieriges Releaseverfahren vor, in das sich die einzelnen Teams einreihen müssen.Following the microservices philosophy, there should never be a long release train where every team has to get in line. Das Team, das den Dienst „A“ erstellt, kann jederzeit ein Update veröffentlichen und muss nicht warten, bis Änderungen für den Dienst „B“ zusammengeführt, getestet und bereitgestellt wurden.The team that builds service "A" can release an update at any time, without waiting for changes in service "B" to be merged, tested, and deployed.

Diagramm einer monolithischen CI/CD-Anwendung

Um eine hohe Releasegeschwindigkeit zu erreichen, muss Ihre Releasepipeline automatisiert und sehr zuverlässig sein, um Risiken zu minimieren.To achieve a high release velocity, your release pipeline must be automated and highly reliable to minimize risk. Bei täglich oder mehrmals täglich durchgeführten Veröffentlichungen in der Produktionsumgebung darf es nur selten zu Regressionen oder Dienstausfällen kommen.If you release to production one or more times daily , regressions or service disruptions must be rare. Sollte doch einmal ein fehlerhaftes Update bereitgestellt werden, müssen Sie schnell und zuverlässig einen Rollback oder Rollforward auf eine frühere Dienstversion ausführen können.At the same time, if a bad update does get deployed, you must have a reliable way to quickly roll back or roll forward to a previous version of a service.

HerausforderungenChallenges

  • Zahlreiche kompakte und unabhängige Codebasen:Many small independent code bases. Jedes Team ist für die Erstellung seines eigenen Diensts verantwortlich und verfügt über eine eigene Buildpipeline.Each team is responsible for building its own service, with its own build pipeline. In einigen Organisationen verwenden die Teams unter Umständen separate Coderepositorys.In some organizations, teams may use separate code repositories. Getrennte Repositorys können dazu führen, dass das Know-how für die Erstellung des Systems auf mehrere Teams verteilt ist und niemand in der Organisation weiß, wie die gesamte Anwendung bereitgestellt wird.Separate repositories can lead to a situation where the knowledge of how to build the system is spread across teams, and nobody in the organization knows how to deploy the entire application. Was passiert beispielsweise in einem Notfallwiederherstellungsszenario, wenn Sie schnell eine Bereitstellung in einem neuen Cluster durchführen müssen?For example, what happens in a disaster recovery scenario, if you need to quickly deploy to a new cluster?

    Lösung: Verwenden Sie für Build und Bereitstellung von Diensten eine einheitliche und automatisierte Pipeline, so dass dieses Wissen nicht in den einzelnen Teams „verborgen“ ist.Mitigation: Have a unified and automated pipeline to build and deploy services, so that this knowledge is not "hidden" within each team.

  • Mehrere Sprachen und Frameworks:Multiple languages and frameworks. Wenn jedes Team seinen eigenen Technologie-Mix verwendet, kann es schwierig sein, einen einzelnen Buildprozess zu erstellen, der für die gesamte Organisation geeignet ist.With each team using its own mix of technologies, it can be difficult to create a single build process that works across the organization. Der Buildprozess muss so flexibel sein, dass jedes Team ihn für die gewählte Sprache oder das gewählte Framework anpassen kann.The build process must be flexible enough that every team can adapt it for their choice of language or framework.

    Lösung: Kapseln Sie den Buildprozess für jeden Dienst in einem Container.Mitigation: Containerize the build process for each service. Auf diese Weise muss das Buildsystem nur dazu fähig sein, die Container auszuführen.That way, the build system just needs to be able to run the containers.

  • Integration und Auslastungstests:Integration and load testing. Wenn Teams Updates nach ihrem eigenen Zeitplan veröffentlichen, kann die Entwicklung zuverlässiger End-to-End-Tests zur Herausforderung werden – insbesondere, wenn Dienste von anderen Diensten abhängen.With teams releasing updates at their own pace, it can be challenging to design robust end-to-end testing, especially when services have dependencies on other services. Darüber hinaus kann der Betrieb eines vollwertigen Produktionsclusters teuer sein, weshalb es unwahrscheinlich ist, dass jedes Team allein zu Testzwecken einen eigenen vollwertigen Cluster auf Produktionsniveau betreibt.Moreover, running a full production cluster can be expensive, so it's unlikely that every team will run its own full cluster at production scales, just for testing.

  • Releaseverwaltung:Release management. Jedes Team sollte in der Lage sein, ein Update in der Produktionsumgebung bereitzustellen.Every team should be able to deploy an update to production. Das bedeutet nicht, dass jedes einzelne Teammitglied über entsprechende Berechtigungen verfügt.That doesn't mean that every team member has permissions to do so. Durch eine zentrale Release-Manager-Rolle werden Bereitstellungen jedoch unter Umständen ausgebremst.But having a centralized Release Manager role can reduce the velocity of deployments.

    Lösung: Je zuverlässiger und stärker automatisiert Ihr CI/CD-Prozess ist, desto weniger Bedarf besteht für eine zentrale Instanz.Mitigation: The more that your CI/CD process is automated and reliable, the less there should be a need for a central authority. Für die Veröffentlichung wichtiger Featureupdates und kleinerer Fehlerbehebung können jeweils unterschiedliche Richtlinien gelten.That said, you might have different policies for releasing major feature updates versus minor bug fixes. Dezentralisierung bedeutet keinen Verzicht auf Governance.Being decentralized doesn't mean zero governance.

  • Dienstupdates:Service updates. Wenn Sie einen Dienst auf eine neue Version aktualisieren, dürfen dadurch keine anderen Dienste beeinträchtigt werden, die von diesem Dienst abhängen.When you update a service to a new version, it shouldn't break other services that depend on it.

    Lösung: Verwenden Sie für geringfügige Änderungen Bereitstellungstechniken wie Blaugrün- oder Canary-Releases.Mitigation: Use deployment techniques such as blue-green or canary release for non-breaking changes. Stellen Sie für Breaking Changes an APIs die neue Version parallel zur vorherigen Version bereit.For breaking API changes, deploy the new version side by side with the previous version. Auf diese Weise können Dienste, die die vorherige API nutzen, aktualisiert und für die neue API getestet werden.That way, services that consume the previous API can be updated and tested for the new API. Mehr dazu finden Sie unten unter Aktualisieren von Diensten.See Updating services, below.

Monorepo im Vergleich mit mehreren RepositorysMonorepo vs. multi-repo

Vor dem Erstellen eines CI/CD-Workflows müssen Sie sich darüber im Klaren sein, wie die Codebasis strukturiert sein und verwaltet werden soll.Before creating a CI/CD workflow, you must know how the code base will be structured and managed.

  • Arbeiten die Teams in separaten Repositorys oder in einem „Monorepo“ (einzelnen Repository)?Do teams work in separate repositories or in a monorepo (single repository)?
  • Wie sieht Ihre Strategie für das „Branchen“ aus?What is your branching strategy?
  • Wer kann Code per Pushvorgang in die Produktion übertragen?Who can push code to production? Ist eine Release Manager-Rolle vorhanden?Is there a release manager role?

Die Beliebtheit des Monorepo-Ansatzes ist gestiegen, aber beide Ansätze haben sowohl Vor- als auch Nachteile.The monorepo approach has been gaining favor but there are advantages and disadvantages to both.

  MonorepoMonorepo Mehrere RepositorysMultiple repos
VorteileAdvantages CodefreigabeCode sharing
Einfacheres Standardisieren von Code und ToolsEasier to standardize code and tooling
Einfacheres Umgestalten von CodeEasier to refactor code
Auffindbarkeit: Zentrale CodeansichtDiscoverability - single view of the code
Eindeutige Eigentümerschaft pro TeamClear ownership per team
Potenziell weniger ZusammenführungskonfliktePotentially fewer merge conflicts
Unterstützung bei der Durchsetzung der Entkopplung von MicroservicesHelps to enforce decoupling of microservices
HerausforderungenChallenges Änderungen an freigegebenem Code können sich auf mehrere Microservices auswirkenChanges to shared code can affect multiple microservices
Höheres Potenzial für ZusammenführungskonflikteGreater potential for merge conflicts
Tools müssen auf große Codebasis skaliert werdenTooling must scale to a large code base
ZugriffssteuerungAccess control
Komplexerer BereitstellungsprozessMore complex deployment process
Schwierigere CodefreigabeHarder to share code
Schwierigeres Durchsetzen von CodierungsstandardsHarder to enforce coding standards
Verwaltung von AbhängigkeitenDependency management
Diffuse Codebasis, schlechte AuffindbarkeitDiffuse code base, poor discoverability
Mangel an freigegebener InfrastrukturLack of shared infrastructure

Aktualisieren von DienstenUpdating services

Für die Aktualisierung eines Diensts, der sich bereits in Produktion befindet, gibt es verschiedene Strategien.There are various strategies for updating a service that's already in production. Hier werden drei gängige Optionen erläutert: paralleles Update, Blaugrün-Bereitstellung und Canary-Release.Here we discuss three common options: Rolling update, blue-green deployment, and canary release.

Parallele UpdatesRolling updates

Bei einem parallelen Update stellen Sie neue Instanzen eines Diensts bereit, und diese neuen Instanzen nehmen sofort Anforderungen entgegen.In a rolling update, you deploy new instances of a service, and the new instances start receiving requests right away. Wenn die neuen Instanzen online geschaltet werden, werden die vorherigen Instanzen entfernt.As the new instances come up, the previous instances are removed.

Beispiel:Example. In Kubernetes stellen parallele Updates das Standardverhalten dar, wenn Sie die Pod-Spezifikation für eine Bereitstellung aktualisieren.In Kubernetes, rolling updates are the default behavior when you update the pod spec for a Deployment. Der Bereitstellungscontroller erstellt eine neue Replikatgruppe (ReplicaSet) für die aktualisierten Pods.The Deployment controller creates a new ReplicaSet for the updated pods. Anschließend wird die neue Replikatgruppe zentral hoch- und die alte Gruppe zentral herunterskaliert, sodass die gewünschte Replikatanzahl erhalten bleibt.Then it scales up the new ReplicaSet while scaling down the old one, to maintain the desired replica count. Alte Pods werden erst gelöscht, wenn die neuen Pods bereit sind.It doesn't delete old pods until the new ones are ready. Kubernetes protokolliert den Verlauf des Updates, damit Sie bei Bedarf ein Rollback für das Update ausführen können.Kubernetes keeps a history of the update, so you can roll back an update if needed.

Beispiel:Example. Azure Service Fabric verwendet standardmäßig die Strategie paralleler Updates.Azure Service Fabric uses the rolling update strategy by default. Diese Strategie eignet sich am besten für die Bereitstellung einer Dienstversion mit neuen Features, ohne vorhandene APIs zu ändern.This strategy is best suited for deploying a version of a service with new features without changing existing APIs. Service Fabric startet eine Upgradebereitstellung, indem es den Anwendungstyp für eine Teilmenge der Knoten oder eine Updatedomäne aktualisiert.Service Fabric starts an upgrade deployment by updating the application type to a subset of the nodes or an update domain. Anschließend wird der Vorgang für die nächste Updatedomäne fortgesetzt, bis alle Domänen aktualisiert sind.It then rolls forward to the next update domain until all domains are upgraded. Falls eine Upgradedomäne nicht aktualisiert werden kann, wird der Anwendungstyp für alle Domänen wieder auf die vorherige Version zurückgesetzt.If an upgrade domain fails to update, the application type rolls back to the previous version across all domains. Beachten Sie, dass ein Anwendungstyp mit mehreren Diensten (und bei Aktualisierung aller Dienste im Rahmen einer Upgradebereitstellung) fehleranfällig ist.Be aware that an application type with multiple services (and if all services are updated as part of one upgrade deployment) is prone to failure. Wenn ein Dienst nicht aktualisiert werden kann, wird die gesamte Anwendung auf die vorherige Version zurückgesetzt, und die weiteren Dienste werden nicht aktualisiert.If one service fails to update, the entire application is rolled back to the previous version and the other services are not updated.

Eine der Herausforderungen bei parallelen Updates besteht darin, dass während der Aktualisierung eine Mischung aus alten und neuen Versionen ausgeführt wird und Datenverkehr empfängt.One challenge of rolling updates is that during the update process, a mix of old and new versions are running and receiving traffic. Während dieser Zeit können Anforderungen jeweils an eine der beiden Versionen weitergeleitet werden.During this period, any request could get routed to either of the two versions.

Für Breaking Changes an APIs ist es eine bewährte Methode, beide Versionen parallel zu unterstützen, bis alle Clients der Vorversion aktualisiert wurden.For breaking API changes, a good practice is to support both versions side by side, until all clients of the previous version are updated. Mehr dazu finden Sie unter API-Versionsverwaltung.See API versioning.

Blaugrün-BereitstellungBlue-green deployment

Bei einer Blaugrün-Bereitstellung stellen Sie die neue Version zusammen mit der vorherigen Version bereit.In a blue-green deployment, you deploy the new version alongside the previous version. Nach der Überprüfung der neuen Version leiten Sie sämtlichen Datenverkehr von der vorherigen Version zur neuen Version um.After you validate the new version, you switch all traffic at once from the previous version to the new version. Anschließend überwachen Sie die Anwendung auf mögliche Probleme.After the switch, you monitor the application for any problems. Im Problemfall können Sie zur alten Version zurückkehren.If something goes wrong, you can swap back to the old version. Liegen keine Probleme, können Sie die alte Version löschen.Assuming there are no problems, you can delete the old version.

Bei einer eher traditionellen monolithischen oder n-schichtigen Anwendung war eine Blaugrün-Bereitstellung in der Regel mit der Bereitstellung zweier identischer Umgebungen verbunden.With a more traditional monolithic or N-tier application, blue-green deployment generally meant provisioning two identical environments. Dabei musste die neue Version in einer Stagingumgebung bereitgestellt und der Clientdatenverkehr anschließend an die Stagingumgebung umgeleitet werden (beispielsweise durch Austauschen der VIP-Adressen).You would deploy the new version to a staging environment, then redirect client traffic to the staging environment — for example, by swapping VIP addresses. In einer Microservicearchtektur erfolgen Updates in der Microserviceschicht, also stellen Sie normalerweise das Update in der gleichen Umgebung bereit und verwenden einen Mechanismus für die Diensterkennung für den Umstieg.In a microservices architecture, updates happen at the microservice level, so you would typically deploy the update into the same environment and use a service discovery mechanism to swap.

Beispiel.Example. In Kubernetes müssen Sie für eine Blaugrün-Bereitstellung keinen separaten Cluster bereitstellen.In Kubernetes, you don't need to provision a separate cluster to do blue-green deployments. Stattdessen können Sie Selektoren nutzen.Instead, you can take advantage of selectors. Erstellen Sie eine neue Bereitstellungsressource mit einer neuen Pod-Spezifikation und einem anderen Satz von Bezeichnungen.Create a new Deployment resource with a new pod spec and a different set of labels. Erstellen Sie diese Bereitstellung, ohne die vorherige Bereitstellung zu löschen oder den Dienst zu ändern, der darauf verweist.Create this deployment, without deleting the previous deployment or modifying the service that points to it. Wenn die neuen Pods aktiv sind, können Sie den Selektor des Diensts auf die neue Bereitstellung aktualisieren.Once the new pods are running, you can update the service's selector to match the new deployment.

Ein Nachteil von Blaugrün-Bereitstellungen ist, dass während der Aktualisierung doppelt so viele Pods für den Dienst (aktuelle und neue Version) aktiv sind.One drawback of blue-green deployment is that during the update, you are running twice as many pods for the service (current and next). Wenn die Pods einen hohen Bedarf an CPU- oder Arbeitsspeicherressourcen haben, müssen Sie den Cluster zur Bewältigung des Ressourcenbedarfs möglicherweise vorübergehend aufskalieren.If the pods require a lot of CPU or memory resources, you may need to scale out the cluster temporarily to handle the resource consumption.

Canary-ReleaseCanary release

Bei einem Canary-Release führen Sie eine aktualisierte Version für eine geringe Anzahl von Clients ein.In a canary release, you roll out an updated version to a small number of clients. Anschließend überwachen Sie das Verhalten des neuen Diensts, bevor Sie ihn für alle Clients einführen.Then you monitor the behavior of the new service before rolling it out to all clients. Dies ermöglicht eine langsame, kontrollierte Einführung, die Beobachtung echter Daten und die Erkennung von Problemen, bevor alle Kunden betroffen sind.This lets you do a slow rollout in a controlled fashion, observe real data, and spot problems before all customers are affected.

Die Verwaltung eines Canary-Release ist im Vergleich zu einer Blaugrün-Bereitstellung oder einem parallelen Update komplexer, da Anforderungen dynamisch an verschiedene Versionen des Diensts weitergeleitet werden müssen.A canary release is more complex to manage than either blue-green or rolling update, because you must dynamically route requests to different versions of the service.

Beispiel.Example. In Kubernetes können Sie einen Dienst so konfigurieren, dass er sich über zwei Replikatgruppen (einen für jede Version) erstreckt, und die Replikatanzahl manuell anpassen.In Kubernetes, you can configure a Service to span two replica sets (one for each version) and adjust the replica counts manually. Aufgrund des von Kubernetes verwendeten Lastenausgleichs zwischen Pods ist dieser Ansatz jedoch nicht sehr präzise.However, this approach is rather coarse-grained, because of the way Kubernetes load balances across pods. Ein Beispiel: Wenn Sie insgesamt über 10 Replikate verfügen, können Sie Datenverkehr nur in Zehn-Prozent-Schritten verlagern.For example, if you have a total of 10 replicas, you can only shift traffic in 10% increments. Bei Verwendung eines Dienstnetzes können Sie mithilfe der entsprechenden Routingregeln eine komplexere Canary-Release-Strategie implementieren.If you are using a service mesh, you can use the service mesh routing rules to implement a more sophisticated canary release strategy.

Nächste SchritteNext steps

Erlernen spezifischer CI/CD-Praktiken für Microservices, die in Kubernetes ausgeführt werden.Learn specific CI/CD practices for microservices running on Kubernetes.