Condividi tramite


Risorse Kubernetes negli ambienti

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

Questo articolo descrive l'uso delle risorse Kubernetes negli ambienti Azure Pipelines verso cui puoi indirizzare le distribuzioni. È possibile connettersi a cluster Kubernetes pubblici o privati nel servizio Azure Kubernetes o in altri provider di servizi cloud.

Le visualizzazioni delle risorse dell'ambiente mostrano lo stato delle risorse Kubernetes e forniscono la tracciabilità alla pipeline e di nuovo al commit di attivazione. È anche possibile creare risorse di ambiente Kubernetes dinamiche per esaminare le richieste pull prima dell'unione. Per altre informazioni sulle risorse dell'ambiente, vedere Risorse nelle pipeline YAML e sicurezza delle risorse.

Nota

Un cluster AKS privato non espone l'endpoint del server API tramite un indirizzo IP pubblico, quindi è necessario connettersi alla rete virtuale del cluster. È possibile configurare un agente self-hosted all'interno di una rete virtuale che può accedere alla rete virtuale del cluster o usare i pool DevOps gestiti. Per altre informazioni, vedere Opzioni per la connessione a un cluster privato.

Vantaggi delle risorse dell'ambiente Kubernetes

Le risorse dell'ambiente Kubernetes e le visualizzazioni delle risorse negli ambienti offrono i vantaggi seguenti:

  • Tracciabilità delle pipeline. L'attività di distribuzione del Manifesto Kubernetes aggiunge annotazioni che facilitano la tracciabilità della pipeline. È possibile visualizzare l'organizzazione, il progetto e la pipeline di Azure DevOps responsabili degli aggiornamenti agli oggetti all'interno dello spazio dei nomi.

    Screenshot che mostra la tracciabilità della pipeline per un cluster Kubernetes.

  • Diagnostica dell'integrità delle risorse. La visualizzazione dello stato del carico di lavoro è un modo rapido per eseguire il debug di errori o regressioni introdotti dalle nuove distribuzioni. Ad esempio, le informazioni sullo stato dei pod possono aiutare a identificare la causa di problemi, come ad esempio un imagePullSecrets non configurato che risultano in errori ImagePullBackOff.

    Screenshot che mostra la visualizzazione dello stato del carico di lavoro per una distribuzione Kubernetes.

  • Esaminare l'app. L'app di revisione distribuisce ogni richiesta pull dal repository Git a una risorsa Kubernetes dinamica nell'ambiente e pubblica un commento GitHub collegato all'app di revisione. I revisori possono vedere come appaiono le modifiche della pull request e lavorare con altri servizi dipendenti prima che le modifiche vengano unite nel ramo di destinazione e distribuite nell'ambiente di produzione.

    Screenshot che mostra il commento dell'app di revisione in GitHub.

Risorse AKS

AKS crea un ServiceAccount nel cluster e nello spazio dei nomi scelto, mappando le risorse Kubernetes nel tuo ambiente allo spazio dei nomi specificato. Per informazioni sulla configurazione di una connessione al servizio Kubernetes all'esterno di un ambiente, vedere Connessione al servizio Kubernetes.

Per un cluster abilitato per il controllo degli accessi in base al ruolo di Kubernetes, RoleBinding viene creato anche per limitare l'ambito dell'account del servizio allo spazio dei nomi scelto. Per un cluster RBAC di Kubernetes disabilitato, l'account del servizio creato ha privilegi a livello di cluster su tutti i namespace.

Per aggiungere una risorsa AKS a un ambiente Azure Pipelines:

  1. Nella pagina dell'ambiente sotto Pipelines>Ambienti, selezionare Aggiungi risorsa e quindi selezionare Kubernetes.

  2. Nella schermata successiva selezionare Servizio Azure Kubernetes per provider e quindi selezionare la sottoscrizione di Azure, il cluster del servizio Azure Kubernetes e lo spazio dei nomi nuovo o esistente. Per un nuovo spazio dei nomi, immettere il nome dello spazio dei nomi.

  3. Selezionare Convalida e crea. La nuova risorsa viene visualizzata nella scheda Risorse dell'ambiente con il testo Mai distribuito.

    Screenshot che mostra una risorsa Kubernetes aggiunta.

Risorse Kubernetes non del servizio Azure Kubernetes

Per eseguire il mapping di una risorsa Kubernetes da un cluster non-AKS a uno spazio dei nomi, è necessario avere un account di servizio esistente per il provider non-AKS.

Per aggiungere una risorsa Kubernetes non gestita da Azure Kubernetes Service (AKS) a un ambiente di Azure Pipelines:

  1. Nella pagina dell'ambiente sotto Pipelines>Ambienti, selezionare Aggiungi risorsa e quindi selezionare Kubernetes.

  2. Nella schermata successiva selezionare Provider Generico (account del servizio esistente) per Provider.

  3. In Credenziali cluster immettere il nome del cluster, lo spazio dei nomi, l'URL del server e il segreto.

    • Per ottenere l'URL del server, eseguire kubectl config view --minify -o jsonpath={.clusters[0].cluster.server} nella shell locale.

    • Per ottenere il segreto:

      1. Per ottenere i nomi delle credenziali dell'account di servizio, eseguire kubectl get serviceAccounts <service-account-name> -n <namespace> -o=jsonpath={.secrets[*].name}.
      2. Eseguire kubectl get secret <service-account-secret-name> -n <namespace> -o json usando l'output del comando precedente.

      Nota

      Se non si ottengono risultati dal get ServiceAccounts comando, vedere Creare manualmente un token API di lunga durata per un ServiceAccount.

  4. Selezionare Convalida e crea.

Risorse Kubernetes nelle pipeline

Il modo più semplice per creare una pipeline YAML da distribuire nel servizio Azure Kubernetes consiste nell'iniziare con il modello Distribuisci nei servizi Azure Kubernetes . Non è necessario scrivere codice YAML o creare manualmente associazioni di ruolo esplicite. La pipeline generata imposta e usa variabili e altri valori in base alle impostazioni di configurazione.

Usare l'app di revisione

Il DeployPullRequest job distribuisce ogni pull request dal tuo repository Git a una risorsa Kubernetes dinamica nell'ambiente. Per aggiungere questo processo alla pipeline, selezionare la casella di controllo Abilita flusso di revisione dell'app per le richieste pull nel modulo di configurazione Distribuisci ai Servizi Kubernetes di Azure.

Nota

Per aggiungere questo processo a una pipeline esistente, assicurarsi che la connessione al servizio che supporti la normale risorsa dell'ambiente Kubernetes sia impostata su Usa credenziali di amministratore del cluster. In caso contrario, è necessario creare associazioni di ruolo tra l'account del servizio sottostante e lo spazio dei nomi dell'applicazione di revisione.

Le risorse dell'app etichettate come Review vengono elencate come Risorse nell'ambiente.

Screenshot che mostra l'ambiente Review nell'elenco degli ambienti della pipeline.

Pipeline di esempio

La pipeline di esempio seguente si basa sul modello Deploy to Azure Kubernetes Services (Distribuisci nei servizi Azure Kubernetes ). La pipeline compila e esegue il push di un'immagine in Registro Azure Container.

Il primo processo di distribuzione viene quindi eseguito per tutti i commit nel main ramo e viene distribuito in una normale risorsa Kubernetes nell'ambiente.

Il secondo processo viene eseguito quando viene creata o aggiornata una PR nel ramo main e viene distribuito in una risorsa dell'app di revisione dinamica creata su richiesta nel cluster.

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