Tutoriel : Utiliser une stratégie de déploiement canary pour Kubernetes
Azure DevOps Services | Azure DevOps Server 2022
Ce guide étape par étape couvre comment utiliser la tâche Kubernetes manifest avec la stratégie canary
. Une stratégie de déploiement canary déploie de nouvelles versions d’une application à côté des versions stables en production.
Vous utilisez le workflow associé pour déployer le code et comparer les déploiements de l'application de référence et de l'application canari. En fonction de l’évaluation, vous décidez de promouvoir ou de rejeter le déploiement canary.
Ce tutoriel utilise les connexions au registre Docker et au service Azure Resource Manager pour se connecter aux ressources Azure. Pour un cluster privé Azure Kubernetes Service (AKS) ou un cluster avec des comptes locaux désactivés, une connexion de service Azure Resource Manager est une meilleure solution de connexion.
Prérequis
Un projet Azure DevOps avec au moins des autorisations utilisateur.
Un compte Azure. Créez un compte gratuitement.
Une instance Azure Container Registry avec des privilèges de push.
Un cluster Azure Kubernetes Service (AKS) déployé. Vous pouvez attacher le cluster AKS à votre cluster de registre de conteneurs Azure lorsque vous déployez le cluster AKS ou par la suite.
Un compte GitHub. Créez un compte GitHub gratuit.
Un fork du référentiel GitHub https://github.com/MicrosoftDocs/azure-pipelines-canary-k8s.
Important
Lors des procédures suivantes, il se peut que vous soyez invité à créer une connexion de service GitHub ou à être redirigé vers GitHub pour vous connecter, installer Azure Pipelines, ou autoriser Azure Pipelines. Suivez les instructions à l’écran pour compléter le processus. Pour plus d’informations, veuillez consulter la section Accès aux référentiels GitHub.
Fichiers du référentiel GitHub
Le référentiel GitHub contient les fichiers suivants :
Fichier | Description |
---|---|
./app/app.py | Un serveur Web simple, basé sur Flask . Le fichier configure un compteur personnalisé pour le nombre de réponses correctes et incorrectes, basé sur la valeur de la variable success_rate . |
./app/Dockerfile | Utilisé pour construire l’image à chaque modification de app.py. Chaque modification déclenche le pipeline de build pour construire l’image et la pousser vers le référentiel de conteneurs. |
./manifests/deployment.yml | Contient la spécification de la charge de travail de déploiement sampleapp correspondant à l’image publiée. Vous utilisez ce fichier manifeste pour la version stable de l’objet de déploiement et pour dériver les variantes de base et canary des charges de travail. |
./manifests/service.yml | Crée le service sampleapp . Ce service redirige les requêtes vers les pods créés par les déploiements stables, de base et canary. |
./misc/fortio.yml | Configure un déploiement fortio. Ce déploiement est un outil de test de charge qui envoie un flux de requêtes au service sampleapp déployé. Le flux de requêtes est redirigé vers les pods sous les trois déploiements : stable, de base et canary. |
Création de connexions de service
- Dans votre projet Azure DevOps, allez dans Paramètres du projet>Pipelines>Connexions de service.
- Créez une connexion de service Docker Registry nommée azure-pipelines-canary-acr associée à votre instance Azure Container Registry.
- Créez une connexion au service Azure Resource Manager avec une identité de charge de travail nommée azure-pipelines-canary-k8s pour votre groupe de ressources.
Ajouter l’étape de génération
Dans votre projet Azure DevOps, allez dans Pipelines>Créer un pipeline ou Nouveau pipeline.
Sélectionnez GitHub comme emplacement de votre code et sélectionnez votre référentiel forké azure-pipelines-canary-k8s.
Sous l’onglet Configurer, choisissez Pipeline de démarrage.
Dans l’onglet Revue, remplacez le fichier YAML du pipeline par le code suivant.
trigger: - main pool: vmImage: ubuntu-latest variables: imageName: azure-pipelines-canary-k8s # name of ACR image dockerRegistryServiceConnection: azure-pipelines-canary-acr # name of ACR service connection imageRepository: 'azure-pipelines-canary-k8s' # name of image repository containerRegistry: example.azurecr.io # name of Azure container registry tag: '$(Build.BuildId)' stages: - stage: Build displayName: Build stage jobs: - job: Build displayName: Build pool: vmImage: ubuntu-latest steps: - task: Docker@2 displayName: Build and push image inputs: containerRegistry: $(dockerRegistryServiceConnection) repository: $(imageName) command: buildAndPush Dockerfile: app/Dockerfile tags: | $(tag)
Si la connexion de service Docker Registry que vous avez créée est associée à un référentiel de conteneurs nommé
example.azurecr.io
, l’image est définie surexample.azurecr.io/azure-pipelines-canary-k8s:$(Build.BuildId)
.Sélectionnez Enregistrer et exécuter et assurez-vous que le travail s’exécute avec succès.
Modifier le fichier manifeste
Dans votre fork de référentiel, modifiez manifests/deployment.yml pour remplacer <foobar>
par l’URL de votre référentiel de conteneurs, par exemple example.azurecr.io/azure-pipelines-canary-k8s
.
Configurer un déploiement continu
Configurez maintenant le déploiement continu, déployez la phase canary, et promouvez ou rejetez le canary via une approbation manuelle.
Créer un environnement
Vous pouvez effectuer un déploiement avec YAML ou Classic.
- Dans votre projet Azure DevOps, allez dans Pipelines>Environnements puis sélectionnez Créer un environnement ou Nouvel environnement.
- Sur le premier écran Nouvel environnement, entrez akscanary sous Nom, sélectionnez Kubernetes sous Ressource, puis sélectionnez Suivant.
- Remplissez l’écran Ressource Kubernetes comme suit :
- Fournisseur : Sélectionnez Azure Kubernetes Service.
- Abonnement Azure : Sélectionnez votre abonnement Azure.
- Cluster : sélectionnez votre cluster AKS.
- Espace de noms : Sélectionnez Nouveau et entrez canarydemo.
- Sélectionnez Valider et créer.
Ajouter la phase canary
Allez dans Pipelines, sélectionnez le pipeline que vous avez créé, et sélectionnez Modifier.
Remplacez l’intégralité du fichier YAML du pipeline par le code suivant.
Ce code modifie l’étape
Docker@2
que vous avez exécutée précédemment pour utiliser une phase, et ajoute deux étapes supplémentaires pour copier les répertoires manifests et misc en tant qu’artefacts pour les étapes consécutives.Le code déplace également certaines valeurs vers des variables pour une utilisation plus facile ultérieurement dans le pipeline. Dans la variable
containerRegistry
, remplacez<example>
par le nom de votre référentiel de conteneurs.trigger: - main pool: vmImage: ubuntu-latest variables: imageName: azure-pipelines-canary-k8s dockerRegistryServiceConnection: azure-pipelines-canary-acr imageRepository: 'azure-pipelines-canary-k8s' containerRegistry: <example>.azurecr.io tag: '$(Build.BuildId)' stages: - stage: Build displayName: Build stage jobs: - job: Build displayName: Build pool: vmImage: ubuntu-latest steps: - task: Docker@2 displayName: Build and push image inputs: containerRegistry: $(dockerRegistryServiceConnection) repository: $(imageName) command: buildAndPush Dockerfile: app/Dockerfile tags: | $(tag) - publish: manifests artifact: manifests - publish: misc artifact: misc
Ajoutez une autre phase à la fin du fichier YAML pour déployer la version canary. Remplacez les valeurs
my-resource-group
etmy-aks-cluster
par votre groupe de ressources et le nom de votre cluster Azure Kubernetes Service.trigger: - main pool: vmImage: ubuntu-latest variables: imageName: azure-pipelines-canary-k8s dockerRegistryServiceConnection: azure-pipelines-canary-acr imageRepository: 'azure-pipelines-canary-k8s' containerRegistry: yourcontainerregistry.azurecr.io #update with container registry tag: '$(Build.BuildId)' stages: - stage: Build displayName: Build stage jobs: - job: Build displayName: Build pool: vmImage: ubuntu-latest steps: - task: Docker@2 displayName: Build and push image inputs: containerRegistry: $(dockerRegistryServiceConnection) repository: $(imageName) command: buildAndPush Dockerfile: app/Dockerfile tags: | $(tag) - publish: manifests artifact: manifests - publish: misc artifact: misc - stage: DeployCanary displayName: Deploy canary dependsOn: Build condition: succeeded() jobs: - deployment: Deploycanary displayName: Deploy canary pool: vmImage: ubuntu-latest environment: 'akscanary' strategy: runOnce: deploy: steps: - task: KubernetesManifest@1 displayName: Create Docker Registry Secret inputs: action: 'createSecret' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' secretType: 'dockerRegistry' secretName: 'my-acr-secret' dockerRegistryEndpoint: 'azure-pipelines-canary-acr' - task: KubernetesManifest@1 displayName: Deploy to Kubernetes cluster inputs: action: 'deploy' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' strategy: 'canary' percentage: '25' manifests: | $(Pipeline.Workspace)/manifests/deployment.yml $(Pipeline.Workspace)/manifests/service.yml containers: '$(containerRegistry)/$(imageRepository):$(tag)' imagePullSecrets: 'my-acr-secret' - task: KubernetesManifest@1 displayName: Deploy Forbio to Kubernetes cluster inputs: action: 'deploy' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' manifests: '$(Pipeline.Workspace)/misc/*'
Sélectionnez Valider et enregistrer, et enregistrez le pipeline directement dans la branche principale.
Ajoutez une approbation manuelle pour promouvoir ou rejeter le déploiement de canaris
Vous pouvez intervenir manuellement avec YAML ou Classic.
- Créez un nouvel environnement Kubernetes appelé akspromote.
- Ouvrez le nouvel environnement akspromote depuis la liste des environnements, et sélectionnez Approbations dans l’onglet Approbations et vérifications.
- Sur l’écran Approbations, ajoutez votre propre compte utilisateur sous Approbateurs.
- Développez Avancé, et assurez-vous que Autoriser les approbateurs à approuver leurs propres exécutions est sélectionné.
- Sélectionnez Créer.
Ajouter des phases de promotion et de rejet au pipeline
Allez dans Pipelines, sélectionnez le pipeline que vous avez créé, et sélectionnez Modifier.
Ajoutez la phase
PromoteRejectCanary
suivante à la fin de votre fichier YAML qui promeut les modifications.- stage: PromoteRejectCanary displayName: Promote or Reject canary dependsOn: DeployCanary condition: succeeded() jobs: - deployment: PromoteCanary displayName: Promote Canary pool: vmImage: ubuntu-latest environment: 'akspromote' strategy: runOnce: deploy: steps: - task: KubernetesManifest@1 displayName: Create Docker Registry Secret for akspromote inputs: action: 'createSecret' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' secretType: 'dockerRegistry' secretName: 'my-acr-secret' dockerRegistryEndpoint: 'azure-pipelines-canary-acr' - task: KubernetesManifest@1 displayName: promote canary inputs: action: 'promote' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' strategy: 'canary' manifests: '$(Pipeline.Workspace)/manifests/*' containers: '$(containerRegistry)/$(imageRepository):$(tag)' imagePullSecrets: 'my-acr-secret' ```
Ajoutez la phase
RejectCanary
suivante à la fin du fichier qui annule les modifications.- stage: RejectCanary displayName: Reject canary dependsOn: PromoteRejectCanary condition: failed() jobs: - deployment: RejectCanary displayName: Reject Canary pool: vmImage: ubuntu-latest environment: 'akscanary' strategy: runOnce: deploy: steps: - task: KubernetesManifest@1 displayName: Create Docker Registry Secret for reject canary inputs: action: 'createSecret' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'kubernetes-testing' kubernetesCluster: 'my-aks-cluster' secretType: 'dockerRegistry' secretName: 'my-acr-secret' dockerRegistryEndpoint: 'azure-pipelines-canary-acr' - task: KubernetesManifest@1 displayName: Reject canary deployment inputs: action: 'reject' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' namespace: 'default' strategy: 'canary' manifests: '$(Pipeline.Workspace)/manifests/*' ```
Sélectionnez Valider et enregistrer, et enregistrez le pipeline directement dans la branche principale.
Déployer une version stable
Pour la première exécution du pipeline, la version stable des charges de travail et leurs versions basées ou canary n’existent pas dans le cluster. Déployez une version stable de la charge de travail sampleapp
comme suit.
Vous pouvez déployer une version stable avec YAML ou Classic.
- Dans app/app.py, remplacez
success_rate = 50
parsuccess_rate = 100
. Ce changement déclenche le pipeline, construit et pousse l’image vers le référentiel de conteneurs, et déclenche également la phaseDeployCanary
. - Étant donné que vous avez configuré une approbation sur l’environnement
akspromote
, la publication attend avant d’exécuter cette phase. Sur la page de résumé de l’exécution du build, sélectionnez Revue puis sélectionnez Approuver.
Une fois approuvé, le pipeline déploie la version stable de la charge de travail sampleapp
dans manifests/deployment.yml vers l’espace de noms.
Lancez le workflow canarien et rejetez l'approbation.
La version stable de la charge de travail sampleapp
existe maintenant dans le cluster. Ensuite, apportez la modification suivante à l'application de simulation.
- Dans app/app.py, remplacez
success_rate = 50
parsuccess_rate = 100
. Ce changement déclenche le pipeline, construit et pousse l’image vers le référentiel de conteneurs, et déclenche également la phaseDeployCanary
. - Étant donné que vous avez configuré une approbation sur l’environnement
akspromote
, la publication attend avant d’exécuter cette phase. - Sur la page de résumé de l'exécution de la construction, sélectionnez Examiner, puis Rejeter dans la boîte de dialogue qui s'affiche. Cela rejette le déploiement.
Une fois rejeté, le pipeline empêche le déploiement du code.
Nettoyage
Si vous ne comptez pas continuer à utiliser cette application, supprimez le groupe de ressources dans Azure portal et le projet dans Azure DevOps