Erstellen einer CI/CD-Pipeline für Microservices in KubernetesBuilding a CI/CD pipeline for microservices on Kubernetes

Das Erstellen eines zuverlässigen CI/CD-Prozesses für eine Microservicearchitektur kann schwierig sein.It can be challenging to create a reliable CI/CD process for a microservices architecture. Einzelne Teams müssen in der Lage sein, Dienste schnell und zuverlässig zu veröffentlichen, ohne andere Teams zu stören oder die Stabilität der gesamten Anwendung zu gefährden.Individual teams must be able to release services quickly and reliably, without disrupting other teams or destabilizing the application as a whole.

Dieser Artikel beschreibt eine CI/CD-Beispielpipeline für das Bereitstellen von Microservices in Azure Kubernetes Service (AKS).This article describes an example CI/CD pipeline for deploying microservices to Azure Kubernetes Service (AKS). Jedes Team und jedes Projekt ist anders, daher sollten Sie diesen Artikel nicht als feststehende Sammlung unverrückbarer Regeln verstehen.Every team and project is different, so don't take this article as a set of hard-and-fast rules. Er soll vielmehr einen Ausgangspunkt für Ihren Entwurf Ihres eigenen CI/CD-Prozesses bilden.Instead, it's meant to be a starting point for designing your own CI/CD process.

Die hier beschriebene Beispielpipeline wurde für eine Microservice-Referenzimplementierung erstellt, die sich Drohnenlieferungsanwendung nennt und auf GitHub verfügbar ist.The example pipeline described here was created for a microservices reference implementation called the Drone Delivery application, which you can find on GitHub. Das Anwendungsszenario ist hier beschrieben.The application scenario is described here.

Die Ziele der Pipeline können wie folgt zusammengefasst werden:The goals of the pipeline can be summarized as follows:

  • Teams können ihre Dienste unabhängig voneinander entwickeln und bereitstellen.Teams can build and deploy their services independently.
  • Codeänderungen, die den CI-Prozess durchlaufen, werden automatisch in einer produktionsähnlichen Umgebung bereitgestellt.Code changes that pass the CI process are automatically deployed to a production-like environment.
  • In jeder Phase der Pipeline werden Quality Gates durchgesetzt.Quality gates are enforced at each stage of the pipeline.
  • 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.

Hintergrundinformationen dazu finden Sie unter CI/CD für Microservicearchitekturen.For more background, see CI/CD for microservices architectures.

AnnahmenAssumptions

Für die Zwecke dieses Beispiels machen wir einige Annahmen über das Entwicklungsteam und die Codebasis:For purposes of this example, here are some assumptions about the development team and the code base:

  • Für das Coderepository wird der Monorepo-Ansatz genutzt, und die Ordner sind nach Microservice organisiert.The code repository is a monorepo, with folders organized by microservice.
  • Die Branchstrategie des Teams basiert auf der Trunk-basierten Entwicklung.The team's branching strategy is based on trunk-based development.
  • Das Team verwendet Releasebranches zur Verwaltung von Releases.The team uses release branches to manage releases. Für jeden Microservice werden separate Releases erstellt.Separate releases are created for each microservice.
  • Der CI/CD-Prozess verwendet Azure Pipelines zum Erstellen, Testen und Bereitstellen der Microservices in AKS.The CI/CD process uses Azure Pipelines to build, test, and deploy the microservices to AKS.
  • Die Containerimages für die einzelnen Microservices sind in der Azure-Containerregistrierung gespeichert.The container images for each microservice are stored in Azure Container Registry.
  • Das Team verwendet Helm-Charts, um die Microservices zu verpacken.The team uses Helm charts to package each microservice.

Diese Annahmen bestimmen viele der spezifischen Details der CI/CD-Pipeline.These assumptions drive many of the specific details of the CI/CD pipeline. Der hier beschriebene Grundansatz lässt sich jedoch für andere Prozesse, Tools und Dienste anpassen, wie etwa Jenkins oder Docker Hub.However, the basic approach described here be adapted for other processes, tools, and services, such as Jenkins or Docker Hub.

ValidierungsbuildsValidation builds

Nehmen wir an, ein Entwickler arbeitet an einem Microservice mit dem Namen „Delivery Service“ (Lieferdienst).Suppose that a developer is working on a microservice called the Delivery Service. Beim Entwickeln eines neuen Features checkt der Entwickler Code in einen Featurebranch ein.While developing a new feature, the developer checks code into a feature branch. Für Featurebranches wird die Benennungskonvention feature/* verwendet.By convention, feature branches are named feature/*.

CI/CD-Workflow

Die Builddefinitionsdatei enthält einen Trigger, der nach dem Branchnamen und dem Quellpfad filtert:The build definition file includes a trigger that filters by the branch name and the source path:

trigger:
  batch: true
  branches:
    include:
    # for new release to production: release flow strategy
    - release/delivery/v*
    - refs/release/delivery/v*
    - master
    - feature/delivery/*
    - topic/delivery/*
  paths:
    include:
    - /src/shipping/delivery/

⮚ Sehen Sie dazu die Quelldatei.⮚ See the source file.

Mit diesem Ansatz kann jedes Team über eine eigene Buildpipeline verfügen.Using this approach, each team can have its own build pipeline. Nur Code, der im Ordner /src/shipping/delivery eingecheckt wird, löst einen Build des Lieferdiensts aus.Only code that is checked into the /src/shipping/delivery folder triggers a build of the Delivery Service. Das Pushen von Commits auf einen Branch, der mit dem Filter übereinstimmt, löst einen CI-Build aus.Pushing commits to a branch that matches the filter triggers a CI build. An diesem Punkt des Workflows führt der CI-Build eine Codeüberprüfung mit minimalem Umfang durch:At this point in the workflow, the CI build runs some minimal code verification:

  1. Erstellen des Codes.Build the code.
  2. Ausführen von Komponententests.Run unit tests.

Das Ziel besteht darin, die Buildzeiten kurz zu halten, damit der Entwickler schnell Feedback erhält.The goal is to keep build times short, so the developer can get quick feedback. Wenn das Feature für die Zusammenführung mit dem Master bereit ist, öffnet der Entwickler einen PR-Vorgang.Once the feature is ready to merge into master, the developer opens a PR. Hierdurch wird ein weiterer CI-Build ausgelöst, bei dem einige zusätzliche Überprüfungen durchgeführt werden:This triggers another CI build that performs some additional checks:

  1. Erstellen des Codes.Build the code.
  2. Ausführen von Komponententests.Run unit tests.
  3. Erstellen des Runtime-Containerimages.Build the runtime container image.
  4. Durchführen von Überprüfungen auf Sicherheitsrisiken für das Image.Run vulnerability scans on the image.

CI/CD-Workflow

Hinweis

In Azure DevOps-Repos können Sie Richtlinien zum Schützen von Branches definieren.In Azure DevOps Repos, you can define policies to protect branches. Für die Richtlinie sind beispielsweise ggf. ein erfolgreicher CI-Build sowie eine Genehmigung eines Prüfers erforderlich, damit die Zusammenführung mit dem Master erfolgen kann.For example, the policy could require a successful CI build plus a sign-off from an approver in order to merge into master.

Vollständiger CI/CD-BuildFull CI/CD build

An einem bestimmten Punkt ist das Team zum Bereitstellen einer neuen Version des Lieferdiensts bereit.At some point, the team is ready to deploy a new version of the Delivery service. Der Release Manager erstellt einen Branch vom Master und verwendet dazu das folgende Benennungsmuster: release/<microservice name>/<semver>.The release manager creates a branch from master with this naming pattern: release/<microservice name>/<semver>. Beispiel: release/delivery/v1.0.2.For example, release/delivery/v1.0.2.

CI/CD-Workflow

Die Erstellung dieses Branches löst einen vollständigen CI-Build aus, für den alle der vorstehenden Schritte ausgeführt werden, plus:Creation of this branch triggers a full CI build that runs all of the previous steps plus:

  1. Pushübertragung des Containerimages in die Azure-ContainerregistrierungPush the container image to Azure Container Registry. Das Image wird mit der Versionsnummer aus dem Branchnamen versehen.The image is tagged with the version number taken from the branch name.
  2. Ausführen von helm package zum Verpacken des Helm-Charts für den DienstRun helm package to package the Helm chart for the service. Das Chart ist außerdem mit einer Versionsnummer gekennzeichnet.The chart is also tagged with a version number.
  3. Übertragen des Helm-Pakets an die Containerregistrierung per Push.Push the Helm package to Container Registry.

Wenn dieser Buildvorgang erfolgreich ist, wird mithilfe einer Releasepipeline von Azure Pipelines ein Bereitstellungsprozess (CD) ausgelöst.Assuming this build succeeds, it triggers a deployment (CD) process using an Azure Pipelines release pipeline. Diese Pipeline weist folgende Stufen auf:This pipeline has the following steps:

  1. Bereitstellen des Helm-Charts in einer QA-Umgebung.Deploy the Helm chart to a QA environment.
  2. Eine genehmigende Person meldet sich ab, bevor das Paket für die Produktion bereitgestellt wird.An approver signs off before the package moves to production. Weitere Informationen finden Sie unter Release deployment control using approvals (Steuerung von Releasebereitstellungen durch Genehmigungen).See Release deployment control using approvals.
  3. Versehen Sie das Docker-Image für den Produktionsnamespace in Azure Container Registry mit einem neuen Tag.Retag the Docker image for the production namespace in Azure Container Registry. Wenn das derzeitige Tag beispielsweise myrepo.azurecr.io/delivery:v1.0.2 lautet, lautet das Tag für die Produktion myrepo.azurecr.io/prod/delivery:v1.0.2.For example, if the current tag is myrepo.azurecr.io/delivery:v1.0.2, the production tag is myrepo.azurecr.io/prod/delivery:v1.0.2.
  4. Stellen Sie das Helm-Chart in der Produktionsumgebung bereit.Deploy the Helm chart to the production environment.

Auch beim Monorepo-Ansatz können diese Aufgaben einzelnen Microservices zugeordnet werden, damit die Teams Bereitstellungen schneller durchführen können.Even in a monorepo, these tasks can be scoped to individual microservices, so that teams can deploy with high velocity. Der Prozess weist einige manuelle Schritte auf: Genehmigen von PRs, Erstellen von Releasebranches und Genehmigen von Bereitstellungen im Produktionscluster.The process has some manual steps: Approving PRs, creating release branches, and approving deployments into the production cluster. Der Richtlinie nach sind dies manuelle Schritte – aber sie können auch automatisiert werden, falls die Organisation dies vorzieht.These steps are manual by policy — they could be automated if the organization prefers.

Isolation von UmgebungenIsolation of environments

Sie verfügen über mehrere Umgebungen, in denen Sie Dienste bereitstellen, z.B. Entwicklung, Feuerprobe, Integrationstests, Auslastungstests und schließlich Produktion.You will have multiple environments where you deploy services, including environments for development, smoke testing, integration testing, load testing, and finally production. Für diese Umgebungen ist ein gewisses Maß an Isolation erforderlich.These environments need some level of isolation. In Kubernetes haben Sie die Wahl zwischen physischer Isolation und logischer Isolation.In Kubernetes, you have a choice between physical isolation and logical isolation. Physische Isolation bedeutet, dass die Bereitstellung in separaten Clustern erfolgt.Physical isolation means deploying to separate clusters. Bei der logischen Isolation werden wie oben beschrieben Namespaces und Richtlinien verwendet.Logical isolation uses namespaces and policies, as described earlier.

Unsere Empfehlung lautet, einen dedizierten Produktionscluster mit einem zusätzlichen separaten Cluster für Ihre Entwicklungs- und Testumgebungen zu erstellen.Our recommendation is to create a dedicated production cluster along with a separate cluster for your dev/test environments. Verwenden Sie die logische Isolation, um Umgebungen im Entwicklungs-/Testcluster zu trennen.Use logical isolation to separate environments within the dev/test cluster. Im Entwicklungs-/Testcluster bereitgestellte Dienste sollten niemals Zugriff auf Datenspeicher haben, in denen sich Geschäftsdaten befinden.Services deployed to the dev/test cluster should never have access to data stores that hold business data.

BuildprozessBuild process

Verpacken Sie nach Möglichkeit Ihren Buildprozess in einem Docker-Container.When possible, package your build process into a Docker container. Auf diese Weise können Sie Ihre Codeartefakte mithilfe von Docker erstellen, ohne die Buildumgebung auf jedem Buildcomputer konfigurieren zu müssen.That allows you to build your code artifacts using Docker, without needing to configure the build environment on each build machine. Ein Container-Buildprozess erleichtert das Aufskalieren der CI-Pipeline durch Hinzufügen neuer Build-Agents.A containerized build process makes it easy to scale out the CI pipeline by adding new build agents. Außerdem kann jeder Entwickler im Team den Code durch einfaches Ausführen des Buildcontainers erstellen.Also, any developer on the team can build the code simply by running the build container.

Durch die Verwendung mehrstufiger Builds in Docker können Sie die Buildumgebung und das Laufzeitimage in einem einzelnen Dockerfile definieren.By using multi-stage builds in Docker, you can define the build environment and the runtime image in a single Dockerfile. Dies ist beispielsweise ein Dockerfile, das eine ASP.NET Core-Anwendung erstellt:For example, here's a Dockerfile that builds an ASP.NET Core application:

FROM microsoft/dotnet:2.2-runtime AS base
WORKDIR /app

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src/Fabrikam.Workflow.Service

COPY Fabrikam.Workflow.Service/Fabrikam.Workflow.Service.csproj .
RUN dotnet restore Fabrikam.Workflow.Service.csproj

COPY Fabrikam.Workflow.Service/. .
RUN dotnet build Fabrikam.Workflow.Service.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish Fabrikam.Workflow.Service.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Fabrikam.Workflow.Service.dll"]

⮚ Sehen Sie dazu die Quelldatei.⮚ See the source file.

Dieses Dockerfile definiert mehrere Buildphasen.This Dockerfile defines several build stages. Beachten Sie, dass die Phase mit dem Namen base die ASP.NET Core-Runtime verwendet, während die Phase mit dem Namen build das vollständige ASP.NET Core SDK verwendet.Notice that the stage named base uses the ASP.NET Core runtime, while the stage named build uses the full ASP.NET Core SDK. Die build Phase wird verwendet, um das ASP.NET Core-Projekt zu erstellen.The build stage is used to build the ASP.NET Core project. Der endgültige Laufzeitcontainer wird jedoch aus base erstellt, das nur die Runtime enthält und erheblich kleiner als das vollständige SDK-Image ist.But the final runtime container is built from base, which contains just the runtime and is significantly smaller than the full SDK image.

Erstellen eines Test RunnersBuilding a test runner

Eine weitere bewährte Methode ist das Ausführen von Komponententests im Container.Another good practice is to run unit tests in the container. Dies ist beispielsweise ein Teil einer Docker-Datei, die einen Test Runner erstellt:For example, here is part of a Docker file that builds a test runner:

FROM build AS testrunner
WORKDIR /src/tests

COPY Fabrikam.Workflow.Service.Tests/*.csproj .
RUN dotnet restore Fabrikam.Workflow.Service.Tests.csproj

COPY Fabrikam.Workflow.Service.Tests/. .
ENTRYPOINT ["dotnet", "test", "--logger:trx"]

Ein Entwickler kann diese Docker-Datei zur lokalen Ausführung der Tests verwenden:A developer can use this Docker file to run the tests locally:

docker build . -t delivery-test:1 --target=testrunner
docker run -p 8080:8080 delivery-test:1

Die CI-Pipeline sollte die Tests ebenfalls im Rahmen des Buildüberprüfungsschritts ausführen.The CI pipeline should also run the tests as part of the build verification step.

Beachten Sie, dass in dieser Datei der Docker-Befehl ENTRYPOINT verwendet wird, um die Tests auszuführen, nicht der Docker-Befehl RUN.Note that this file uses the Docker ENTRYPOINT command to run the tests, not the Docker RUN command.

  • Wenn Sie den Befehl RUN verwenden, werden die Tests jedes Mal ausgeführt, wenn Sie das Image erstellen.If you use the RUN command, the tests run every time you build the image. Durch Verwendung von ENTRYPOINT sind die Tests optional aktivierbar.By using ENTRYPOINT, the tests are opt-in. Sie werden nur ausgeführt, wenn Sie die Phase testrunner explizit ansteuern.They run only when you explicitly target the testrunner stage.
  • Ein Fehler im Test führt nicht zu einem Fehler beim Docker-Befehl build.A failing test doesn't cause the Docker build command to fail. Auf diese Weise können Sie Buildfehler des Containers von Testfehlern unterscheiden.That way you can distinguish container build failures from test failures.
  • Testergebnisse können auf einem eingebundenen Volume gespeichert werden.Test results can be saved to a mounted volume.

Bewährte Methoden für ContainerContainer best practices

Hier sind einige weitere bewährte Methoden, die beim Arbeiten mit Containern berücksichtigt werden sollten:Here are some other best practices to consider for containers:

  • Definieren Sie organisationsweite Konventionen für Containertags und für die Versionsverwaltung sowie Namenskonventionen für im Cluster bereitgestellte Ressourcen (Pods, Dienste und Ähnliches).Define organization-wide conventions for container tags, versioning, and naming conventions for resources deployed to the cluster (pods, services, and so on). Dies kann die Diagnose von Bereitstellungsproblemen vereinfachen.That can make it easier to diagnose deployment issues.

  • Im Rahmen des Entwicklungs- und Testzyklus erstellt der CI/CD-Prozess zahlreiche Containerimages.During the development and test cycle, the CI/CD process will build many container images. Nicht alle dieser Images kommen für die Veröffentlichung in Frage, und nur einige der so genannten Release Candidates werden in die Produktionsumgebung heraufgestuft.Only some of those images are candidates for release, and then only some of those release candidates will get promoted to production. Entwickeln Sie eine klare Versionsverwaltungsstrategie, damit Sie wissen, welche Images derzeit in der Produktionsumgebung bereitgestellt sind, und bei Bedarf einen Rollback auf eine vorherige Version ausführen können.Have a clear versioning strategy, so that you know which images are currently deployed to production, and can roll back to a previous version if necessary.

  • Stellen Sie immer spezifische Containerversionstags bereit, nicht einfach latest.Always deploy specific container version tags, not latest.

  • Verwenden Sie Namespaces in der Azure-Containerregistrierung, um Images, die bereits für die Produktion genehmigt wurden, von den noch in der Testphase befindlichen Images zu isolieren.Use namespaces in Azure Container Registry to isolate images that are approved for production from images that are still being tested. Verschieben Sie ein Image nur dann in den Produktionsnamespace, wenn Sie bereit sind, es für die Produktion bereitzustellen.Don't move an image into the production namespace until you're ready to deploy it into production. Wenn Sie diese Vorgehensweise mit der semantischen Versionsverwaltung von Containerimages kombinieren, verringert sich die Wahrscheinlichkeit, dass Sie versehentlich eine Version bereitstellen, die nicht für die Veröffentlichung freigegeben wurde.If you combine this practice with semantic versioning of container images, it can reduce the chance of accidentally deploying a version that wasn't approved for release.

  • Befolgen Sie das Prinzip der geringsten Rechte, indem Sie Container als Benutzer ohne besondere Rechte ausführen.Follow the principle of least privilege by running containers as a nonprivileged user. In Kubernetes können Sie eine Pod-Sicherheitsrichtlinie erstellen, die die Ausführung von Containern als root verhindert.In Kubernetes, you can create a pod security policy that prevents containers from running as root. Weitere Informationen finden Sie unter Prevent Pods From Running With Root Privileges (Verhindern der Ausführung von Pods mit Stammberechtigungen).See Prevent Pods From Running With Root Privileges.

Helm-DiagrammeHelm charts

Erwägen Sie die Verwendung von Helm zum Erstellen und Bereitstellen von Diensten.Consider using Helm to manage building and deploying services. Dies sind einige der Features von Helm, die für CI/CD nützlich sind:Here are some of the features of Helm that help with CI/CD:

  • Häufig wird ein einzelner Microservice durch mehrere Kubernetes-Objekte definiert.Often a single microservice is defined by multiple Kubernetes objects. Helm ermöglicht das Verpacken dieser Objekte in einem einzelnen Helm-Chart.Helm allows these objects to be packaged into a single Helm chart.
  • Ein Chart kann mit einem einzelnen Helm-Befehl statt einer Reihe von kubectl-Befehlen bereitgestellt werden.A chart can be deployed with a single Helm command, rather than a series of kubectl commands.
  • Charts enthalten eine explizite Versionsangabe.Charts are explicitly versioned. Verwenden Sie Helm, um eine Version zu veröffentlichen, Releases anzuzeigen und das Rollback zu einer früheren Version auszuführen.Use Helm to release a version, view releases, and roll back to a previous version. Nachverfolgen von Updates und Revisionen per semantischer Versionierung und möglicher Rollback auf eine vorherige VersionTracking updates and revisions, using semantic versioning, along with the ability to roll back to a previous version.
  • Helm-Charts verwenden Vorlagen zur Vermeidung von doppelten Informationen, z.B. Bezeichnungen und Selektoren, über viele Dateien hinweg.Helm charts use templates to avoid duplicating information, such as labels and selectors, across many files.
  • Helm kann Abhängigkeiten zwischen Charts verwalten.Helm can manage dependencies between charts.
  • Charts können in einem Helm-Repository gespeichert werden, beispielsweise in der Azure-Containerregistrierung, und in die Buildpipeline integriert werden.Charts can be stored in a Helm repository, such as Azure Container Registry, and integrated into the build pipeline.

Weitere Informationen zur Verwendung von Container Registry als Helm-Repository finden Sie unter Verwenden Sie Azure Container Registry als Helm-Repository für Ihre Anwendungsdiagramme.For more information about using Container Registry as a Helm repository, see Use Azure Container Registry as a Helm repository for your application charts.

Wichtig

Diese Funktion steht derzeit als Vorschau zur Verfügung.This feature is currently in preview. Vorschauversionen werden Ihnen zur Verfügung gestellt, wenn Sie die zusätzlichen Nutzungsbedingungen akzeptieren.Previews are made available to you on the condition that you agree to the supplemental terms of use. Einige Aspekte dieses Features werden bis zur allgemeinen Verfügbarkeit unter Umständen noch geändert.Some aspects of this feature may change prior to general availability (GA).

Bei einem einzelnen Microservice können mehrere Kubernetes-Konfigurationsdateien im Spiel sein.A single microservice may involve multiple Kubernetes configuration files. Das Aktualisieren eines Diensts kann bedeuten, dass alle diese Dateien bearbeitet werden müssen, um Selektoren, Bezeichnungen und Imagetags zu aktualisieren.Updating a service can mean touching all of these files to update selectors, labels, and image tags. Helm behandelt diese als einzelnes Paket, das Chart genannt wird und es Ihnen ermöglicht, die YAML-Dateien mithilfe von Variablen komfortabel zu aktualisieren.Helm treats these as a single package called a chart and allows you to easily update the YAML files by using variables. Helm verwendet eine Vorlagensprache (die auf Go-Vorlagen beruht), um Ihnen das Schreiben von parametrisierten YAML-Konfigurationsdateien zu ermöglichen.Helm uses a template language (based on Go templates) to let you write parameterized YAML configuration files.

Dies ist beispielsweise ein Teil einer YAML-Datei, die eine Bereitstellung definiert:For example, here's part of a YAML file that defines a deployment:

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: {{ include "package.fullname" . | replace "." "" }}
  labels:
    app.kubernetes.io/name: {{ include "package.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
  annotations:
    kubernetes.io/change-cause: {{ .Values.reason }}

...

  spec:
      containers:
      - name: &package-container_name fabrikam-package
        image: {{ .Values.dockerregistry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        env:
        - name: LOG_LEVEL
          value: {{ .Values.log.level }}

⮚ Sehen Sie dazu die Quelldatei.⮚ See the source file.

Sie können sehen, dass für den Bereitstellungsnamen, die Bezeichnungen und die Containerspezifikation sämtlich Vorlagenparameter verwendet werden, die zum Zeitpunkt der Bereitstellung zur Verfügung gestellt werden.You can see that the deployment name, labels, and container spec all use template parameters, which are provided at deployment time. Beispielsweise an der Befehlszeile:For example, from the command line:

helm install $HELM_CHARTS/package/ \
     --set image.tag=0.1.0 \
     --set image.repository=package \
     --set dockerregistry=$ACR_SERVER \
     --namespace backend \
     --name package-v0.1.0

Zwar könnte Ihre CI/CD-Pipeline ein Chart direkt in Kubernetes installieren, wir empfehlen jedoch, ein Chartarchiv (TGZ-Datei) zu erstellen und das Chart per Push in ein Helm-Repository zu übertragen, wie etwa die Azure-Containerregistrierung.Although your CI/CD pipeline could install a chart directly to Kubernetes, we recommend creating a chart archive (.tgz file) and pushing the chart to a Helm repository such as Azure Container Registry. Weitere Informationen finden Sie unter Package Docker-based apps in Helm charts in Azure Pipelines (Verpacken von Docker-basierten Apps in Helm-Charts in Azure Pipelines).For more information, see Package Docker-based apps in Helm charts in Azure Pipelines.

Erwägen Sie, Helm in seinem eigenen Namespace bereitzustellen und RBAC (rollenbasierte Zugriffssteuerung) zu verwenden, um die Namespaces für die Bereitstellung einzuschränken.Consider deploying Helm to its own namespace and using role-based access control (RBAC) to restrict which namespaces it can deploy to. Weitere Informationen finden Sie in der Helm-Dokumentation zur rollenbasierten Zugriffssteuerung.For more information, see Role-based Access Control in the Helm documentation.

RevisionenRevisions

Helm-Charts weisen immer eine Versionsnummer auf, die semantische Versionierung befolgen muss.Helm charts always have a version number, which must use semantic versioning. Ein Chart kann außerdem eine appVersion aufweisen.A chart can also have an appVersion. Dieses Feld ist optional und muss nicht auf die Chartversion bezogen sein.This field is optional, and doesn't have to be related to the chart version. Für manche Teams kann es sinnvoll sein, die Version von Anwendungen separat von Chartaktualisierungen zu verwalten.Some teams might want to application versions separately from updates to the charts. Es ist jedoch einfacher, nur eine Versionsnummer zu verwenden, so dass eine 1:1-Beziehung zwischen der Chartversion und der Anwendungsversion besteht.But a simpler approach is to use one version number, so there's a 1:1 relation between chart version and application version. Auf diese Weise können Sie ein Chart pro Release speichern und das gewünschte Release komfortabel bereitstellen:That way, you can store one chart per release and easily deploy the desired release:

helm install <package-chart-name> --version <desiredVersion>

Eine weitere bewährte Methode besteht im Angeben einer Anmerkung für den Änderungsgrund in der Bereitstellungsvorlage:Another good practice is to provide a change-cause annotation in the deployment template:

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: {{ include "delivery.fullname" . | replace "." "" }}
  labels:
     ...
  annotations:
    kubernetes.io/change-cause: {{ .Values.reason }}

Auf diese Weise können Sie mithilfe des Befehls kubectl rollout history das Feld mit dem Änderungsgrund für jede Revision anzeigen.This lets you view the change-cause field for each revision, using the kubectl rollout history command. Im vorherigen Beispiel wird der Änderungsgrund als Helm-Chartparameter bereitgestellt.In the previous example, the change-cause is provided as a Helm chart parameter.

$ kubectl rollout history deployments/delivery-v010 -n backend
deployment.extensions/delivery-v010
REVISION  CHANGE-CAUSE
1         Initial deployment

Sie können aber auch den Befehl helm list verwenden, um den Revisionsverlauf anzuzeigen:You can also use the helm list command to view the revision history:

~$ helm list
NAME            REVISION    UPDATED                     STATUS        CHART            APP VERSION     NAMESPACE
delivery-v0.1.0 1           Sun Apr  7 00:25:30 2019    DEPLOYED      delivery-v0.1.0  v0.1.0          backend

Tipp

Verwenden Sie beim Initialisieren von Helm das --history-max-Flag.Use the --history-max flag when initializing Helm. Diese Einstellung schränkt die Anzahl der Revisionen ein, die Tiller in seinem Verlauf speichert.This setting limits the number of revisions that Tiller saves in its history. Tiller speichert den Revisionsverlauf in Konfigurationskarten.Tiller stores revision history in configmaps. Wenn Sie häufig Aktualisierungen veröffentlichen, können die Konfigurationskarten sehr groß werden, sofern Sie die Verlaufsgröße nicht beschränken.If you're releasing updates frequently, the configmaps can grow very large unless you limit the history size.

Azure DevOps-PipelineAzure DevOps Pipeline

In Azure Pipelines wird zwischen Buildpipelines und Releasepipelines unterschieden.In Azure Pipelines, pipelines are divided into build pipelines and release pipelines. Die Buildpipeline führt den CI-Prozess aus und erstellt Buildartefakte.The build pipeline runs the CI process and creates build artifacts. Für eine Microservicearchitektur in Kubernetes sind diese Artefakte die Containerimages und Helm-Charts, die jeden Microservice definieren.For a microservices architecture on Kubernetes, these artifacts are the container images and Helm charts that define each microservice. Die Releasepipeline führt den CD-Prozess aus, der einen Microservice in einem Cluster bereitstellt.The release pipeline runs that CD process that deploys a microservice into a cluster.

Aufbauend auf dem weiter oben in diesem Artikel beschriebenen CI-Flow, kann eine Buildpipeline aus den folgenden Aufgaben bestehen:Based on the CI flow described earlier in this article, a build pipeline might consist of the following tasks:

  1. Erstellen des Test Runner-Containers.Build the test runner container.

    - task: Docker@1
      inputs:
        azureSubscriptionEndpoint: $(AzureSubscription)
        azureContainerRegistry: $(AzureContainerRegistry)
        arguments: '--pull --target testrunner'
        dockerFile: $(System.DefaultWorkingDirectory)/$(dockerFileName)
        imageName: '$(imageName)-test'
    
  2. Ausführen der Tests durch Aufrufen der Docker-Ausführung für den Test Runner-Container.Run the tests, by invoking docker run against the test runner container.

    - task: Docker@1
      inputs:
        azureSubscriptionEndpoint: $(AzureSubscription)
        azureContainerRegistry: $(AzureContainerRegistry)
        command: 'run'
        containerName: testrunner
        volumes: '$(System.DefaultWorkingDirectory)/TestResults:/app/tests/TestResults'
        imageName: '$(imageName)-test'
        runInBackground: false
    
  3. Veröffentlichen der Testergebnisse.Publish the test results. Siehe Erstellen eines Images.See Build an image.

    - task: PublishTestResults@2
      inputs:
        testResultsFormat: 'VSTest'
        testResultsFiles: 'TestResults/*.trx'
        searchFolder: '$(System.DefaultWorkingDirectory)'
        publishRunAttachments: true
    
  4. Erstellen Sie den Runtimecontainer.Build the runtime container.

    - task: Docker@1
      inputs:
        azureSubscriptionEndpoint: $(AzureSubscription)
        azureContainerRegistry: $(AzureContainerRegistry)
        dockerFile: $(System.DefaultWorkingDirectory)/$(dockerFileName)
        includeLatestTag: false
        imageName: '$(imageName)'
    
  5. Übertragen Sie per Push aus der Azure-Containerregistrierung (oder einer anderen Containerregistrierung) in den Container.Push to the container to Azure Container Registry (or other container registry).

    - task: Docker@1
      inputs:
        azureSubscriptionEndpoint: $(AzureSubscription)
        azureContainerRegistry: $(AzureContainerRegistry)
        command: 'Push an image'
        imageName: '$(imageName)'
        includeSourceTags: false
    
  6. Verpacken Sie das Helm-Chart.Package the Helm chart.

    - task: HelmDeploy@0
      inputs:
        command: package
        chartPath: $(chartPath)
        chartVersion: $(Build.SourceBranchName)
        arguments: '--app-version $(Build.SourceBranchName)'
    
  7. Übertragen Sie das Helm-Paket in die Azure-Containerregistrierung (oder ein anderes Helm-Repository).Push the Helm package to Azure Container Registry (or other Helm repository).

    task: AzureCLI@1
      inputs:
        azureSubscription: $(AzureSubscription)
        scriptLocation: inlineScript
        inlineScript: |
        az acr helm push $(System.ArtifactsDirectory)/$(repositoryName)-$(Build.SourceBranchName).tgz --name $(AzureContainerRegistry);
    

⮚ Sehen Sie dazu die Quelldatei.⮚ See the source file.

Die Ausgabe der CI-Pipeline ist ein produktionsbereites Containerimage und ein aktualisiertes Helm-Chart für den Microservice.The output from the CI pipeline is a production-ready container image and an updated Helm chart for the microservice. An diesem Punkt kann die Releasepipeline übernehmen.At this point, the release pipeline can take over. Sie führt die folgenden Schritte aus:It performs the following steps:

  • Bereitstellen in den DEV-/QA-/Stagingumgebungen.Deploy to dev/QA/staging environments.
  • Warten auf eine genehmigende Person, die die Bereitstellung genehmigt oder ablehnt.Wait for an approver to approve or reject the deployment.
  • Zuordnen eines neuen Tags zum Containerimage für das ReleaseRetag the container image for release
  • Übertragen Sie das Releasetag per Push in die Containerregistrierung.Push the release tag to the container registry.
  • Aktualisieren Sie das Helm-Chart im Produktionscluster.Upgrade the Helm chart in the production cluster.

Weitere Informationen zum Erstellen einer Releasepipeline finden Sie unter Release pipelines, draft releases, and release options (Releasepipelines, Entwurfsreleases und Releaseoptionen).For more information about creating a release pipeline, see Release pipelines, draft releases, and release options.

Im folgenden Diagramm ist der in diesem Artikel beschriebene End-to-End-CI/CD--Prozess dargestellt:The following diagram shows the end-to-end CI/CD process described in this article:

CI/CD-Pipeline

Nächste SchritteNext steps

Dieser Artikel basiert auf einer Referenzimplementierung, die Sie auf GitHub finden können.This article was based on a reference implementation that you can find on GitHub.