CI/CD-Pipeline mit Azure Pipelines und Google Kubernetes Engine erstellen

Last reviewed 2022-11-29 UTC

In dieser Anleitung wird gezeigt, wie Sie Azure Pipelines, Google Kubernetes Engine (GKE) und Container Registry nutzen, um eine CI/CD-Pipeline (Continuous Integration/Continuous Deployment) für eine ASP.NET MVC-Webanwendung zu erstellen. Für diese Anleitung können Sie zwischen zwei Beispielanwendungen wählen:

  • Eine ASP.NET Core-Webanwendung, die .NET 6.0 verwendet und unter Linux ausgeführt wird
  • Eine ASP.NET MVC-Webanwendung, die .NET Framework 4 verwendet und unter Windows ausgeführt wird

Die CI/CD-Pipeline verwendet zwei separate GKE-Cluster, einen für die Entwicklung und einen für die Produktion, wie das folgende Diagramm zeigt.

Konzeptionelles Diagramm der CI/CD-Pipeline zur Darstellung der Interaktion von Entwicklern und Endnutzern mit der Anwendung

Am Anfang der Pipeline nehmen Entwickler Änderungen an der Beispielcodebasis vor. Diese Aktion veranlasst die Pipeline dazu, eine Freigabe zu erstellen und sie im Entwicklungscluster bereitzustellen. Ein Release-Manager kann dann den Release hochstufen, sodass er im Produktionscluster bereitgestellt wird.

Diese Anleitung richtet sich an Entwickler und DevOps-Entwickler. Es wird davon ausgegangen, dass Sie Grundkenntnisse in Microsoft .NET, Azure Pipelines und GKE haben. Für die Anleitung benötigen Sie außerdem Administratorzugriff auf ein Azure DevOps-Konto.

Lernziele

  • Verbindung von Container Registry zu Azure Pipelines für die Veröffentlichung von Docker-Images herstellen
  • Eine .NET Core-Beispielanwendung für das Deployment GKE vorbereiten
  • Sicher bei GKE authentifizieren, ohne die ältere Authentifizierung verwenden zu müssen
  • Releaseverwaltung von Azure Pipelines zur Orchestrierung von GKE-Deployments verwenden

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Auf der Azure DevOps-Preisseite finden Sie alle Gebühren, die bei der Verwendung von Azure DevOps anfallen können.

Hinweis

In der Regel empfiehlt es sich, getrennte Projekte für Entwicklungs- und Produktionsarbeitslasten zu verwenden. So können Sie IAM-Rollen und -Berechtigungen (Identity and Access Management) einzeln zuweisen. Zur Vereinfachung wird in dieser Anleitung ein einziges Projekt für zwei GKE-Cluster verwendet – ein Cluster für die Entwicklung und einer für die Produktion.

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Sie müssen ein Azure DevOps-Konto mit Administratorzugriff haben. Wenn Sie noch kein Azure DevOps-Konto haben, können Sie sich auf der Azure DevOps-Startseite registrieren.

Azure DevOps-Projekt erstellen

Sie verwenden Azure DevOps, um den Quellcode zu verwalten, Builds und Tests auszuführen und das Deployment in GKE zu orchestrieren. Erstellen Sie zuerst in Ihrem Azure DevOps-Konto ein Projekt.

  1. Rufen Sie die Azure DevOps-Startseite (https://dev.azure.com/YOUR_AZURE_DEVOPS_ACCOUNT_NAME) auf.
  2. Klicken Sie auf Neues Projekt.
  3. Geben Sie einen Projektnamen ein, z. B. CloudDemo.
  4. Legen Sie für Sichtbarkeit die Option Privat fest und klicken Sie dann auf Erstellen.
  5. Nachdem Sie das Projekt erstellt haben, klicken Sie im Menü links auf Repositories.
  6. Klicken Sie auf Importieren, um einen Fork des Repositorys dotnet-docs-samples aus GitHub zu erstellen, und legen Sie dann die folgenden Werte fest:
    • Repository-Typ: Git
    • Klon-URL: https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
  7. Klicken Sie auf Importieren.

    Wenn der Importvorgang abgeschlossen ist, wird der Quellcode des Repositorys dotnet-docs-samples angezeigt.

Azure Pipelines mit Google Container Registry verbinden

Bevor Sie die kontinuierliche Integration für die Anwendung CloudDemo einrichten können, müssen Sie Azure Pipelines mit Container Registry verbinden. Über diese Verbindung kann Azure Pipelines Container-Images in Container Registry veröffentlichen.

Dienstkonto für die Veröffentlichung von Images einrichten

Erstellen Sie in Ihrem Projekt ein Google Cloud-Dienstkonto:

  1. Öffnen Sie die Google Cloud Console.

  2. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  3. Damit Sie die Projekt-ID und die Optionen für Compute Engine nicht immer wieder neu eingeben müssen, können Sie mit folgenden Befehlen Standardkonfigurationswerte festlegen:

    gcloud config set project PROJECT_ID
    gcloud config set compute/zone us-central1-a
    

    Ersetzen Sie dabei PROJECT_ID durch die Projekt-ID Ihres Zielprojekts.

  4. Aktivieren Sie im Projekt die Container Registry API:

    gcloud services enable containerregistry.googleapis.com
    
  5. Erstellen Sie ein Dienstkonto, das von Azure Pipelines zum Veröffentlichen von Docker-Images verwendet wird:

    gcloud iam service-accounts create azure-pipelines-publisher \
        --display-name="Azure Pipelines Publisher"
    
  6. Weisen Sie dem Dienstkonto die IAM-Rolle "Storage Administrator" (roles/storage.admin) zu, damit Azure Pipelines per Push in Container Registry übertragen kann:

    AZURE_PIPELINES_PUBLISHER=azure-pipelines-publisher@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member serviceAccount:$AZURE_PIPELINES_PUBLISHER \
        --role roles/storage.admin
    
  7. Generieren Sie einen Dienstkontoschlüssel:

    gcloud iam service-accounts keys create azure-pipelines-publisher.json \
        --iam-account $AZURE_PIPELINES_PUBLISHER
    
    tr -d '\n' < azure-pipelines-publisher.json > azure-pipelines-publisher-oneline.json
    
  8. Rufen Sie den Inhalt der Dienstkonto-Schlüsseldatei auf:

    echo $(<azure-pipelines-publisher-oneline.json)
    

    Sie benötigen den Dienstkontoschlüssel in einem der folgenden Schritte.

Dienstverbindung für Container Registry erstellen

Erstellen Sie in Azure Pipelines eine neue Dienstverbindung für Container Registry:

  1. Wählen Sie im Azure DevOps-Menü die Option Project settings und dann Pipelines > Agent pools aus.
  2. Klicken Sie auf Dienstverbindung erstellen.
  3. Wählen Sie in der Liste Docker Registry aus und klicken Sie dann auf Next.
  4. Geben Sie im Dialogfeld Werte für die folgenden Felder ein:
    • Registry type (Registry-Typ): Others (Andere).
    • Docker Registry (Docker-Registry): https://gcr.io/PROJECT_ID. Ersetzen Sie PROJECT_ID durch den Namen Ihres Projekts (z. B. https://gcr.io/azure-pipelines-test-project-12345).
    • Docker ID (Docker-ID): _json_key.
    • Password: Fügen Sie den Inhalt von azure-pipelines-publisher-oneline.json ein.
    • Service connection name: gcr-tutorial.
  5. Klicken Sie auf Save, um die Verbindung herzustellen.

Kontinuierlich erstellen

Sie können jetzt mit Azure Pipelines die kontinuierliche Integration einrichten. Für jeden Commit, der an das Git-Repository gesendet wird, erstellt Azure Pipelines den Code und verpackt die Build-Artefakte in einen Docker-Container. Der Container wird dann in Container Registry veröffentlicht.

Das Repository enthält bereits das folgende Dockerfile:

.NET/Linux

#
# Copyright 2020 Google LLC
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

FROM mcr.microsoft.com/dotnet/aspnet:6.0
EXPOSE 8080

#------------------------------------------------------------------------------
# Copy publishing artifacts.
#------------------------------------------------------------------------------

WORKDIR /app
COPY CloudDemo.MvcCore/bin/Release/net6.0/publish/ /app/

ENV ASPNETCORE_URLS=http://0.0.0.0:8080

#------------------------------------------------------------------------------
# Run application in Kestrel.
#------------------------------------------------------------------------------

ENTRYPOINT ["dotnet", "CloudDemo.MvcCore.dll"]

.NET Framework/Windows

#
# Copyright 2020 Google LLC
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

FROM mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
EXPOSE 80
SHELL ["powershell", "-command"]

#------------------------------------------------------------------------------
# Add LogMonitor so that IIS and Windows logs are emitted to STDOUT and can be
# picked up by Docker/Kubernetes.
#
# See https://github.com/microsoft/windows-container-tools/wiki/Authoring-a-Config-File
# for details.
#------------------------------------------------------------------------------

ADD https://github.com/microsoft/windows-container-tools/releases/download/v1.1/LogMonitor.exe LogMonitor/
ADD LogMonitorConfig.json LogMonitor/

#------------------------------------------------------------------------------
# Copy publishing artifacts to webroot.
#------------------------------------------------------------------------------

ADD CloudDemo.Mvc/bin/Release/PublishOutput/ c:/inetpub/wwwroot/

#------------------------------------------------------------------------------
# Configure IIS using the helper functions from deployment.ps1.
#------------------------------------------------------------------------------

ADD deployment.ps1 /
RUN . /deployment.ps1; \
	Install-Iis; \
	Register-WebApplication -AppName "CloudDemo"; \
	Remove-Item /deployment.ps1

#------------------------------------------------------------------------------
# Run IIS, wrapped by LogMonitor.
#------------------------------------------------------------------------------

ENTRYPOINT ["C:\\LogMonitor\\LogMonitor.exe", "C:\\ServiceMonitor.exe", "w3svc"]

Jetzt erstellen Sie eine neue Pipeline, die die YAML-Syntax verwendet:

  1. Klonen Sie Ihr neues Git-Repository mit Visual Studio oder einem git-Befehlszeilenclient und sehen Sie sich den main-Zweig an.
  2. Erstellen Sie im Stammverzeichnis des Repositorys eine Datei mit dem Namen azure-pipelines.yml.
  3. Kopieren Sie den folgenden Code in die Datei:

    .NET/Linux

    resources:
    - repo: self
      fetchDepth: 1
    pool:
      vmImage: ubuntu-20.04
    trigger:
    - main
    variables:
      TargetFramework: 'net6.0'
      BuildConfiguration: 'Release'
      DockerImageName: 'PROJECT_ID/clouddemo'
    steps:
    - task: DotNetCoreCLI@2
      displayName: Publish
      inputs:
        projects: 'applications/clouddemo/netcore/CloudDemo.MvcCore.sln'
        publishWebProjects: false
        command: publish
        arguments: '--configuration $(BuildConfiguration) --framework=$(TargetFramework)'
        zipAfterPublish: false
        modifyOutputPath: false
    - task: CmdLine@1
      displayName: 'Lock image version in deployment.yaml'
      inputs:
        filename: /bin/bash
        arguments: '-c "awk ''{gsub(\"CLOUDDEMO_IMAGE\", \"gcr.io/$(DockerImageName):$(Build.BuildId)\", $0); print}'' applications/clouddemo/netcore/deployment.yaml > $(build.artifactstagingdirectory)/deployment.yaml"'
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        PathtoPublish: '$(build.artifactstagingdirectory)'
    - task: Docker@2
      displayName: 'Login to Container Registry'
      inputs:
        command: login
        containerRegistry: 'gcr-tutorial'
    - task: Docker@2
      displayName: 'Build and push image'
      inputs:
        Dockerfile: 'applications/clouddemo/netcore/Dockerfile'
        command: buildAndPush
        repository: '$(DockerImageName)'

    .NET Framework/Windows

    resources:
    - repo: self
      fetchDepth: 1
    pool:
      vmImage: windows-2019     # Matches WINDOWS_LTSC in GKE
      demands:
      - msbuild
      - visualstudio
    trigger:
    - master
    variables:
      Solution: 'applications/clouddemo/net4/CloudDemo.Mvc.sln'
      BuildPlatform: 'Any CPU'
      BuildConfiguration: 'Release'
      DockerImageName: 'PROJECT_ID/clouddemo'
    steps:
    - task: NuGetCommand@2
      displayName: 'NuGet restore'
      inputs:
        restoreSolution: '$(Solution)'
    - task: VSBuild@1
      displayName: 'Build solution'
      inputs:
        solution: '$(Solution)'
        msbuildArgs: '/p:DeployOnBuild=true /p:PublishProfile=FolderProfile'
        platform: '$(BuildPlatform)'
        configuration: '$(BuildConfiguration)'
    - task: PowerShell@2
      displayName: 'Lock image version in deployment.yaml'
      inputs:
        targetType: 'inline'
        script: '(Get-Content applications\clouddemo\net4\deployment.yaml) -replace "CLOUDDEMO_IMAGE","gcr.io/$(DockerImageName):$(Build.BuildId)" | Out-File -Encoding ASCII $(build.artifactstagingdirectory)\deployment.yaml'
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        PathtoPublish: '$(build.artifactstagingdirectory)'
    - task: Docker@2
      displayName: 'Login to Container Registry'
      inputs:
        command: login
        containerRegistry: 'gcr-tutorial'
    - task: Docker@2
      displayName: 'Build and push image'
      inputs:
        Dockerfile: 'applications/clouddemo/net4/Dockerfile'
        command: buildAndPush
        repository: '$(DockerImageName)'

    Ersetzen Sie PROJECT_ID durch den Namen Ihres Projekts und speichern Sie die Datei.

  4. Übernehmen Sie die Änderungen und übertragen Sie sie per Push an Azure Pipelines.

    Visual Studio

    1. Öffnen Sie den Team Explorer und klicken Sie auf das Symbol Startseite.
    2. Klicken Sie auf Änderungen.
    3. Geben Sie eine Commit-Nachricht wie Add pipeline definition ein.
    4. Klicken Sie auf Commit für alle und Push.

    Befehlszeile

    1. Alle geänderten Dateien bereitstellen:

      git add -A
      
    2. Übernehmen Sie die Änderungen für das lokale Repository:

      git commit -m "Add pipeline definition"
      
    3. Übertragen Sie die Änderungen per Push an Azure DevOps:

      git push
      
  5. Wählen Sie im Azure DevOps-Menü Pipelines aus und klicken Sie dann auf Pipeline erstellen.

  6. Wählen Sie Azure Repos Git aus.

  7. Wählen Sie Ihr Repository aus.

  8. Klicken Sie auf der Seite YAML-Pipeline prüfen auf Ausführen.

    Ein neuer Build wird ausgelöst. Es kann etwa sechs Minuten dauern, bis der Build abgeschlossen ist.

  9. Rufen Sie zur Überprüfung, ob das Image in Container Registry veröffentlicht wurde, Ihr Projekt in der Google Cloud Console auf. Wählen Sie dort Container Registry > Images aus und klicken Sie dann auf clouddemo.

    Ein einzelnes Image und dessen Tag werden angezeigt. Das Tag entspricht der numerischen ID des Builds, der in Azure Pipelines ausgeführt wurde.

Kontinuierliches Deployment

Da Azure Pipelines den Code automatisch erstellt und für jedes Commit Docker-Images veröffentlicht werden, können Sie sich nun dem Deployment widmen.

Im Gegensatz zu anderen Systemen für Continuous Integration unterscheidet Azure Pipelines zwischen Builds und Deployments. Daher steht in Azure Pipelines eine Reihe von speziellen Tools unter dem Namen "Releaseverwaltung" zur Verfügung, die für alle Aufgaben in Zusammenhang mit dem Deployment zum Einsatz kommen.

Die Azure Pipelines-Releaseverwaltung basiert auf folgenden Konzepten:

  • Ein Release bezieht sich auf eine Reihe von Artefakten, die eine bestimmte Version Ihrer Anwendung ausmachen und normalerweise das Ergebnis eines Build-Prozesses sind.
  • Deployment bezieht sich auf das Erstellen eines Releases in einer bestimmten Umgebung.
  • Bei einem Deployment werden mehrere Aufgaben ausgeführt, die in Jobs zusammengefasst sein können.
  • Mit Phasen können Sie Ihre Pipeline segmentieren und Deployments in mehreren Umgebungen (z. B. Entwicklungs- und Testumgebungen) orchestrieren.

Das primäre Artefakt, das sich aus dem CloudDemo-Build-Prozess ergibt, ist das Docker-Image. Da das Docker-Image jedoch in Container Registry veröffentlicht wird, liegt es außerhalb des Geltungsbereichs von Azure Pipelines. Das Image ist daher keine geeignete Definition für ein Release.

Für das Deployment in Kubernetes benötigen Sie außerdem ein Manifest, das einer Stückliste ähnelt. Das Manifest definiert nicht nur die Ressourcen, die Kubernetes erstellen und verwalten soll, sondern gibt auch die genaue Version des zu verwendenden Docker-Images an. Das Kubernetes-Manifest eignet sich gut als Artefakt, das den Release in der Azure Pipelines-Releaseverwaltung definiert.

Deployment in Kubernetes konfigurieren

Zum Ausführen von CloudDemo in Kubernetes benötigen Sie folgende Ressourcen:

  • Ein Deployment, das einen einzelnen Pod definiert, der das vom Build erstellte Docker-Image ausführt
  • Ein NodePort-Dienst, der den Pod für ein Load-Balancing-Modul verfügbar macht
  • Eingehenden Traffic, der die Anwendung mithilfe eines Cloud HTTP(S)-Load-Balancers im öffentlichen Internet verfügbar macht

Das Repository enthält bereits das folgende Kubernetes-Manifest, das diese Ressourcen definiert:

.NET/Linux

#
# Copyright 2020 Google LLC
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

apiVersion: v1
kind: Service
metadata:
  name: clouddemo-netcore
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: clouddemo-netcore
  type: NodePort

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: clouddemo-netcore
spec:
  defaultBackend:
    service:
      name: clouddemo-netcore
      port:
        number: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: clouddemo-netcore
spec:
  replicas: 2
  selector:
    matchLabels:
      app: clouddemo-netcore
  template:
    metadata:
      labels:
        app: clouddemo-netcore
    spec:
      containers:
      - name: clouddemo-netcore
        image: CLOUDDEMO_IMAGE
        ports:
          - containerPort: 8080
        livenessProbe:      # Used by deployment controller
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:     # Used by Ingress/GCLB
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 5
        resources:
          limits:
            memory: 1024Mi
          requests:
            memory: 256Mi

.NET Framework/Windows

#
# Copyright 2020 Google LLC
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

apiVersion: v1
kind: Service
metadata:
  name: clouddemo-net4
  annotations:
    cloud.google.com/neg: '{"ingress": false}' # Disable NEG

spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: clouddemo-net4
  type: NodePort

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: clouddemo-net4
spec:
  defaultBackend:
    service:
      name: clouddemo-net4
      port:
        number: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: clouddemo-net4
spec:
  replicas: 2
  selector:
    matchLabels:
      app: clouddemo-net4
  template:
    metadata:
      labels:
        app: clouddemo-net4
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
      - name: clouddemo-net4
        image: CLOUDDEMO_IMAGE
        ports:
          - containerPort: 80
        livenessProbe:      # Used by deployment controller
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 120
          periodSeconds: 5
        readinessProbe:     # Used by Ingress/GCLB
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        resources:
          limits:
            memory: 1024Mi
          requests:
            memory: 256Mi

Entwicklungs- und Produktionsumgebung einrichten

Bevor Sie zur Azure Pipelines-Releaseverwaltung zurückkehren, müssen Sie die GKE-Cluster erstellen.

GKE-Cluster erstellen

  1. Kehren Sie zur Cloud Shell-Instanz zurück.

  2. Aktivieren Sie die GKE API für Ihr Projekt:

    gcloud services enable container.googleapis.com
  3. Erstellen Sie den Entwicklungs-Cluster mit dem folgenden Befehl. Die Ausführung kann einige Minuten dauern.

    .NET/Linux

    gcloud container clusters create azure-pipelines-cicd-dev --enable-ip-alias
    

    .NET Framework/Windows

    gcloud container clusters create azure-pipelines-cicd-dev --enable-ip-alias
    
    gcloud container node-pools create azure-pipelines-cicd-dev-win \
        --cluster=azure-pipelines-cicd-dev \
        --image-type=WINDOWS_LTSC \
        --no-enable-autoupgrade \
        --machine-type=n1-standard-2
    
  4. Erstellen Sie den Produktionscluster mit dem folgenden Befehl. Die Ausführung kann einige Minuten dauern.

    .NET/Linux

    gcloud container clusters create azure-pipelines-cicd-prod --enable-ip-alias
    

    .NET Framework/Windows

    gcloud container clusters create azure-pipelines-cicd-prod --enable-ip-alias
    
    gcloud container node-pools create azure-pipelines-cicd-prod-win \
        --cluster=azure-pipelines-cicd-prod \
        --image-type=WINDOWS_LTSC \
        --no-enable-autoupgrade \
        --machine-type=n1-standard-2
    

Azure Pipelines mit dem Entwicklungscluster verbinden

Mit Azure Pipelines können Sie eine Verbindung zu einer externen Docker-Registry wie Container Registry herstellen. Ebenso unterstützt Azure Pipelines die Einbindung externer Kubernetes-Cluster.

Es ist möglich, sich mit einem Google Cloud-Dienstkonto bei Container Registry zu authentifizieren. Für die Authentifizierung bei GKE hingegen unterstützt Azure Pipelines die Verwendung von Google Cloud-Dienstkonten nicht. Stattdessen müssen Sie hier ein Kubernetes-Dienstkonto verwenden.

Für die Herstellung einer Verbindung von Azure Pipelines zu Ihrem Entwicklungscluster müssen Sie daher erst einmal ein Kubernetes-Dienstkonto erstellen.

  1. Stellen Sie in Cloud Shell eine Verbindung zum Entwicklungscluster her:

    gcloud container clusters get-credentials azure-pipelines-cicd-dev
  2. Erstellen Sie ein Kubernetes-Dienstkonto für Azure Pipelines:

    kubectl create serviceaccount azure-pipelines-deploy
  3. Erstellen Sie ein Kubernetes-Secret mit einem Token-Anmeldedaten für Azure Pipelines:

    kubectl create secret generic azure-pipelines-deploy-token --type=kubernetes.io/service-account-token --dry-run -o yaml \
      | kubectl annotate --local -o yaml -f - kubernetes.io/service-account.name=azure-pipelines-deploy \
      | kubectl apply -f -
    
  4. Weisen Sie dem Dienstkonto die Rolle cluster-admin zu, indem Sie eine Clusterrollenbindung erstellen:

    kubectl create clusterrolebinding azure-pipelines-deploy --clusterrole=cluster-admin --serviceaccount=default:azure-pipelines-deploy
  5. Bestimmen Sie die IP-Adresse des Clusters:

    gcloud container clusters describe azure-pipelines-cicd-dev --format=value\(endpoint\)
    

    Sie benötigen diese Adresse in einem der folgenden Schritte.

  6. Wählen Sie im Azure DevOps-Menü die Option Project settings (Projekteinstellungen) und dann Pipelines > Agent pools (Agent-Pools) aus.

  7. Klicken Sie auf New service connection (Neue Dienstverbindung).

  8. Wählen Sie Kubernetes aus und klicken Sie auf Next (Weiter).

  9. Legen Sie folgende Einstellungen fest:

    • Authentication method (Authentifizierungsmethode): Service account (Dienstkonto).
    • Server-URL: https://PRIMARY_IP. Ersetzen Sie PRIMARY_IP durch die zuvor ermittelte IP-Adresse.
    • Secret: Das zuvor erstellte Kubernetes-Secret. Führen Sie dazu den folgenden Befehl aus, kopieren Sie das Secret und kopieren Sie es dann auf die Azure-Seite.
      kubectl get secret azure-pipelines-deploy-token -o yaml
    • Service connection name: azure-pipelines-cicd-dev.
  10. Klicken Sie auf Speichern.

Azure Pipelines mit dem Produktionscluster verbinden

Zum Verbinden von Azure Pipelines mit einem Produktionscluster gehen Sie vor wie beim Herstellen einer Verbindung zum Entwicklungscluster.

  1. Stellen Sie in Cloud Shell eine Verbindung zum Produktionscluster her:

    gcloud container clusters get-credentials azure-pipelines-cicd-prod
  2. Erstellen Sie ein Kubernetes-Dienstkonto für Azure Pipelines:

    kubectl create serviceaccount azure-pipelines-deploy
  3. Weisen Sie dem Dienstkonto die Rolle cluster-admin zu, indem Sie eine Clusterrollenbindung erstellen:

    kubectl create clusterrolebinding azure-pipelines-deploy --clusterrole=cluster-admin --serviceaccount=default:azure-pipelines-deploy
  4. Bestimmen Sie die IP-Adresse des Clusters:

    gcloud container clusters describe azure-pipelines-cicd-prod --format=value\(endpoint\)
    

    Sie benötigen diese Adresse in einem der folgenden Schritte.

  5. Wählen Sie im Azure DevOps-Menü die Option Project settings (Projekteinstellungen) und dann Pipelines > Agent pools (Agent-Pools) aus.

  6. Klicken Sie auf New service connection (Neue Dienstverbindung).

  7. Wählen Sie Kubernetes aus und klicken Sie auf Next (Weiter).

  8. Legen Sie folgende Einstellungen fest:

    • Authentication method (Authentifizierungsmethode): Service account (Dienstkonto).
    • Server-URL: https://PRIMARY_IP. Ersetzen Sie PRIMARY_IP durch die zuvor ermittelte IP-Adresse.
    • Secret: Führen Sie in Cloud Shell den folgenden Befehl aus und kopieren Sie die Ausgabe:
      kubectl get secret $(kubectl get serviceaccounts azure-pipelines-deploy -o custom-columns=":secrets[0].name") -o yaml
    • Service connection name: azure-pipelines-cicd-prod.
  9. Klicken Sie auf Speichern.

Release-Pipeline konfigurieren

Nachdem Sie die GKE-Infrastruktur eingerichtet haben, kehren Sie zu Azure Pipelines zurück, um das Deployment zu automatisieren. Dieser Vorgang umfasst die folgenden Aufgaben:

  • Bereitstellung in der Entwicklungsumgebung
  • Anfordern der manuellen Genehmigung, bevor das Deployment in der Produktionsumgebung eingeleitet wird
  • In der Produktionsumgebung bereitstellen

Release-Definition erstellen

Im ersten Schritt erstellen Sie eine neue Releasedefinition.

  1. Wählen Sie im Azure DevOps-Menü Pipelines > Releases aus.
  2. Klicken Sie auf New pipeline (Neue Pipeline).
  3. Wählen Sie in der Vorlagenliste den Eintrag Empty job aus.
  4. Wenn Sie einen Namen für die Phase angeben sollen, geben Sie Development ein.
  5. Geben Sie dem Release am oberen Bildschirmrand den Namen CloudDemo-KubernetesEngine.
  6. Klicken Sie im Pipelinediagramm neben Artifacts auf Add.
  7. Wählen Sie Build aus und legen Sie folgende Einstellungen fest:

    • Source type (Quelltyp): Build.
    • Source (build pipeline) (Quelle (Build-Pipeline)): Wählen Sie die Build-Definition aus (es sollte nur eine Option vorhanden sein)
    • Default version (Standardversion): Latest.
    • Source Alias (Quellalias): manifest.
  8. Klicken Sie auf Add (Hinzufügen).

  9. Klicken Sie im Feld Artifact (Artefakt) auf Continuous deployment trigger (Trigger für kontinuierliches Deployment) (das Blitzsymbol), um einen Deployment-Trigger hinzuzufügen.

  10. Stellen Sie unter Continuous Deployment Trigger den Schieberegler auf Aktiviert ein.

  11. Klicken Sie auf Speichern.

  12. Geben Sie bei Bedarf einen Kommentar ein und bestätigen Sie mit OK.

    Die Pipeline wird in etwa so dargestellt:

    Screenshot der aktualisierten Pipeline in Azure Pipelines

Auf dem Entwicklungscluster bereitstellen

Mit der erstellten Releasedefinition können Sie nun die Bereitstellung für den GKE-Entwicklungscluster konfigurieren.

  1. Wechseln Sie im Menü zum Tab Tasks (Aufgaben).
  2. Klicken Sie auf Agent-Job und konfigurieren Sie die folgenden Einstellungen:

    • Agent-Pool: Azure Pipelines
    • Agent-Spezifikation: ubuntu-18.04
  3. Klicken Sie neben Agent job (Agent-Job) auf Add a task to agent job (Aufgabe zum Agent-Job hinzufügen) , um der Phase einen Schritt hinzuzufügen.

  4. Wählen Sie die Aufgabe Deploy to Kubernetes (Auf Kubernetes bereitstellen) aus und klicken Sie auf Add (Hinzufügen).

  5. Klicken Sie auf die neu hinzugefügte Aufgabe und legen Sie die folgenden Einstellungen fest:

    • Display name (Anzeigename): Deploy.
    • Action (Aktion): deploy (Deployment).
    • Kubernetes service connection (Kubernetes-Dienstverbindung): azure-pipelines-cicd-dev
    • Namespace: default.
    • Strategy (Strategie): None (Keine).
    • Manifests (Manifeste): manifest/drop/deployment.yaml.
  6. Klicken Sie auf Speichern.

  7. Geben Sie bei Bedarf einen Kommentar ein und bestätigen Sie mit OK.

Auf dem Produktionscluster bereitstellen

Zum Abschluss konfigurieren Sie die Bereitstellung im GKE-Produktionscluster.

  1. Wechseln Sie im Menü zum Tab Pipeline.
  2. Wählen Sie im Feld "Stages" die Option Add > New stage aus.
  3. Wählen Sie in der Vorlagenliste den Eintrag Empty job aus.
  4. Wenn Sie einen Namen für die Phase angeben sollen, geben Sie Production ein.
  5. Klicken Sie auf das Blitzsymbol der neu erstellten Phase.
  6. Legen Sie folgende Einstellungen fest:

    • Select trigger (Trigger auswählen): After stage
    • Stages (Phasen): Dev
    • Pre-deployment approvals (Genehmigungen vor der Bereitstellung): (aktiviert)
    • Approvers (Genehmigende Personen): Wählen Sie Ihren eigenen Nutzernamen aus.

    Die Pipeline sieht nun so aus:

    Screenshot der aktualisierten Pipeline in Azure Pipelines

  7. Wechseln Sie zum Tab Tasks (Aufgaben).

  8. Bewegen Sie den Mauszeiger auf den Tab Tasks (Aufgaben) und wählen Sie Tasks (Aufgaben) > Production (Produktion) aus.

  9. Klicken Sie auf Agent-Job und konfigurieren Sie die folgenden Einstellungen:

    • Agent-Pool: Azure Pipelines
    • Agent-Spezifikation: ubuntu-18.04
  10. Klicken Sie auf Add a task to agent job (Aufgabe zum Agent-Job hinzufügen) , um der Phase einen Schritt hinzuzufügen.

  11. Wählen Sie die Aufgabe Deploy to Kubernetes (Auf Kubernetes bereitstellen) aus und klicken Sie auf Add (Hinzufügen).

  12. Klicken Sie auf die neu hinzugefügte Aufgabe und legen Sie die folgenden Einstellungen fest:

    • Display name (Anzeigename): Deploy.
    • Action (Aktion): deploy (Deployment).
    • Kubernetes service connection (Kubernetes-Dienstverbindung): azure-pipelines-cicd-prod.
    • Namespace: default.
    • Strategy (Strategie): None (Keine).
    • Manifests (Manifeste): manifest/drop/deployment.yaml.
  13. Klicken Sie auf Speichern.

  14. Geben Sie bei Bedarf einen Kommentar ein und bestätigen Sie mit OK.

Pipeline ausführen

Nachdem Sie nun die gesamte Pipeline konfiguriert haben, können Sie sie testen, indem Sie eine Änderung am Quellcode vornehmen:

  1. Öffnen Sie auf Ihrem lokalen Computer die Datei Index.cshtml aus dem Git-Repository, das Sie zuvor geklont haben.

    .NET/Linux

    Die Datei befindet sich in applications\clouddemo\netcore\CloudDemo.MvcCore\Views\Home\.

    .NET Framework/Windows

    Die Datei befindet sich in applications\clouddemo\net4\CloudDemo.Mvc\Views\Home\.

  2. Ändern Sie in Zeile 26 den Wert von ViewBag.Title von Home Page in This app runs on GKE.

  3. Übernehmen Sie die Änderungen und übertragen Sie sie per Push an Azure Pipelines.

    Visual Studio

    1. Öffnen Sie den Team Explorer und klicken Sie auf das Symbol Startseite.
    2. Klicken Sie auf Änderungen.
    3. Geben Sie eine Commit-Nachricht wie Change site title ein.
    4. Klicken Sie auf Commit für alle und Push.

    Befehlszeile

    1. Alle geänderten Dateien bereitstellen:

      git add -A
      
    2. Übernehmen Sie die Änderungen für das lokale Repository:

      git commit -m "Change site title"
      
    3. Übertragen Sie die Änderungen per Push an Azure Pipelines:

      git push
      
  4. Wählen Sie im Azure DevOps-Menü Pipelines aus. Ein Build wird ausgelöst.

  5. Wählen Sie nach Abschluss des Builds Pipelines > Releases aus. Ein Freigabeprozess wird gestartet.

  6. Klicken Sie auf Release-1, um die Detailseite zu öffnen, und warten Sie, bis der Status der Phase Development (Entwicklung) zu Succeeded (Erfolgreich) wechselt.

  7. Wählen Sie in der Google Cloud Console Kubernetes Engine > Dienste und Ingress > Ingress aus.

  8. Suchen Sie den Dienst für eingehenden Traffic für den Cluster azure-pipelines-cicd-dev und warten Sie, bis der Status zu OK wechselt. Dieser Vorgang kann einige Minuten dauern.

  9. Öffnen Sie den Link in der Spalte Frontends derselben Zeile. Unter Umständen wird anfangs ein Fehler angezeigt, da der Load-Balancer erst nach einigen Minuten verfügbar ist. Achten Sie darauf, dass CloudDemo bereitgestellt wurde und den benutzerdefinierten Titel verwendet.

  10. Klicken Sie in Azure Pipelines auf die Schaltfläche Approve (Genehmigen), die sich unterhalb der Prod-Phase befindet, um das Deployment in der Produktionsumgebung anzustoßen.

    Wenn die Schaltfläche nicht angezeigt wird, müssen Sie möglicherweise erst einen vorherigen Release genehmigen oder ablehnen.

  11. Geben Sie bei Bedarf einen Kommentar ein und bestätigen Sie mit Approve (Genehmigen).

  12. Warten Sie, bis der Status der Umgebung Prod zu Succeeded (Erfolgreich) wechselt. Unter Umständen müssen Sie die Seite im Browser manuell aktualisieren.

  13. Aktualisieren Sie in der Google Cloud Console die Seite Dienste und eingehenden Traffic.

  14. Suchen Sie den Dienst für eingehenden Traffic für den Cluster azure-pipelines-cicd-prod und warten Sie, bis der Status zu OK wechselt. Dieser Vorgang kann einige Minuten dauern.

  15. Öffnen Sie den Link in der Spalte Frontends derselben Zeile. Auch hier wird unter Umständen erst ein Fehler angezeigt, da der Load-Balancer erst nach einigen Minuten verfügbar ist. Anschließend sehen Sie wieder die CloudDemo-App mit dem benutzerdefinierten Titel, die diesmal im Produktionscluster ausgeführt wird.

Bereinigen

Löschen Sie die von Ihnen erstellten Entitäten, um nach Abschluss dieser Anleitung keine weiteren Kosten zu verursachen.

Azure Pipelines-Projekt löschen

Informationen zum Löschen des Azure Pipelines-Projekts finden Sie in der Dokumentation zu Azure DevOps Services. Wenn Sie das Azure Pipelines-Projekt löschen, gehen alle Änderungen am Quellcode verloren.

Google Cloud-Entwicklung und -Projekte löschen

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Nächste Schritte