Freigeben über


Kubernetes-Ressourcen in Umgebungen

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

In diesem Artikel wird die Verwendung von Kubernetes-Ressourcen in Azure Pipelines-Umgebungen beschrieben, auf die Sie mit Bereitstellungen abzielen können. Sie können eine Verbindung mit öffentlichen oder privaten Kubernetes-Clustern in Azure Kubernetes Service (AKS) oder anderen Cloudanbietern herstellen.

Umgebungsressourcenansichten zeigen den Kubernetes-Ressourcenstatus an und bieten Rückverfolgbarkeit für die Pipeline und zurück zum auslösenden Commit. Sie können auch dynamische Kubernetes-Umgebungsressourcen erstellen, um Pullanforderungen vor dem Zusammenführen zu überprüfen. Weitere Informationen zu Umgebungsressourcen finden Sie unter Ressourcen in YAML-Pipelines und Ressourcensicherheit.

Hinweis

Ein privater AKS-Cluster macht seinen API-Serverendpunkt nicht über eine öffentliche IP-Adresse verfügbar, daher müssen Sie eine Verbindung mit dem virtuellen Netzwerk des Clusters herstellen. Sie können einen selbst gehosteten Agent in einem virtuellen Netzwerk einrichten, der auf das virtuelle Netzwerk des Clusters zugreifen oder verwaltete DevOps-Pools verwenden kann. Weitere Informationen finden Sie unter "Optionen zum Herstellen einer Verbindung mit einem privaten Cluster".

Vorteile von Kubernetes-Umgebungsressourcen

Kubernetes-Umgebungsressourcen und Ressourcenansichten in Umgebungen bieten die folgenden Vorteile:

  • Pipelineablaufverfolgung. Die Kubernetes-Manifestbereitstellungsaufgabe fügt Anmerkungen hinzu, die die Pipelineablaufverfolgung unterstützen. Sie können die Azure DevOps-Organisation, das Projekt und die Pipeline sehen, die für Aktualisierungen von Objekten im Namespace verantwortlich sind.

    Screenshot der Pipelineverfolgbarkeit eines Kubernetes-Clusters.

  • Ressourcenintegritätsdiagnose. Die Ansicht "Workloadstatus" ist eine schnelle Möglichkeit zum Debuggen von Fehlern oder Regressionen, die von neuen Bereitstellungen eingeführt wurden. Beispielsweise können Podstatusinformationen Ihnen helfen, die Ursache von Problemen wie nicht konfigurierten imagePullSecrets zu identifizieren, die zu ImagePullBackOff-Fehlern führen.

    Screenshot, der die Workloadstatusansicht für eine Kubernetes-Bereitstellung zeigt.

  • App überprüfen. Die Prüf-App stellt jede Pull-Anforderung aus Ihrem Git-Repository in einer dynamischen Kubernetes-Ressource in der Umgebung bereit und veröffentlicht einen GitHub-Kommentar, der mit der Rezensions-App verknüpft ist. Prüfer können sehen, wie die PR-Änderungen aussehen und mit anderen abhängigen Diensten arbeiten, bevor die Änderungen in der Zielverzweigung zusammengeführt und in der Produktion bereitgestellt werden.

    Screenshot des Kommentars der Rezensions-App in GitHub.

AKS-Ressourcen

AKS erstellt ein ServiceAccount in Ihrem ausgewählten Cluster und Namespace und ordnet Kubernetes-Ressourcen in Ihrer Umgebung dem angegebenen Namespace zu. Informationen zum Einrichten einer Kubernetes-Dienstverbindung außerhalb einer Umgebung finden Sie unter Kubernetes-Dienstverbindung.

Für einen Cluster mit Kubernetes role-based access control (RBAC) wird auch eine RoleBinding erstellt, um den Umfang des Dienstkontos auf den gewählten Namespace zu beschränken. Für einen kubernetes RBAC-deaktivierten Cluster verfügt das erstellte Dienstkonto über clusterweite Berechtigungen für alle Namespaces.

So fügen Sie einer Azure Pipelines-Umgebung eine AKS-Ressource hinzu:

  1. Wählen Sie auf der Seite "Pipelines">"Umgebungen" die Option "Ressource hinzufügen" und dann "Kubernetes" aus.

  2. Wählen Sie auf dem nächsten Bildschirm Den Azure Kubernetes-Dienst für den Anbieter aus, und wählen Sie dann Ihr Azure-Abonnement, AKS-Cluster und neuen oder vorhandenen Namespace aus. Geben Sie für einen neuen Namespace den Namespacenamen ein.

  3. Wählen Sie "Überprüfen und erstellen" aus. Die neue Ressource wird auf der Registerkarte " Ressourcen " der Umgebung mit dem Text "Nie bereitgestellt" angezeigt.

    Screenshot einer hinzugefügten Kubernetes-Ressource.

Nicht-AKS Kubernetes-Ressourcen

Um eine Kubernetes-Ressource von einem Nicht-AKS-Cluster zu einem Namespace zuzuordnen, müssen Sie über ein vorhandenes Dienstkonto für den Nicht-AKS-Anbieter verfügen.

So fügen Sie einer Azure Pipelines-Umgebung eine Ressource ohne AKS Kubernetes hinzu:

  1. Wählen Sie auf der Seite "Pipelines">"Umgebungen" die Option "Ressource hinzufügen" und dann "Kubernetes" aus.

  2. Wählen Sie auf dem nächsten Bildschirm den generischen Anbieter (vorhandenes Dienstkonto) für den Anbieter aus.

  3. Geben Sie unter "Clusteranmeldeinformationen" den Clusternamen, den Namespace, die Server-URL und den geheimen Schlüssel ein.

    • Um die Server-URL abzurufen, führen Sie kubectl config view --minify -o jsonpath={.clusters[0].cluster.server} in Ihrer lokalen Shell aus.

    • Um das Geheimnis zu erhalten:

      1. Rufen Sie geheime Namen des Dienstkontos ab, indem Sie diese ausführen kubectl get serviceAccounts <service-account-name> -n <namespace> -o=jsonpath={.secrets[*].name}.
      2. Führen Sie kubectl get secret <service-account-secret-name> -n <namespace> -o json mit der Ausgabe des vorherigen Befehls aus.

      Hinweis

      Wenn Sie mit dem get ServiceAccounts Befehl keine Ergebnisse erhalten, lesen Sie Manuelles Erstellen eines langlebigen API-Tokens für ein ServiceAccount.

  4. Wählen Sie "Überprüfen und erstellen" aus.

Kubernetes-Ressourcen in Pipelines

Die einfachste Möglichkeit zum Erstellen einer YAML-Pipeline für die Bereitstellung in AKS besteht darin, mit der Vorlage "Deploy to Azure Kubernetes Services " zu beginnen. Sie müssen keinen YAML-Code schreiben oder explizite Rollenbindungen manuell erstellen. Die generierte Pipeline legt Variablen und andere Werte basierend auf Ihren Konfigurationseinstellungen fest und verwendet diese.

Verwenden der Rezensions-App

Der DeployPullRequest Auftrag stellt jede Pullanforderung aus Ihrem Git-Repository in einer dynamischen Kubernetes-Ressource in der Umgebung bereit. Um diesen Auftrag zur Pipeline hinzuzufügen, aktivieren Sie das Kontrollkästchen für Überprüfungs-App Flow für Pull-Anfragen aktivieren im Konfigurationsformular „Bereitstellen für Azure Kubernetes Services“.

Hinweis

Um diesen Auftrag einer vorhandenen Pipeline hinzuzufügen, stellen Sie sicher, dass die Dienstverbindung, die die reguläre Kubernetes-Umgebungsressource unterstützt, auf die Verwendung von Clusteradministratoranmeldeinformationen festgelegt ist. Andernfalls müssen Rollenbindungen für das zugrunde liegende Dienstkonto zum Review-App-Namespace erstellt werden.

App-Ressourcen sind in der Ressourcen-Auflistung der Umgebung als Überprüfung gekennzeichnet.

Screenshot der Überprüfungsumgebung in der Pipelineumgebungsauflistung.

Beispielpipeline

Die folgende Beispielpipeline basiert auf der Vorlage "Deploy to Azure Kubernetes Services ". Die Pipeline erstellt zuerst ein Image und überträgt dieses in die Azure-Containerregistrierung.

Der erste Bereitstellungsauftrag wird dann für alle Commits an der main Verzweigung ausgeführt und wird auf eine normale Kubernetes-Ressource in der Umgebung bereitgestellt.

Der zweite Job wird ausgeführt, wenn eine PR in der main-Branch erstellt oder aktualisiert wird, und stellt eine dynamische Review-App-Ressource bereit, die bei Bedarf im Cluster erstellt wird.

# Deploy to Azure Kubernetes Service
# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- main

resources:
- repo: self

variables:

  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '12345' # Docker service connection identifier
  imageRepository: 'name-of-image-repository' # name of image repository
  containerRegistry: 'mycontainer.azurecr.io' # path to container registry
  dockerfilePath: '**/Dockerfile'
  tag: '$(Build.BuildId)'
  imagePullSecret: 'my-app-secret' # image pull secret

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

  # Name of the new namespace being created to deploy the PR changes.
  k8sNamespaceForPR: 'review-app-$(System.PullRequest.PullRequestId)'

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - upload: manifests
      artifact: manifests

- stage: Production
  displayName: Deploy stage
  dependsOn: Build

  jobs:
  - deployment: Production
    condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
    displayName: Production
    pool:
      vmImage: $(vmImageName)
    environment: 'myenvironmentname.myresourcename'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: KubernetesManifest@1
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@1
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: deploy
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml
                $(Pipeline.Workspace)/manifests/service.yml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository):$(tag)

  - deployment: DeployPullRequest
    displayName: Deploy Pull request
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/pull/'))
    pool:
      vmImage: $(vmImageName)

    environment: 'myenvironmentname.$(k8sNamespaceForPR)'
    strategy:
      runOnce:
        deploy:
          steps:
          - reviewApp: default

          - task: Kubernetes@1
            displayName: 'Create a new namespace for the pull request'
            inputs:
              command: apply
              useConfigurationFile: true
              inline: '{ "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "$(k8sNamespaceForPR)" }}'

          - task: KubernetesManifest@1
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              namespace: $(k8sNamespaceForPR)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@1
            displayName: Deploy to the new namespace in the Kubernetes cluster
            inputs:
              action: deploy
              namespace: $(k8sNamespaceForPR)
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml
                $(Pipeline.Workspace)/manifests/service.yml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository):$(tag)

          - task: Kubernetes@1
            name: get
            displayName: 'Get services in the new namespace'
            continueOnError: true
            inputs:
              command: get
              namespace: $(k8sNamespaceForPR)
              arguments: svc
              outputFormat: jsonpath='http://{.items[0].status.loadBalancer.ingress[0].ip}:{.items[0].spec.ports[0].port}'

          # Get the IP of the deployed service and writing it to a variable for posting comment
          - script: |
              url="$(get.KubectlOutput)"
              message="Your review app has been deployed"
              if [ ! -z "$url" -a "$url" != "http://:" ]
              then
                message="${message} and is available at $url."
              fi
              echo "##vso[task.setvariable variable=GITHUB_COMMENT]$message"