Partager via


Ressources Kubernetes dans les environnements

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

Cet article décrit l’utilisation de ressources Kubernetes dans des environnements Azure Pipelines que vous pouvez cibler avec des déploiements. Vous pouvez vous connecter à des clusters Kubernetes publics ou privés dans Azure Kubernetes Service (AKS) ou à d’autres fournisseurs de cloud.

Les vues de ressources d’environnement affichent l’état des ressources Kubernetes et fournissent une traçabilité vers le pipeline et vers la validation de déclenchement. Vous pouvez également créer des ressources d’environnement Kubernetes dynamiques pour passer en revue les pull requests avant leur intégration. Pour plus d’informations sur les ressources d’environnement, consultez Ressources dans les pipelines YAML et sécurité des ressources.

Remarque

Un cluster AKS privé n’expose pas son point de terminaison de serveur d’API via une adresse IP publique. Vous devez donc vous connecter au réseau virtuel du cluster. Vous pouvez configurer un agent auto-hébergé au sein d’un réseau virtuel qui peut accéder au réseau virtuel du cluster ou utiliser des pools DevOps managés. Pour plus d’informations, consultez Options de connexion à un cluster privé.

Avantages des ressources de l’environnement Kubernetes

Les ressources d’environnement Kubernetes et les vues de ressources dans les environnements offrent les avantages suivants :

  • Traçabilité du pipeline. La tâche de déploiement de manifeste Kubernetes ajoute des annotations qui prennent en charge la traçabilité du pipeline. Vous pouvez voir l’organisation, le projet et le pipeline Azure DevOps responsables des mises à jour des objets dans l’espace de noms.

    Capture d’écran montrant la traçabilité du pipeline pour un cluster Kubernetes.

  • Diagnostics d’intégrité des ressources. La vue d’état de la charge de travail est un moyen rapide de déboguer des erreurs ou des régressions introduites par de nouveaux déploiements. Par exemple, les informations d'état du pod peuvent vous aider à identifier la cause des problèmes tels qu'un imagePullSecrets non configuré qui entraîne des erreurs ImagePullBackOff.

    Capture d’écran montrant la vue d’état de la charge de travail pour un déploiement Kubernetes.

  • Passez en revue l’application. L’application de révision déploie chaque demande de tirage de votre dépôt Git vers une ressource Kubernetes dynamique dans l’environnement et publie un commentaire GitHub lié à l’application de révision. Les réviseurs peuvent voir comment les modifications de la pull request s’affichent et fonctionnent avec d’autres services dépendants avant que les modifications ne soient fusionnées dans la branche cible et déployées en production.

    Capture d’écran montrant le commentaire de l’application Révision dans GitHub.

Ressources AKS

AKS crée un ServiceAccount dans votre cluster et espace de noms choisi, et mappe les ressources Kubernetes dans votre environnement à l’espace de noms spécifié. Pour plus d’informations sur la configuration d’une connexion de service Kubernetes en dehors d’un environnement, consultez connexion de service Kubernetes.

Pour un cluster avec contrôle d’accès en fonction du rôle (RBAC) Kubernetes, RoleBinding est également créé pour limiter l’étendue du compte de service à l’espace de noms choisi. Pour un cluster Kubernetes avec RBAC désactivé, le compte de service créé dispose de privilèges à l'échelle du cluster pour tous les espaces de noms.

Pour ajouter une ressource AKS à un environnement Azure Pipelines :

  1. Dans la page de l'environnement sous Pipelines>Environnements, sélectionnez Ajouter une ressource, puis sélectionnez Kubernetes.

  2. Dans l’écran suivant, sélectionnez Azure Kubernetes Service pour le fournisseur, puis sélectionnez votre abonnement Azure, le cluster AKS et l’espace de noms nouveau ou existant. Pour un nouvel espace de noms, entrez le nom de l’espace de noms.

  3. Sélectionnez Valider et créer. La nouvelle ressource apparaît sous l’onglet Ressources de l’environnement avec le texte Jamais déployé.

    Capture d’écran montrant une ressource Kubernetes ajoutée.

Ressources Kubernetes non-AKS

Pour mapper une ressource Kubernetes d’un cluster non AKS à un espace de noms, vous devez disposer d’un compte de service existant pour le fournisseur non AKS.

Pour ajouter une ressource Kubernetes non AKS à un environnement Azure Pipelines :

  1. Dans la page de l'environnement sous Pipelines>Environnements, sélectionnez Ajouter une ressource, puis sélectionnez Kubernetes.

  2. Dans l’écran suivant, sélectionnez Fournisseur générique (compte de service existant) pour le fournisseur.

  3. Sous Informations d’identification du cluster, entrez le nom du cluster, l’espace de noms, l’URL du serveur et le secret.

    • Pour obtenir l’URL du serveur, exécutez kubectl config view --minify -o jsonpath={.clusters[0].cluster.server} dans votre interpréteur de commandes local.

    • Pour obtenir le secret :

      1. Obtenez des noms de secrets de compte de service en exécutant kubectl get serviceAccounts <service-account-name> -n <namespace> -o=jsonpath={.secrets[*].name}.
      2. Exécutez kubectl get secret <service-account-secret-name> -n <namespace> -o json à l’aide de la sortie de la commande précédente.

      Remarque

      Si vous n’obtenez aucun résultat de la get ServiceAccounts commande, consultez Créer manuellement un jeton d’API de longue durée pour un ServiceAccount.

  4. Sélectionnez Valider et créer.

Ressources Kubernetes dans les pipelines

Le moyen le plus simple de créer un pipeline YAML à déployer sur AKS consiste à commencer par le modèle Déployer sur Azure Kubernetes Services . Vous n’avez pas besoin d’écrire du code YAML ou de créer manuellement des liaisons de rôle explicites. Les ensembles de pipelines générés définissent et utilisent des variables et d'autres valeurs en fonction de vos paramètres de configuration.

Utiliser l’application de révision

La tâche DeployPullRequest déploie chaque pull request de votre dépôt Git sur une ressource Kubernetes dynamique dans l'environnement spécifié. Pour ajouter ce travail au pipeline, cochez la case Activer le flux d'application de révision pour les demandes de tirage (Pull Requests) dans le formulaire de configuration Déployer sur Azure Kubernetes Services.

Remarque

Pour ajouter ce travail à un pipeline existant, vérifiez que la connexion de service qui sauvegarde la ressource d’environnement Kubernetes standard est définie sur Utiliser les informations d’identification de l’administrateur de cluster. Dans le cas contraire, les liaisons de rôle doivent être créées pour le compte de service sous-jacent à l’espace de noms de l’application de révision.

Les ressources de l’application de révision sont étiquetées Révision dans la liste des ressources de l’environnement.

Capture d’écran montrant l’environnement de révision dans la liste de l’environnement de pipeline.

Exemple de pipeline

L’exemple de pipeline suivant est basé sur le modèle Déployer sur Azure Kubernetes Services . Le pipeline génère et publie une image dans Azure Container Registry.

Le premier travail de déploiement s’exécute ensuite pour toutes les validations sur la main branche et se déploie sur une ressource Kubernetes régulière dans l’environnement.

Le deuxième travail s'exécute lorsqu'une pull request est créée ou mise à jour vers la branche main, et se déploie sur une ressource d'application de révision dynamique qu'elle crée dans le cluster à la demande.

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