Delen via


Zelfstudie: Een canary-implementatiestrategie gebruiken voor Kubernetes

Azure DevOps Services | Azure DevOps Server 2022

In deze stapsgewijze handleiding wordt beschreven hoe u de Kubernetes-manifesttaak gebruikt met de canary strategie. Met een canary-implementatiestrategie worden nieuwe versies van een toepassing naast stabiele, productieversies geïmplementeerd.

U gebruikt de bijbehorende werkstroom om de code te implementeren en de basislijn- en canary-app-implementaties te vergelijken. Op basis van de evaluatie besluit u of u de canary-implementatie wilt promoveren of afwijzen.

In deze zelfstudie worden Docker Registry- en Azure Resource Manager-serviceverbindingen gebruikt om verbinding te maken met Azure-resources. Voor een privécluster van Azure Kubernetes Service (AKS) of een cluster waarvoor lokale accounts zijn uitgeschakeld, is een Azure Resource Manager-serviceverbinding een betere manier om verbinding te maken.

Vereisten

GitHub-opslagplaatsbestanden

De GitHub-opslagplaats bevat de volgende bestanden:

Bestand Beschrijving
./app/app.py Een eenvoudige, op Flask gebaseerde webserver. Het bestand stelt een aangepast teller in voor het aantal goede en slechte antwoorden, op basis van de waarde van de success_rate variabele.
./app/Dockerfile Wordt gebruikt voor het bouwen van de installatiekopieën met elke wijziging in app.py. Elke wijziging activeert de build-pijplijn om de installatiekopieën te bouwen en naar het containerregister te pushen.
./manifesten/deployment.yml Bevat de specificatie van de sampleapp implementatieworkload die overeenkomt met de gepubliceerde installatiekopieën. U gebruikt dit manifestbestand voor de stabiele versie van het implementatieobject en voor het afleiden van de basislijn en canary-varianten van de workloads.
./manifesten/service.yml Hiermee maakt u de sampleapp service. Met deze service worden aanvragen naar de pods gerouteerd die zijn opgebouwd door de stabiele, basislijn- en canary-implementaties.
./misc/fortio.yml Hiermee stelt u een fortio-implementatie in. Deze implementatie is een hulpprogramma voor belastingstests waarmee een stroom aanvragen naar de geïmplementeerde sampleapp service wordt verzonden. De aanvraagstroom routeert naar pods onder de drie implementaties: stabiel, basislijn en kanarie.

Serviceverbindingen maken

  1. Ga in uw Azure DevOps-project naar Project settings>Pipelines>Service-verbindingen.
  2. Maak een Docker Registry-serviceverbinding met de naam azure-pipelines-canary-acr die is gekoppeld aan uw Azure Container Registry-exemplaar.
  3. Maak een Azure Resource Manager-serviceverbinding met workloadidentiteit met de naam azure-pipelines-canary-k8s voor uw resourcegroep.

De buildfase toevoegen

  1. Ga in uw Azure DevOps-project naar Pijplijnen pijplijn> maken of Nieuwe pijplijn.

  2. Selecteer GitHub voor uw codelocatie en selecteer uw forked azure-pipelines-canary-k8s-opslagplaats .

  3. Kies Starter-pijplijn op het tabblad Configureren.

  4. Vervang op het tabblad Controleren de YAML-pijplijn door de volgende code.

    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)
    

    Als de Docker-registerserviceverbinding die u hebt gemaakt, is gekoppeld aan een containerregister met de naam example.azurecr.io, wordt de installatiekopieën ingesteld example.azurecr.io/azure-pipelines-canary-k8s:$(Build.BuildId)op .

  5. Selecteer Opslaan en uitvoeren en zorg ervoor dat de taak wordt uitgevoerd.

Het manifestbestand bewerken

Bewerk manifesten/deployment.yml in uw opslagplaats fork om bijvoorbeeld te vervangen door <foobar> de URL example.azurecr.io/azure-pipelines-canary-k8svan uw containerregister.

Doorlopende implementatie instellen

Stel nu continue implementatie in, implementeer de canary-fase en promoveer of negeer de kanarie via handmatige goedkeuring.

Een omgeving maken

U kunt implementeren met YAML of klassiek.

  1. Ga in uw Azure DevOps-project naar Pijplijnomgevingen> en selecteer vervolgens Omgeving maken of Nieuwe omgeving.
  2. Voer in het eerste scherm Nieuwe omgeving akscanary in onder Naam, selecteer Kubernetes onder Resource en selecteer Volgende.
  3. Vul het kubernetes-resourcescherm als volgt in:
    • Provider: Selecteer Azure Kubernetes Service.
    • Azure-abonnement: selecteer uw Azure-abonnement.
    • Cluster: Selecteer uw AKS-cluster.
    • Naamruimte: Selecteer Nieuw en voer canarydemo in.
  4. Selecteer Valideren en maken.

De canary-fase toevoegen

  1. Ga naar Pijplijnen, selecteer de pijplijn die u hebt gemaakt en selecteer Bewerken.

  2. Vervang de hele YAML-pijplijn door de volgende code.

    Deze code wijzigt de Docker@2 stap die u eerder hebt uitgevoerd om een fase te gebruiken en voegt nog twee stappen toe om de manifesten en misc directory's te kopiëren als artefacten voor opeenvolgende fasen die moeten worden gebruikt.

    De code verplaatst ook enkele waarden naar variabelen voor eenvoudiger gebruik verderop in de pijplijn. Vervang in de containerRegistry variabele door <example> de naam van het containerregister.

    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
    
  3. Voeg een andere fase toe aan het einde van het YAML-bestand om de canary-versie te implementeren. Vervang de waarden my-resource-group en my-aks-cluster door de resourcegroep en de naam van het Azure Kubernetes Service-cluster.

    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/*'
    
  4. Selecteer Valideren en opslaan en sla de pijplijn rechtstreeks op in de hoofdbranch.

Handmatige goedkeuring toevoegen voor het promoten of afwijzen van kanarie-implementatie

U kunt handmatig tussenbeide komen met YAML of klassiek.

  1. Maak een nieuwe Kubernetes-omgeving met de naam akspromote.
  2. Open de nieuwe akspromote-omgeving in de lijst met omgevingen en selecteer Goedkeuringen op het tabblad Goedkeuringen en controles.
  3. Voeg in het scherm Goedkeuringen uw eigen gebruikersaccount toe onder Goedkeurders.
  4. Vouw Geavanceerd uit en zorg ervoor dat goedkeurders hun eigen uitvoeringen goedkeuren, is geselecteerd.
  5. Selecteer Maken.

Niveau verhogen en weigeren aan de pijplijn toevoegen

  1. Ga naar Pijplijnen, selecteer de pijplijn die u hebt gemaakt en selecteer Bewerken.

  2. Voeg de volgende PromoteRejectCanary fase toe aan het einde van uw YAML-bestand dat de wijzigingen bevordert.

    - 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'
        ```
    
    
  3. Voeg de volgende RejectCanaryfase toe aan het einde van het bestand waarmee de wijzigingen worden teruggedraaid.

    - 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/*'
        ```
    
  4. Selecteer Valideren en opslaan en sla de pijplijn rechtstreeks op in de hoofdbranch.

Een stabiele versie implementeren

Voor de eerste uitvoering van de pijplijn, de stabiele versie van de workloads en de bijbehorende basislijn- of canary-versies, bestaat deze niet in het cluster. Implementeer als volgt een stabiele versie van de sampleapp workload.

U kunt een stabiele versie implementeren met YAML of Klassiek.

  1. Ga in app/app.py naar success_rate = 50 success_rate = 100. Deze wijziging activeert de pijplijn, het bouwen en pushen van de installatiekopieën naar het containerregister en activeert ook de DeployCanary fase.
  2. Omdat u een goedkeuring voor de akspromote omgeving hebt geconfigureerd, wacht de release voordat deze fase wordt uitgevoerd. Selecteer Controleren op de overzichtspagina van de builduitvoering en selecteer Vervolgens Goedkeuren.

Zodra deze is goedgekeurd, implementeert de pijplijn de stabiele versie van de sampleapp workload in manifesten/deployment.yml naar de naamruimte.

De canary-werkstroom initiëren en de goedkeuring weigeren

De stabiele versie van de sampleapp workload bestaat nu in het cluster. Breng vervolgens de volgende wijziging aan in de simulatietoepassing.

  1. Ga in app/app.py naar success_rate = 50 success_rate = 100. Deze wijziging activeert de pijplijn, het bouwen en pushen van de installatiekopieën naar het containerregister en activeert ook de DeployCanary fase.
  2. Omdat u een goedkeuring voor de akspromote omgeving hebt geconfigureerd, wacht de release voordat deze fase wordt uitgevoerd.
  3. Selecteer Controleren op de overzichtspagina van de builduitvoering en selecteer vervolgens Weigeren in het volgende dialoogvenster. Hiermee wordt de implementatie geweigerd.

Nadat de pijplijn is geweigerd, voorkomt u dat de code-implementatie wordt uitgevoerd.

Opschonen

Als u deze toepassing niet meer gaat gebruiken, verwijdert u de resourcegroep in Azure Portal en het project in Azure DevOps.