Dela via


Kubernetes-resurser i miljöer

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

Den här artikeln beskriver hur du använder Kubernetes-resurser i Azure Pipelines-miljöer som du kan rikta in dig på med distributioner. Du kan ansluta till offentliga eller privata Kubernetes-kluster i Azure Kubernetes Service (AKS) eller andra molnleverantörer.

Miljöresursvyer visar Kubernetes-resursstatus och ger spårningsbarhet till pipelinen och tillbaka till den utlösande incheckningen. Du kan också skapa dynamiska Kubernetes-miljöresurser för att granska pull-begäranden före sammanslagning. Mer information om miljöresurser finns i Resurser i YAML-pipelines och Resurssäkerhet.

Kommentar

Ett privat AKS-kluster exponerar inte dess API-serverslutpunkt via en offentlig IP-adress, så du måste ansluta till klustrets virtuella nätverk. Du kan konfigurera en lokalt installerad agent i ett virtuellt nätverk som kan komma åt klustrets virtuella nätverk eller använda Hanterade DevOps-pooler. Mer information finns i Alternativ för att ansluta till ett privat kluster.

Fördelar med Kubernetes-miljöresurser

Kubernetes-miljöresurser och resursvyer i miljöer ger följande fördelar:

  • Pipelinespårning. Kubernetes-manifestets distributionuppgift lägger till annoteringar som stöder spårning av pipeline. Du kan se azure DevOps-organisationen, projektet och pipelinen som ansvarar för uppdateringar av objekt i namnområdet.

    Skärmbild som visar pipelinespårning för ett Kubernetes-kluster.

  • Diagnostik för resurshälsa. Arbetsbelastningsstatusvyn är ett snabbt sätt att felsöka misstag eller regressioner som introduceras av nya utrullningar. Till exempel kan poddstatusinformation hjälpa dig att identifiera orsaken till problem som okonfigurerade imagePullSecrets som resulterar i ImagePullBackOff fel.

    Skärmbild som visar arbetsbelastningsstatusvyn för en Kubernetes-distribution.

  • Granska appen. Granskningsappen distribuerar varje pull-begäran från din Git-lagringsplats till en dynamisk Kubernetes-resurs i miljön och publicerar en GitHub-kommentar som länkar till granskningsappen. Granskare kan se hur PR-ändringarna ser ut och fungerar med andra beroende tjänster innan ändringarna sammanfogas till målgrenen och distribueras till produktion.

    Skärmbild som visar kommentaren Recension app på GitHub.

AKS-resurser

AKS skapar ett ServiceAccount i det valda klustret och namnområdet och mappar Kubernetes-resurser i din miljö till det angivna namnområdet. Information om hur du konfigurerar en Kubernetes-tjänstanslutning utanför en miljö finns i Kubernetes-tjänstanslutning.

För ett RbAC-aktiverat kluster (Rollbaserad åtkomstkontroll i Kubernetes) skapas även RoleBinding för att begränsa omfånget för tjänstkontot till det valda namnområdet. För ett Kubernetes RBAC-inaktiverat kluster har det skapade tjänstkontot klusteromfattande behörigheter mellan namnområden.

Så här lägger du till en AKS-resurs i en Azure Pipelines-miljö:

  1. På miljöns sida underPipelines-miljöer> väljer du Lägg till resurs och sedan Kubernetes.

  2. På nästa skärm väljer du Azure Kubernetes Service för providern och väljer sedan din Azure-prenumeration, AKS-kluster och ett nytt eller befintligt namnområde. Ange namnområdets namn för ett nytt namnområde.

  3. Välj Verifiera och skapa. Den nya resursen visas på fliken Resurser i miljön med texten Aldrig distribuerad.

    Skärmbild som visar en tillagd Kubernetes-resurs.

Kubernetes-resurser som inte är AKS-resurser

Om du vill mappa en Kubernetes-resurs från ett icke-AKS-kluster till ett namnområde måste du ha ett befintligt tjänstkonto för icke-AKS-providern.

Så här lägger du till en Kubernetes-resurs som inte är AKS i en Azure Pipelines-miljö:

  1. På miljöns sida underPipelines-miljöer> väljer du Lägg till resurs och sedan Kubernetes.

  2. På nästa skärm väljer du Allmän provider (befintligt tjänstkonto) för providern.

  3. Under Klusterautentiseringsuppgifter anger du klusternamn, namnområde, server-URL och hemlighet.

    • Hämta server-URL:en genom att köra kubectl config view --minify -o jsonpath={.clusters[0].cluster.server} i det lokala gränssnittet.

    • Så här hämtar du hemligheten:

      1. Hämta namn på hemligheter för tjänstekonton genom att köra kubectl get serviceAccounts <service-account-name> -n <namespace> -o=jsonpath={.secrets[*].name}.
      2. Kör kubectl get secret <service-account-secret-name> -n <namespace> -o json med utdata från föregående kommando.

      Kommentar

      Om du inte får några resultat från get ServiceAccounts kommandot kan du läsa Manuellt skapa en API-token med lång livslängd för ett ServiceAccount.

  4. Välj Verifiera och skapa.

Kubernetes-resurser i processflöden

Det enklaste sättet att skapa en YAML-pipeline att distribuera till AKS är att börja med mallen Distribuera till Azure Kubernetes Services . Du behöver inte skriva YAML-kod eller skapa explicita rollbindningar manuellt. De genererade pipelinesystemen använder variabler och andra värden baserat på din konfiguration.

Använda granskningsappen

Jobbet DeployPullRequest distribuerar varje pull-begäran från din Git-lagringsplats till en dynamisk Kubernetes-resurs i miljön. Om du vill lägga till det här jobbet i pipelinen, markera kryssrutan Aktivera granskningsappens flöde för pull-förfrågningar i konfigurationsformuläret Driftsätt till Azure Kubernetes Services.

Kommentar

Om du vill lägga till det här jobbet i en befintlig pipeline kontrollerar du att tjänstanslutningen som stöder den vanliga Kubernetes-miljöresursen är inställd på Använd autentiseringsuppgifter för klusteradministratör. Annars måste rollbindningar skapas för det underliggande tjänstkontot till granskningsappens namnområde.

Granskning av applikationsresurser är taggad som Granskning i en miljös resursförteckning.

Skärmbild som visar granskningsmiljön i listan över pipelinemiljöer.

Exempelpipeline

Följande exempel på en pipeline baseras på mallen Deploy to Azure Kubernetes Services. Pipelinen bygger först och översänder en image till Azure Container Registry.

Det första distributionsjobbet körs sedan för alla incheckningar till grenen main och distribueras mot en vanlig Kubernetes-resurs i miljön.

Det andra jobbet körs när en PR skapas eller uppdateras till grenen main, och det distribueras mot en dynamisk granskningsapplikationsresurs som den skapar i klustret på begäran.

# 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"