Exercice - Déployer une solution à plusieurs conteneurs sur un cluster Kubernetes

Effectué

Le pipeline de mise en production fourni avec votre projet est conçu pour générer la solution en tant que conteneur Docker et la déployer sur Azure App Service. Pour prendre en charge le déploiement de plusieurs conteneurs sur un cluster Kubernetes, vous devez modifier ce pipeline.

Dans cette unité, vous allez découvrir comment :

  • Mettez à jour le pipeline pour qu’il se déclenche avec une validation sur la branche principale.
  • Définissez les variables à partager dans le pipeline.
  • Générez et publiez des images Docker.
  • Publiez les manifestes Kubernetes.
  • Ajoutez une tâche pour créer un secret d’extraction d’image à utiliser entre vos instances Kubernetes et Container Registry.
  • Déployez les images mises à jour sur un cluster Kubernetes.

Mettre à jour le pipeline pour prendre en charge les déclencheurs

  1. Connectez-vous à votre organisation Azure DevOps puis accédez à votre projet.

  2. Sélectionnez Pipelines, puis choisissez votre pipeline.

  3. Sélectionnez Modifier pour modifier votre fichier azure-pipelines.yml.

    Andy : Il s’agit de l’étape de génération que nous avions en place pour la solution de conteneur unique précédente. Je savais qu’elle ne s’exécutait pas correctement. Je l’ai donc désactivée. Nous pouvons commencer par réactiver les déclencheurs en cas de validations sur la branche main.

  4. Remplacez la ligne trigger existante en haut du fichier par l’extrait de code suivant. Cette action déclenche une exécution de pipeline à chaque fois qu’une validation est effectuée sur la branche primaire.

    trigger:
    - 'main'
    

Définir les variables accessibles dans le pipeline

Andy : Nous allons devoir ajouter deux variables pour le pipeline. Une pour spécifier le nom du référentiel leaderboard, qui est leaderboard. L’autre correspond au nom du secret d’extraction d’image utilisé pour le partage entre les instances AKS et ACR pendant le déploiement.

  1. Ajoutez le code mis en surbrillance suivant à la section variables.

    variables:
      buildConfiguration: 'Release'
      leaderboardRepository: 'leaderboard'
      webRepository: 'web'
      tag: '$(Build.BuildId)'
      imagePullSecret: 'secret'
    

Générer et publier l’image Docker sur Azure Container Registry

Andy : Nous avons déjà une tâche de création d’application web en tant que conteneur Docker, que nous publions dans notre registre de conteneurs. Nous pouvons simplement utiliser une deuxième tâche pour en faire de même pour notre classement.

  1. Ajoutez une deuxième tâche Docker@2 pour générer et publier le conteneur de leaderboard en utilisant l’extrait de code mis en surbrillance suivant. Ajoutez cette tâche juste après la tâche de conteneur web.

    - task: Docker@2
      displayName: 'Build and push the web image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(webRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.Web/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    
    - task: Docker@2
      displayName: 'Build and push the leaderboard image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(leaderboardRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.LeaderboardContainer/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    

Conseil

Assurez-vous que la tâche que vous ajoutez ici utilise une mise en retrait cohérente avec la tâche précédente, car un espace blanc est important dans un fichier YAML.

Publier les manifestes Kubernetes

Andy : Je pense que nous pouvons passer à la phase suivante. Voyez-vous quelque chose qui manque ?

Mara : Vous avez mentionné qu’il existe certains fichiers de manifeste dans le projet source qui définissent le déploiement et des services dont Kubernetes a besoin lors de notre déploiement. Nous devons les publier avant de terminer cette étape.

Andy : Ah oui ? Ils ne seront pas encore sur le disque local ?

Mara : Ils le seraient si nous ajoutions les tâches de déploiement dans la même phase que la génération. Toutefois, étant donné que nos tâches de déploiement se déroulent dans leur propre phase de Déploiement, elles s’exécutent sur un environnement nouveau, probablement même sur un autre agent. Nous devons veiller à publier tout ce que cette phase produit dont l’autre phase a besoin.

Andy : Bien vu. Et c’est facile à faire ? Nous devons simplement nous assurer que le dossier manifests est copié vers le nouvel agent.

Mara : C’est à quoi sert la tâche PublishBuildArtifacts@1. C’est tellement courant qu’il y a même un raccourci pour, publish.

  1. Ajoutez une tâche publish qui stocke le dossier manifests pour une phase ultérieure, comme indiqué dans l’extrait de code suivant. Assurez-vous que la mise en retrait de cette tâche correspond à celle de la tâche précédente.

    - task: Docker@2
      displayName: 'Build and push the leaderboard image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(leaderboardRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.LeaderboardContainer/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    
    - publish: '$(Build.SourcesDirectory)/manifests'
      artifact: manifests
    

Remplacer la phase de déploiement

Mara : Je vais remplacer notre phase Déploiement existante par une phase qui utilise un travail de déploiement. Un travail de déploiement est un type spécial de travail qui nous permet d’associer le déploiement à l’environnement Azure DevOps créé précédemment. Cette action facilite le suivi de l’historique de déploiement, ce qui est particulièrement utile car nos solutions deviennent plus sophistiquées.

  1. Supprimez la phase de Déploiement existante (tout ce qui suit la phase de génération) et remplacez-la par l’extrait de code suivant. Prenez note de la ligne mise en surbrillance qui indique l’environnement de déploiement à utiliser.

    - stage: 'Deploy'
      displayName: 'Deploy the containers'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        displayName: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: 'Dev'
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
    

    Mara : La première étape que nous allons ajouter à la phase de déploiement consiste à télécharger les artefacts de manifeste publiés précédemment à l’aide de la tâche DownloadBuildArtifacts@0.

    Andy : Laissez-moi deviner, il existe un raccourci download pour cette tâche ?

    Mara : Exact ! Nous pouvons utiliser le spécificateur current pour indiquer que nous voulons l’artefact de l’exécution actuelle du pipeline.

  2. Ajoutez les lignes mises en évidence comme première étape de la phase Déploiement.

    - stage: 'Deploy'
      displayName: 'Deploy the containers'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        displayName: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: 'spike.default'
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: manifests
    

    Andy : Nous devons maintenant créer un secret d’extraction d’image qui sera partagé entre nos instances ACR et AKS. Savez-vous s’il existe une tâche que nous pouvons utiliser ?

    Mara : Je regardais ça justement, et c’est notre jour de chance. La tâche KubernetesManifest@0 prend en charge une action pour créer le secret requis.

Tâche de manifeste Kubernetes

La tâche de manifeste Kubernetes est conçue pour gérer toutes les opérations de déploiement courantes requises pour Kubernetes. Elle prend en charge plusieurs options action qui vont de la création de secrets au déploiement d’images. Dans ce cas, l’action createSecret est utilisée, ainsi que les paramètres suivants :

  • action indique la fonctionnalité à exécuter. Dans ce cas, createSecret crée le secret partagé.
  • connectionType spécifie le type de connexion de service à utiliser. Options : azureResourceManager ou kubernetesServiceConnection.
  • secretName spécifie le nom de la clé secrète à créer.
  • dockerRegistryEndpoint spécifie le nom de la connexion des Services Azure Container Registry.
  • azureSubscriptionConnection spécifie le nom de la connexion des Services ARM.
  • azureResourceGroup spécifie le nom de votre groupe de ressources.
  • kubernetesCluster spécifie le nom de votre cluster AKS.
  • namespace spécifie l’espace de noms Kubernetes auquel cette action s’applique.
  1. Ajoutez l’extrait de code suivant à la fin de votre pipeline. Assurez-vous que le nom du groupe de ressources et le nom du cluster correspondent aux noms de ceux que vous avez créés précédemment. Veillez à ce que la mise en retrait de cette tâche corresponde à celle de la tâche de téléchargement.

    - task: KubernetesManifest@1
      displayName: Create imagePullSecret
      inputs:
        action: createSecret
        connectionType: azureResourceManager
        secretName: $(imagePullSecret)
        dockerRegistryEndpoint: 'Container Registry Connection'
        azureSubscriptionConnection: 'Kubernetes Cluster Connection'
        azureResourceGroup: 'tailspin-space-game-rg'
        kubernetesCluster: 'tailspinspacegame-24591'
        namespace: 'default'
    

    Andy : La dernière phase consiste à déclencher le déploiement de nos images sur le cluster Kubernetes. D’après la documentation, il semble que nous puissions utiliser la même tâche, mais avec une action et des paramètres différents.

    • action indique la fonctionnalité à exécuter. Dans ce cas, deploy pour déployer sur un cluster AKS.
    • connectionType spécifie le type de connexion de service à utiliser. Options : azureResourceManager ou kubernetesServiceConnection.
    • azureSubscriptionConnection spécifie le nom de la connexion des Services ARM.
    • azureResourceGroup spécifie le nom de votre groupe de ressources.
    • kubernetesCluster spécifie le nom de votre cluster AKS.
    • namespace spécifie l’espace de noms Kubernetes auquel cette action s’applique.
    • imagePullSecrets spécifie la liste des secrets nécessaires à l’extraction à partir du registre de conteneurs.
    • containers spécifie la liste des images de conteneur à déployer.
  2. Ajoutez l’extrait de code suivant à la fin du pipeline. Assurez-vous que le nom du groupe de ressources et le nom du cluster correspondent aux noms de ceux que vous avez créés précédemment. Assurez-vous que la mise en retrait de cette tâche correspond à celle de la tâche précédente.

    - task: KubernetesManifest@1
      displayName: Deploy to Kubernetes cluster
      inputs:
        action: deploy
        connectionType: azureResourceManager
        azureSubscriptionConnection: 'Kubernetes Cluster Connection'
        azureResourceGroup: 'tailspin-space-game-rg'
        kubernetesCluster: 'tailspinspacegame-24591'
        namespace: 'default'
        manifests: |
          $(Pipeline.Workspace)/manifests/deployment.yml
          $(Pipeline.Workspace)/manifests/service.yml
        imagePullSecrets: |
          $(imagePullSecret)
        containers: |
          $(RegistryName)/$(webRepository):$(tag)
          $(RegistryName)/$(leaderboardRepository):$(tag)
    

Exécuter votre pipeline

  1. Sélectionnez Enregistrer en haut à droite de la page. Sélectionnez Enregistrer pour confirmer votre message de validation.

  2. Sélectionnez Exécuter, confirmez le nom de votre branche, puis sélectionnez Exécuter pour déclencher une exécution de pipeline.

  3. Sélectionnez Pipelines, puis choisissez votre pipeline pour afficher les journaux pendant l’exécution de votre pipeline.

  4. Une fois l’exécution du pipeline terminée, sélectionnez Environnements dans le volet gauche, puis sélectionnez l’environnement Dev pour afficher vos travaux de déploiement.

  5. Consultons maintenant notre application web déployée et notre point de terminaison d’API. Pour ce faire, nous devons obtenir les adresses IP externes pour les services web et leaderboard.

  6. Accédez au portail Azure, sélectionnez votre cluster AKS, puis choisissez Services et entrées.

    Screenshot of how to find the external IPs for your web and leaderboard services.

  7. Sélectionnez l’adresse IP externe de votre service web pour afficher votre site sur AKS.

    Screenshot of the Space Game web site.

  8. Revenez à votre fenêtre du portail Azure où vous vous étiez arrêté, puis copiez l’adresse IP externe de votre service leaderboard. Cette adresse IP est l’emplacement où l’API de classement est hébergée publiquement.

  9. Remplacez l’espace réservé dans le lien suivant par l’adresse IP externe que vous avez copiée. Vous pouvez également ajouter un paramètre de requête pageSize=10 pour faciliter l’affichage de la réponse JSON dans votre navigateur. Utilisez une URL semblable à celle qui suit dans un nouvel onglet de navigateur.

    http://[IP]/api/Leaderboard?pageSize=10
    
  10. Vous pouvez voir la réponse JSON brute de l’API leaderboard hébergée dans le cluster AKS. Vous disposez maintenant d’une API REST que vous pouvez appeler à partir d’autres applications.

    Screenshot of a web browser showing the JSON response from the leaderboard service.

Andy : C’est parfait ! Je pense que l’utilisation de Kubernetes serait un excellent moyen d’adopter une stratégie de microservices plus large.