Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Erstellung eines zuverlässigen kontinuierlichen Integrationsprozesses und eines CI/CD-Prozesses für eine Microservices-Architektur kann eine Herausforderung darstellen. Jedes Team muss Dienste schnell und zuverlässig freigeben, ohne andere Teams zu stören oder die Anwendung als Ganzes zu destabilisieren.
In diesem Artikel wird ein Beispiel für eine CI/CD-Pipeline für die Bereitstellung von Microservices in Azure Kubernetes Service (AKS) beschrieben. Jedes Team und jedes Projekt ist anders, daher sollten Sie diesen Artikel nicht als feststehende Sammlung unverrückbarer Regeln verstehen. Verwenden Sie es stattdessen als Ausgangspunkt für das Entwerfen Ihres eigenen CI/CD-Prozesses.
Die folgende Liste fasst die Ziele einer CI/CD-Pipeline für Kubernetes gehostete Microservices zusammen:
- Teams können ihre Dienste unabhängig voneinander entwickeln und bereitstellen.
- Codeänderungen, die den CI-Prozess übergeben, werden automatisch in einer produktionsähnlichen Umgebung bereitgestellt.
- Jede Phase der Pipeline erzwingt Qualitätstore.
- Eine neue Version eines Diensts kann parallel zur vorherigen Version bereitgestellt werden.
Weitere Informationen finden Sie unter CI/CD für Microservices-Architekturen.
Annahmen
In diesem Beispiel sind einige Annahmen über das Entwicklungsteam und die Codebasis aufgeführt:
- Für das Coderepository wird der Monorepo-Ansatz genutzt, und die Ordner sind nach Microservice organisiert.
- Die Branchstrategie des Teams basiert auf der trunkbasierten Entwicklung.
- Das Team verwendet Releasebranches zur Verwaltung von Releases. Für jeden Microservice werden separate Releases erstellt.
- Der CI/CD-Prozess verwendet Azure Pipelines zum Erstellen, Testen und Bereitstellen der Microservices in AKS.
- Die Containerimages für alle Microservices werden in einer einzigen, freigegebenen Azure Container Registry Instanz mit einem separaten Repository für jeden Microservice gespeichert. Verwenden Sie containerregistrierung Azure ABAC-Repositoryberechtigungen, um jede Pipelineidentität auf ihr eigenes Repository zu beschränken, oder verwenden Sie separate Registrierungen, bei denen stärkere Vertrauensgrenzen erforderlich sind.
- Das Team verwendet Helm-Charts, um die Microservices zu verpacken.
- Es wird ein Pushbereitstellungsmodell verwendet, bei dem Azure Pipelines und zugehörigen Agents Bereitstellungen ausführen, indem eine direkte Verbindung mit dem AKS-Cluster hergestellt wird.
Diese Annahmen bestimmen viele der spezifischen Details der CI/CD-Pipeline. Sie können jedoch den hier beschriebenen grundlegenden Ansatz für andere Prozesse, Tools und Dienste wie GitHub Actions, Jenkins oder Docker Hub anpassen.
Alternatives
Wenn Sie eine CI/CD-Strategie mit AKS auswählen, sollten Sie die folgenden gängigen Alternativen in Betracht ziehen:
Anstatt Helm als Paketverwaltungs- und Bereitstellungstool zu verwenden, können Sie Kustomize verwenden, ein Kubernetes-systemeigenes Konfigurationsverwaltungstool, mit dem eine vorlagenfreie Möglichkeit zum Anpassen und Parametrisieren der Anwendungskonfiguration eingeführt wird.
Anstatt Azure DevOps für Git-Repositorys und -Pipelines zu verwenden, können Sie GitHub Repositorys für private und öffentliche Git-Repositorys und GitHub Actions für CI/CD-Pipelines verwenden.
GitHub Actions bietet die Integration mit AKS mit Startworkflows und unterstützt OpenID Connect (OIDC) für sichere, geheime Authentifizierung zum Azure.
Anstatt ein Pushbereitstellungsmodell zu verwenden, sollten Sie die Kubernetes-Konfiguration im großen Maßstab mithilfe eines GitOps -Bereitstellungsmodells (Pull-Bereitstellungsmodell) verwalten. Ein In-Cluster Kubernetes-Operator wie Flux oder Argo CD synchronisiert den Clusterzustand basierend auf der Konfiguration, die in einem Git-Repository gespeichert ist. GitOps beseitigt die Notwendigkeit, dass Pipelines direkten Clusterzugriff haben, die Angriffsfläche reduzieren und Selbstheilungs- und Drifterkennungsfunktionen bieten.
Tip
Berücksichtigen Sie bei der Auswertung von Push-basierten Bereitstellungsmodellen (Pull-based, GitOps) Ihre Workloadanforderungen. Pushbasierte Bereitstellungen bieten deterministische Updates und direkte Pipelinesteuerung, die für sichere Bereitstellungsmethoden geeignet ist. Pull-basierte Bereitstellungen (GitOps) bieten Konsistenz, Auditierbarkeit und Self-Healing, was sie ideal für Umgebungen macht, in denen Cluster mit einem gewünschten Zustand ohne direkten Pipeline-zu-Cluster-Zugriff in Einklang gebracht werden müssen.
Validierungsbuilds
Angenommen, ein Entwickler arbeitet an einem Microservice namens Delivery Service. Beim Entwickeln eines neuen Features überprüft der Entwickler Code in einen Featurezweig. In der Regel werden Feature-Branches gemäß der Benennungskonvention feature/* benannt.
Das Diagramm zeigt zwei horizontale Git-Verzweigungslinien und eine Buildpipeline darunter. Oben befindet sich der Hauptzweig, der als horizontale Linie dargestellt wird. Die Funktion/8150-Verzweigung unterscheidet sich vom Hauptteil. Diese Verzweigung hat drei Punkte, die zusammen mit Beschriftungen versehen sind. Von jedem der drei Commits zeigt ein Pfeil nach unten auf ein Feld am unteren Rand des Diagramms. Das Feld ist mit der Bezeichnung Buildpipeline versehen und enthält den Pipelinenamen ci-delivery-validation. Alle drei gestrichelten Pfeile werden in diesem einzigen Buildpipelinefeld zusammengeführt, das angibt, dass jeder Commit an das Feature/8150-Verzweigung eine Ausführung der Ci-Delivery-Validation-Pipeline auslöst.
Die Builddefinitionsdatei enthält einen Trigger, der nach dem Branchnamen und dem Quellpfad filtert:
trigger:
batch: true
branches:
include:
# for new release to production: release flow strategy
- release/delivery/v*
- refs/release/delivery/v*
- main
- feature/delivery/*
- topic/delivery/*
paths:
include:
- /src/shipping/delivery/
Wenn Sie diesen Ansatz verwenden, kann jedes Team über eine eigene Buildpipeline verfügen. Nur Code, der in den /src/shipping/delivery Ordner eingecheckt ist, löst einen Build des Übermittlungsdiensts aus. Das Pushen von Commits auf einen Branch, der mit dem Filter übereinstimmt, löst einen CI-Build aus. An diesem Punkt des Workflows führt der CI-Build eine Codeüberprüfung mit minimalem Umfang durch:
- Erstellen des Codes.
- Ausführen von Komponententests.
Das Ziel besteht darin, die Buildzeiten kurz zu halten, damit der Entwickler schnell Feedback erhält. Wenn das Feature zur Hauptzusammenführung bereit ist, öffnet der Entwickler eine PR. Durch diesen Vorgang wird ein weiterer CI-Build ausgelöst, bei dem einige zusätzliche Überprüfungen durchgeführt werden:
- Erstellen des Codes.
- Ausführen von Komponententests.
- Führen Sie statische Anwendungssicherheitstests (SAST) im Quellcode aus.
- Erstelle das ausführbare Container-Image.
- Schwachstellen-Scans für das Image durchführen.
Das Diagramm zeigt zwei horizontale Git-Verzweigungslinien und eine Buildpipeline darunter. Oben befindet sich der Hauptzweig, der als horizontale Linie dargestellt wird. Darunter wird die Funktion/8150-Verzweigung parallel ausgeführt und weist drei Punkte darauf auf, die Commits darstellen. Am rechten Ende der Funktion/8150 Verzweigung verbindet sich ein gestrichelter Pfeil mit einem Punkt auf der Hauptzweige. Dieser Punkt ist mit einem anderen Punkt markiert, der als PR bezeichnet wird und angibt, dass eine Pullanforderung für den Hauptteil geöffnet wurde. Vom PR-Punkt auf der Hauptverzweigung zeigt ein gestrichelter Pfeil nach unten auf eine boxbeschriftete Buildpipeline, die den Pipelinenamen ci-delivery-full enthält. Diese Zeile veranschaulicht, dass das Öffnen einer Pullanforderung aus der Featureverzweigung zum Hauptauslöser der ci-delivery-full-Pipeline führt, die den erweiterten Satz von CI-Prüfungen ausführt.
Hinweis
In Azure Repos können Sie eines der Dienste in Azure DevOps definieren, um Filialen zu schützen. Die Richtlinie kann z. B. einen erfolgreichen CI-Build und eine Abmeldung von einem Genehmigenden erfordern, bevor eine Zusammenführung in den Hauptvorgang erfolgt.
Vollständiger CI/CD-Build
Wenn das Team bereit ist, eine neue Version des Zustellungsdiensts bereitzustellen, erstellt der Release-Manager eine Verzweigung aus der Hauptzweigung, wobei dieses Benennungsmuster verwendet wird: release/<microservice name>/<semver> Beispiel: release/delivery/v1.0.2
Das Diagramm zeigt drei horizontale Git-Verzweigungslinien und zwei Pipelines darunter. In der Mitte befindet sich der Hauptzweig, der als horizontale Linie dargestellt wird. Unterhalb des Hauptteils befindet sich das Feature/8150-Verzweigung, das drei Punkte enthält, die Commits darstellen. Die Funktion/8150-Verzweigung stellt eine Verbindung mit der Hauptzweigung an einem Punkt mit Bezeichnung zusammen, der angibt, dass die Feature-Verzweigung mit dem Hauptteil zusammengeführt wird. Oben und rechts neben der Hauptverzweigung erstreckt sich rechts eine neue Verzweigung mit der Bezeichnung Release/Delivery/v1.0.2. Diese Release-Verzweigung stammt von der Hauptstelle rechts neben dem Seriendruck. Von der Release/Delivery/v1.0.2-Verzweigung zeigt eine gestrichelte Linie nach unten auf eine Box mit der Bezeichnung ci-delivery-full, die sich oberhalb der Etikettenbuildpipeline befindet. Rechts neben ci-delivery-full zeigt ein horizontaler Pfeil auf eine zweite boxbeschriftete CD-Lieferung, die sich oberhalb der Etikettenversionspipeline befindet.
Durch das Erstellen dieser Verzweigung wird ein vollständiger CI-Build ausgelöst, der alle vorherigen Schritte und die folgenden Schritte ausführt:
- Verschieben Sie das Containerimage in die Containerregistrierung. Das Bild wird mit der Versionsnummer im Verzweigungsnamen markiert.
- Führen Sie
helm packageaus, um das Helm-Chart für den Dienst zu verpacken. Das Chart ist außerdem mit einer Versionsnummer gekennzeichnet. - Übertragen des Helm-Pakets an die Containerregistrierung per Push.
Wenn dieser Build erfolgreich ist, löst er einen Bereitstellungsprozess (CD) mithilfe einer Azure Pipelines Releasepipeline aus. Diese Pipeline enthält die folgenden Schritte:
- Bereitstellen des Helm-Charts in einer QA-Umgebung.
- Bevor das Paket in die Produktion geht, stimmt eine genehmigende Person zu. Weitere Informationen finden Sie unter Steuerung von Releasebereitstellungen durch Genehmigungen.
- Retagieren Sie das Docker-Image für den Produktionsnamespace in der Containerregistrierung. Wenn das aktuelle Tag beispielsweise
myrepo.azurecr.io/delivery:v1.0.2ist, lautet das Produktionstagmyrepo.azurecr.io/prod/delivery:v1.0.2. - Stellen Sie das Helm-Chart in der Produktionsumgebung bereit.
Auch in einem Monorepo können Sie diese Aufgaben auf einzelne Microservices beschränken, damit Teams unabhängig bereitstellen können. Der Prozess umfasst einige manuelle Schritte: Genehmigen von PRs, Erstellen von Release-Verzweigungen und Genehmigen von Bereitstellungen im Produktionscluster. Workloadteams können diese Schritte automatisieren, wenn sie möchten.
Isolation von Umgebungen
Sie stellen Dienste in mehreren Umgebungen bereit, einschließlich Umgebungen für Entwicklung, Rauchtests, Integrationstests, Auslastungstests und Produktion. Für diese Umgebungen ist ein gewisses Maß an Isolation erforderlich. In Kubernetes können Sie zwischen physischer Isolation und logischer Isolation wählen. Physische Isolation wird für separate Cluster bereitgestellt. Die logische Isolierung verwendet Namespaces und Richtlinien.
Unsere Empfehlung besteht darin, einen dedizierten Produktionscluster zusammen mit einem separaten Cluster für Ihre Entwicklungs-/Testumgebungen zu erstellen. Verwenden Sie die logische Isolation, um Umgebungen im Entwicklungs-/Testcluster zu trennen. Im Entwicklungs-/Testcluster bereitgestellte Dienste sollten niemals Zugriff auf Datenspeicher haben, in denen sich Geschäftsdaten befinden.
Führen Sie die folgenden Schritte aus, um die Isolation innerhalb eines Clusters zu erzwingen:
-
Namespaces: Verwenden Sie Kubernetes-Namespaces, um logische Umgebungen zu trennen (z
dev. B. , ,staging).qa - Netzwerkrichtlinien: Wenden Sie Kubernetes-Netzwerkrichtlinien an, um die Pod-zu-Pod-Kommunikation über Namespaces hinweg zu verweigern.
- Ressourcenkontingente: Wenden Sie Ressourcenkontingente pro Namespace an, um Probleme mit lauten Nachbarn in freigegebenen Clustern zu verhindern.
- Microsoft Entra ID Integration: Kombinieren Sie Microsoft Entra ID Authentifizierung mit Kubernetes RBAC und Microsoft Entra ID, um zu steuern, welche Microsoft Entra Benutzer und Gruppen auf jeden Namespace zugreifen können.
Authentifizierung und Autorisierung
Verwenden Sie nach Möglichkeit die geheime Authentifizierung sowohl für die Pipelines, die Ihre Microservices bereitstellen, als auch für die Workloads, die diese Pipelines bereitstellen:
- Workload identity federation for pipelines: For Azure Pipelines, use a workload identity federation service connection to authenticate to Azure without speicher long-lived service principal secrets. Konfigurieren Sie für GitHub Actions OIDC, um die gleiche geheime Authentifizierung zu erzielen.
- Microsoft Entra Workload ID für bereitgestellte Workloads: Konfigurieren Sie die Mikroservices, die Ihre Pipeline bereitstellt, um Microsoft Entra Workload ID zu verwenden, anstatt Anmeldeinformationen über Manifeste, Helmwerte oder Kubernetes-Schlüssel einzugeben. Die Workload-ID verknüpft Kubernetes-Dienstkonten mit Microsoft Entra ID, sodass pods sich bei Azure Diensten (z. B. Azure Key Vault, Containerregistrierung oder Azure SQL) authentifizieren können, ohne dass die Pipeline geheime Schlüssel verwaltet.
Geheimnisverwaltung
Nie geheime Schlüssel (Verbindungszeichenfolgen, API-Schlüssel, Datenbank-Kennwörter) direkt in Quellcode, Dockerfiles, Helm-Wertedateien oder Pipelinedefinitionen einbetten. Stattdessen:
- Speichern Sie geheime Schlüssel im Key Vault.
- Verwenden Sie den Key Vault Provider for Secrets Store CSI Driver, um geheime Schlüssel direkt in Pods als Volumes oder Umgebungsvariablen bereitzustellen. Dieser Ansatz bewahrt geheime Schlüssel von Kubernetes-Objekten
Secretauf, die base64-codiert und standardmäßig nicht verschlüsselt sind. - Verwenden Sie für geheime Pipelineschlüssel Key Vault Integration mit Azure Pipelines oder GitHub Actions geheimen Schlüsseln.
- Aktivieren Sie Key Vault vorläufigen Lösch- und Löschschutz, um vor versehentlichem oder böswilligen geheimen Löschvorgang zu schützen.
Important
Vermeiden Sie das Speichern langlebiger Anmeldeinformationen (geheime Clientschlüssel, Zertifikate oder Kennwörter) in Pipelinevariablen, Umgebungsvariablen oder Kubernetes-Schlüsseln. Verwenden Sie stattdessen verwaltete Identitäten und Verbundanmeldeinformationen, um die Drehung der Anmeldeinformationen und die Angriffsfläche zu verringern.
Erstellungsprozess
Verpacken Sie nach Möglichkeit Ihren Buildprozess in einem Docker-Container. Mit dieser Konfiguration können Sie Codeartefakte mithilfe von Docker erstellen, ohne eine Buildumgebung auf jedem Buildcomputer zu konfigurieren. Ein containerisierter Buildprozess vereinfacht das Skalieren der CI-Pipeline durch Hinzufügen neuer Build-Agents. Außerdem kann jeder Entwickler im Team den Code erstellen, indem er den Buildcontainer ausführt.
Mithilfe von Multistage-Builds in Docker können Sie die Buildumgebung und das Laufzeitimage in einer einzelnen Dockerfile-Datei definieren. Beispielsweise erstellt die folgende Dockerfile-Datei eine .NET 10-Anwendung:
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:10.0 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/build --no-restore
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"]
FROM build AS publish
RUN dotnet publish Fabrikam.Workflow.Service.csproj -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Fabrikam.Workflow.Service.dll"]
Dieses Dockerfile definiert mehrere Buildphasen. Beachten Sie, dass die benannte Phase das .NET 10 ASP.NET Laufzeitimage verwendet, während die benannte basebuild Phase das vollständige .NET 10 SDK verwendet. In der build Phase wird das .NET Projekt erstellt. 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.
Important
Ab .NET 8 enthalten offizielle Linux-basierte .NET Containerimages einen Nicht-Root-Benutzer, der aufgerufen wirdapp. Die USER app Anweisung in der Dockerfile-Datei führt den Container als dieser nicht privilegierte Benutzer aus, und zwar nach dem Prinzip der geringsten Rechte. ASP.NET Core Containerimages haben auch ihren Standard-Überwachungsport von 80 auf 8080 geändert.
Erstellen eines Test Runners
Eine weitere bewährte Methode ist das Ausführen von Komponententests im Container. Der folgende Code zeigt beispielsweise einen Teil einer Dockerfile-Datei, die einen Testläufer erstellt:
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 Dockerfile-Datei verwenden, um die Tests lokal auszuführen:
docker build . -t delivery-test:1 --target=testrunner
docker run delivery-test:1
Die CI-Pipeline sollte die Tests ebenfalls im Rahmen des Build-Verifizierungsschritts ausführen.
Diese Datei verwendet den Docker-Befehl ENTRYPOINT , nicht den Docker-Befehl RUN , um die Tests auszuführen.
- Wenn Sie den Befehl
RUNverwenden, werden die Tests jedes Mal ausgeführt, wenn Sie das Image erstellen. Wenn Sie dies verwendenENTRYPOINT, sind die Tests opt-in. Sie werden nur ausgeführt, wenn Sie die Phasetestrunnerexplizit ansteuern. - Ein Fehler im Test führt nicht zu einem Fehler beim Docker-Befehl
build. Mit diesem Verhalten können Sie Containerbuildfehler von Testfehlern unterscheiden. - Testergebnisse können auf einem eingebundenen Volume gespeichert werden.
Bewährte Praktiken für Container
Hier sind einige weitere bewährte Methoden, die beim Arbeiten mit Containern berücksichtigt werden sollten:
- Definieren Sie organisationsweite Konventionen für Containertags, Versionsverwaltung und Benennungskonventionen für Ressourcen, die im Cluster bereitgestellt werden (z. B. Pods und Dienste). Die Verwendung dieser Konventionen erleichtert die Diagnose von Bereitstellungsproblemen.
- Während des Entwicklungs- und Testzyklus erstellt der CI/CD-Prozess viele Containerimages. Nur einige dieser Bilder sind Kandidaten für die Veröffentlichung, und nur einige dieser Releasekandidaten werden zur Produktion heraufgestuft. Verfügen Sie über eine klare Versionsverwaltungsstrategie, damit Sie wissen, welche Images zurzeit in der Produktion bereitgestellt werden und bei Bedarf problemlos auf eine frühere Version zurückwechseln können.
- Stellen Sie immer spezifische Containerversionstags bereit, nicht einfach
latest. - Verwenden Sie Namespaces in der Containerregistrierung, um Bilder zu isolieren , die für die Produktion von Noch getesteten Images genehmigt wurden. Verschieben Sie ein Image nur dann in den Produktions-Namespace, wenn Sie bereit sind, es in der Produktion einzusetzen. Durch die Kombination dieser Vorgehensweise mit der semantischen Versionsverwaltung von Containerimages kann die Wahrscheinlichkeit reduziert werden, dass versehentlich eine Version bereitgestellt wird, die nicht für die Veröffentlichung genehmigt wurde.
- Befolgen Sie das Prinzip der geringsten Rechte, indem Sie Container als Benutzer ohne besondere Rechte ausführen. Verwenden Sie in Kubernetes pod Security Standards mit pod Security Admission (die die veralteten Pod-Sicherheitsrichtlinien in Kubernetes 1.25 ersetzt haben), um Einschränkungen wie das Verhindern der Ausführung von Containern als Stamm zu erzwingen. Verwenden Sie das
restrictedProfil für Produktionsworkloads. - Verwenden Sie minimale oder unerlässige Basisimages (z. B. alpine basierte Bilder, Azure Linux-Basis oder distrolose Bilder oder chiselierte .NET Images), um die Angriffsfläche Ihrer Containerimages zu reduzieren.
- Konfigurieren Sie für Premium-Registrierungen eine Aufbewahrungsrichtlinie für die Containerregistrierung , um nicht markierte Manifeste zu löschen. Um Tags nach Alter oder Name zu löschen, planen Sie eine Containerregistrierungsaufgabe, die ein Löschvorgang ausführt. Beibehalten von Images, auf die aktive Bereitstellungen und Rollbackpläne verwiesen werden.
Helm-Diagramme
Erwägen Sie, das Tool Helm für das Entwickeln und Implementieren von Diensten zu nutzen. Die folgenden Helm-Funktionen unterstützen eine CI/CD-Pipeline:
- Ein einzelner Microservice wird häufig durch mehrere Kubernetes-Objekte definiert. Helm ermöglicht es, diese Objekte in ein einzelnes Helm-Diagramm zu packen.
- Sie können ein Diagramm mithilfe eines einzigen Helmbefehls anstelle einer Reihe von Kubectl-Befehlen bereitstellen.
- Charts enthalten eine explizite Versionsangabe. Verwenden Sie Helm, um eine Version zu veröffentlichen, Releases anzuzeigen und das Rollback zu einer früheren Version auszuführen. Helm verwendet die semantische Versionsverwaltung zum Nachverfolgen von Updates und Überarbeitungen.
- Helm-Charts verwenden Vorlagen, um Informationen wie Labels und Selektoren nicht über viele Dateien hinweg zu duplizieren.
- Helm kann Abhängigkeiten zwischen Charts verwalten.
- Sie können Diagramme in einem Helm-Repository, z. B. der Containerregistrierung, speichern und in die Buildpipeline integrieren.
Weitere Informationen finden Sie unter Verwenden der Containerregistrierung als Helmrepository für Ihre Anwendungsdiagramme.
Ein einzelner Microservice erfordert möglicherweise mehrere Kubernetes-Konfigurationsdateien. Um einen Dienst zu aktualisieren, müssen Sie möglicherweise alle diese Dateien bearbeiten, um Selektoren, Bezeichnungen und Bildtags zu aktualisieren. Helm behandelt diese Dateien als einzelnes Paket, das als Diagramm bezeichnet wird, und erleichtert das Aktualisieren der YAML-Dateien mithilfe von Variablen. Helm verwendet eine Vorlagensprache (basierend auf Go-Vorlagen), mit der Sie parametrisierte YAML-Konfigurationsdateien schreiben können.
Dies ist beispielsweise ein Teil einer YAML-Datei, die eine Bereitstellung definiert:
apiVersion: apps/v1
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:
template:
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 }}
Sie können sehen, dass der Bereitstellungsname, die Bezeichnungen und der Container alle Vorlagenparameter verwenden, die Sie zur Bereitstellungszeit bereitstellen. Beispielsweise in der Befehlszeile:
helm install <release-name> oci://<registry>/<repository>/<package-chart-name> --version <desiredVersion> \
--set image.tag=0.1.0 \
--set image.repository=package \
--set dockerregistry=$ACR_SERVER \
--namespace backend
Obwohl eine CI/CD-Pipeline ein Diagramm direkt in Kubernetes installieren kann, erstellen Sie ein Diagrammarchiv (TGZ-Datei), und verschieben Sie das Diagramm an ein Helm-Repository wie container Registry. Weitere Informationen finden Sie unter Packen und Bereitstellen von Helmdiagrammen (HelmDeploy-Aufgabe).
Revisions
Helmdiagramme verfügen immer über eine Versionsnummer, die die semantische Versionsverwaltung verwenden muss. Ein Diagramm kann außerdem ein appVersion enthalten. Dieses Feld ist optional und muss nicht mit der Diagrammversion verknüpft sein. Einige Teams möchten Anwendungen möglicherweise separat von Updates für die Diagramme versionsieren. Ein einfacherer Ansatz besteht darin, eine Versionsnummer zu verwenden. Daher gibt es eine Beziehung zwischen Diagrammversion und Anwendungsversion. Auf diese Weise können Sie ein Chart pro Release speichern und das gewünschte Release komfortabel bereitstellen:
helm install <package-chart-name> --version <desiredVersion>
Eine weitere bewährte Methode besteht im Angeben einer Anmerkung für den Änderungsgrund in der Bereitstellungsvorlage:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "delivery.fullname" . | replace "." "" }}
labels:
...
annotations:
kubernetes.io/change-cause: {{ .Values.reason }}
Mit dieser Anmerkung können Sie das Änderungsursachenfeld für jede Überarbeitung mithilfe des kubectl rollout history Befehls anzeigen. Im vorherigen Beispiel wird die Änderungsursache als Helm-Diagrammparameter bereitgestellt.
kubectl rollout history deployments/delivery-v010 -n backend
deployment.apps/delivery-v010
REVISION CHANGE-CAUSE
1 Initial deployment
Sie können aber auch den Befehl helm list verwenden, um den Revisionsverlauf anzuzeigen:
helm list -n backend
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
delivery-v0.1.0 backend 1 2024-04-07 00:25:30.000000 +0000 UTC deployed delivery-v0.1.0 v0.1.0
Azure Pipelines
Azure Pipelines verfügt ein Dienst in Azure DevOps über zwei Pipelinetypen: Buildpipelines und Releasepipelines. Die Build-Pipeline führt den CI-Prozess aus und erstellt Build-Artefakte. Für eine Microservicearchitektur in Kubernetes sind diese Artefakte die Containerimages und Helm-Charts, die jeden Microservice definieren. Die Releasepipeline führt den CD-Prozess aus, der einen Microservice in einem Cluster bereitstellt.
Aufbauend auf dem weiter oben in diesem Artikel beschriebenen CI-Flow, kann eine Buildpipeline aus den folgenden Aufgaben bestehen:
- Erstellen Sie den Testausführungscontainer mithilfe der
DockerAufgabe. - Führen Sie die Tests aus, indem Sie mithilfe der
DockerAufgabe den Testausführungscontainer aufrufendocker run. - Veröffentlichen Sie die Testergebnisse mithilfe der
PublishTestResultsAufgabe. Weitere Informationen finden Sie unter Erstellen eines Bilds. - Führen Sie SAST im Quellcode aus.
- Erstellen Sie den Laufzeitcontainer mithilfe lokaler
docker buildund derDockerAufgabe oder mithilfe von Containerregistrierungsbuilds und derAzureCLIAufgabe. Generieren Sie eine Softwareabrechnung von Materialien (SBOM) für das Bild, z. B. mithilfe des Microsoft SBOM-Tools, und veröffentlichen Sie sie als Pipelineartefakt, das dem Imagedigest zugeordnet ist, oder fügen Sie es an das Image in der Containerregistrierung an. - Führen Sie die Sicherheitsrisikoüberprüfung des Containerimages aus (z. B. mithilfe von Microsoft Defender für Container oder einem Tool ohne Microsoft wie Trivy), um bekannte Sicherheitsrisiken zu erkennen, bevor das Image veröffentlicht wird.
- Pushen Sie das Containerimage mithilfe der oder
AzureCLIder Aufgabe an dieDockerContainerregistrierung (oder eine andere Containerregistrierung). - Signieren Sie das pushte Bild durch unveränderlichen Digest, um die Integrität und Authentizität sicherzustellen. Folgen Sie für Azure Pipelines den Notation-Signaturanweisungen.
- Packen Sie das Helmdiagramm mithilfe der
HelmDeployAufgabe. - Pushen Sie das Helm-Paket mithilfe der Aufgabe an die
HelmDeployContainerregistrierung (oder ein anderes Helm-Repository).
Die Ausgabe der CI-Pipeline ist ein produktionsbereites Containerimage und ein aktualisiertes Helm-Chart für den Microservice. An diesem Punkt kann die Release-Pipeline übernehmen. Für jeden Microservice gibt es eine einzigartige Releasepipeline. Die Release-Pipeline wurde so konfiguriert, dass die Quelle des Triggers auf die CI-Pipeline festgelegt wurde, die das Artefakt veröffentlicht hat. Mit dieser Pipeline können Sie jeden Microservice unabhängig bereitstellen. Die Releasepipeline führt die folgenden Schritte aus:
- Stellen Sie das Helm-Diagramm für Entwicklungs-/QA/Staging-Umgebungen bereit. Sie können den
helm upgradeBefehl mit der--installKennzeichnung verwenden, um die erste Installation und nachfolgende Upgrades zu unterstützen. - Warten auf einen Genehmiger, der die Bereitstellung genehmigt oder ablehnt.
- Retagieren Sie das Containerimage für die Freigabe.
- Übertragen Sie das Releasetag per Push in die Containerregistrierung.
- Stellen Sie das Helm-Chart im Produktionscluster bereit. Verwenden Sie Ratify mit Azure Policy, um Bildsignaturen während der Zulassung zu überprüfen, und konfigurieren Sie separat eine Richtlinie für zulässige Bilder, um Bilder auf vertrauenswürdige Registrierungen einzuschränken.
Hinweis
Um AKS das Abrufen von Images aus der Containerregistrierung ohne separate Image-Pullschlüssel zu ermöglichen, verwenden Sie die AKS-to-Container-Registry-Integration für eine Registrierung, die registrierungsweite RBAC verwendet. Für eine ABAC-fähige Registrierung wird diese Integration nicht unterstützt. Weisen Sie stattdessen die Container Registry Repository Reader Rolle der kubeletverwalteten Identität des Clusters zu.
Weitere Informationen zum Erstellen einer Releasepipeline finden Sie unter Release pipelines, draft releases, and release options (Releasepipelines, Entwurfsreleases und Releaseoptionen).
Im folgenden Diagramm ist der in diesem Artikel beschriebene End-to-End-CI/CD--Prozess dargestellt:
GitHub Actions Alternative
Wenn Ihr Team GitHub für die Quellcodeverwaltung verwendet, stellt GitHub Actions eine entsprechende CI/CD-Plattform bereit. Berücksichtigen Sie zusätzlich zu den zuvor erwähnten Startworkflows und der OIDC-Authentifizierung diese GitHub spezifischen Funktionen, wenn Sie auf AKS abzielen:
- Umgebungen und Schutzregeln. Wenn Ihre GitHub Plan- und Repositorysichtbarkeit unterstützen, verwenden Sie GitHub Umgebungen mit erforderlichen Prüfern, Wartezeiten und Bereitstellungszweigen, um Genehmigungsgates zu implementieren.
- Containerüberprüfung. Verwenden Sie GitHub Actions Marketplace-Aktionen für Trivy, Microsoft Defender for DevOps oder ähnliche Tools zum Scannen von Containerimages direkt in Ihrem Workflow.
Observierbarkeit und Systemüberwachung
Implementieren Sie Die Observability in der gesamten CI/CD-Pipeline und Laufzeitumgebung:
- Pipelineüberwachung. Nachverfolgen von Builddauern, Testdurchlaufraten, Bereitstellungshäufigkeit und Fehlerraten. Azure DevOps bietet integrierte Analysen. GitHub Actions können nicht Microsoft Dashboards verwenden.
- Laufzeitüberwachung. Verwenden Sie Azure Monitor verwalteten Dienst für Prometheus und Azure Managed Grafana, um AKS-Clusterintegritäts- und Workloadmetriken zu überwachen.
- Anwendungstelemetrie. Instrumentieren Sie Ihre Microservices mit Azure Monitor Application Insights für verteilte Ablaufverfolgung, Anforderungsprotokollierung und Abhängigkeitsnachverfolgung.
- Alarmierung. Konfigurieren Sie Warnungen für Bereitstellungsfehler, Pod-Neustarts, hohe Fehlerraten und Ressourcensättigung, um eine schnelle Reaktion auf Vorfälle zu ermöglichen.
Well-Architected Framework-Ausrichtung
Berücksichtigen Sie beim Entwerfen Ihrer CI/CD-Pipeline für Microservices auf Kubernetes die Säulen des Azure Well-Architected Frameworks:
| Säule | Considerations |
|---|---|
| Reliability | Automatisierte Rollbackstrategien, Integritätssonden für Bereitstellungen, Blaugrün- oder Canary-Releasestrategien, Pod-Unterbrechungsbudgets. |
| Security | Geheime Authentifizierung (Workload-ID, OIDC), Imagesignierung, Lieferkettensicherheit, RBAC mit geringsten Rechten, Netzwerkrichtlinien. |
| Kostenoptimierung | Build-Agents für die richtige Größenanpassung mit ephemeren selbst gehosteten Läufern, Implementieren von Aufbewahrungsrichtlinien für Containerregistrierungsimages und Verwenden von Spotknotenpools nur für unterbrechungstolerante nicht produktionsfähige Workloads. |
| Operative Exzellenz | GitOps für deklarative Bereitstellungen, Infrastruktur als Code, Pipeline as Code (YAML), Observability und Runbook Automation. |
| Performance-Effizienz | Parallele Pipelinephasen, Buildzwischenspeicherung (Docker-Layerzwischenspeicherung, Abhängigkeitszwischenspeicherung), horizontale Podskalierung. |
Beitragende
Microsoft verwaltet diesen Artikel. Die folgenden Mitwirkenden haben diesen Artikel geschrieben.
Hauptautor:
- Ray Kao | Principal Solutions Engineer
Um nicht öffentliche LinkedIn-Profile zu sehen, melden Sie sich bei LinkedIn an.
Nächste Schritte
- Eine Git-Branching-Strategie einführen
- Was ist Azure Pipelines?
- Releasepipelines, Entwurfsversionen und Releaseoptionen
- Bereitstellungssteuerung mithilfe von Genehmigungen
- Einführung in Azure Container Registry
- Microsoft Entra Workload ID mit AKS
- Azure Key Vault-Anbieter für Secrets Store CSI Driver
- DevSecOps in AKS