Partilhar via


Tutorial: Usar uma estratégia de implantação canary para Kubernetes

Serviços de DevOps do Azure | Azure DevOps Server 2022

Este guia passo a passo aborda como usar a tarefa de manifesto do Kubernetes com a canary estratégia. Uma estratégia de implantação canária implanta novas versões de um aplicativo ao lado de versões estáveis de produção.

Você usa o fluxo de trabalho associado para implantar o código e comparar as implantações de linha de base e de aplicativo canário. Com base na avaliação, você decide se promove ou rejeita a implantação canária.

Este tutorial usa conexões de serviço do Docker Registry e do Azure Resource Manager para se conectar aos recursos do Azure. Para um cluster privado do Serviço Kubernetes do Azure (AKS) ou um cluster que tenha contas locais desabilitadas, uma conexão de serviço do Azure Resource Manager é uma maneira melhor de se conectar.

Pré-requisitos

  • Um projeto de DevOps do Azure com pelo menos permissões de usuário .

  • Uma conta do Azure. Crie uma conta gratuitamente.

  • Uma instância do Registro de Contêiner do Azure com privilégios de push.

  • Um cluster do Serviço Kubernetes do Azure (AKS) implantado. Você pode anexar o cluster AKS ao cluster de registro do Contêiner do Azure quando implantar o cluster AKS ou posteriormente.

  • Uma conta GitHub. Crie uma conta gratuita no GitHub.

  • Uma bifurcação do https://github.com/MicrosoftDocs/azure-pipelines-canary-k8s repositório GitHub.

    Importante

    Durante os procedimentos a seguir, você pode ser solicitado a criar uma conexão de serviço do GitHub ou ser redirecionado para o GitHub para entrar, instalar o Azure Pipelines ou autorizar o Azure Pipelines. Siga as instruções na tela para concluir o processo. Para obter mais informações, consulte Acesso a repositórios do GitHub.

Arquivos de repositório do GitHub

O repositório GitHub contém os seguintes arquivos:

Ficheiro Description
./app/app.py Um servidor web simples, baseado em Flask. O arquivo configura um contador personalizado para o número de respostas boas e ruins, com base no valor da success_rate variável.
./app/Dockerfile Usado para construir a imagem a cada alteração para app.py. Cada alteração aciona o pipeline de compilação para criar a imagem e enviá-la por push para o registro do contêiner.
./manifestos/deployment.yml Contém a especificação da sampleapp carga de trabalho de implantação correspondente à imagem publicada. Use esse arquivo de manifesto para a versão estável do objeto de implantação e para derivar as variantes de linha de base e canárias das cargas de trabalho.
./manifestos/service.yml Cria o sampleapp serviço. Esse serviço roteia solicitações para os pods girados pelas implantações estável, linha de base e canário.
./misc/fortio.yml Configura uma implantação fortio. Essa implantação é uma ferramenta de teste de carga que envia um fluxo de solicitações para o serviço implantado sampleapp . O fluxo de solicitação roteia para pods sob as três implantações: estável, linha de base e canário.

Criar conexões de serviço

  1. Em seu projeto do Azure DevOps, vá para Configurações>do projeto Conexões do Serviço de Pipelines.>
  2. Crie uma conexão de serviço do Registro do Docker chamada azure-pipelines-canary-acr associada à sua instância do Registro de Contêiner do Azure.
  3. Crie uma conexão de serviço do Azure Resource Manager com identidade de carga de trabalho chamada azure-pipelines-canary-k8s para seu grupo de recursos.

Adicionar o estágio de construção

  1. Em seu projeto do Azure DevOps, vá para Pipelines>Create Pipeline ou New pipeline.

  2. Selecione GitHub para seu local de código e selecione seu repositório azure-pipelines-canary-k8s bifurcado.

  3. Na guia Configurar, escolha Pipeline inicial.

  4. Na guia Revisão, substitua o pipeline YAML pelo código a seguir.

    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)
    

    Se a conexão do serviço de registro do Docker que você criou estiver associada a um registro de contêiner chamado example.azurecr.io, a imagem será definida como example.azurecr.io/azure-pipelines-canary-k8s:$(Build.BuildId).

  5. Selecione Salvar e executar e verifique se o trabalho é executado com êxito.

Editar o arquivo de manifesto

Na bifurcação do repositório, edite manifestos/deployment.yml para substituir <foobar> pelo URL do registro do contêiner, por exemplo example.azurecr.io/azure-pipelines-canary-k8s.

Set up continuous deployment (Configurar a implementação contínua)

Agora, configure a implantação contínua, implante o estágio canário e promova ou rejeite o canário por meio de aprovação manual.

Criar um ambiente

Você pode implantar com YAML ou Classic.

  1. No seu projeto de DevOps do Azure, vá para Ambientes de Pipelines>e selecione Criar ambiente ou Novo ambiente.
  2. Na primeira tela Novo ambiente, digite akscanary em Nome, selecione Kubernetes em Recurso e selecione Avançar.
  3. Preencha a tela de recursos do Kubernetes da seguinte maneira:
    • Provedor: selecione Serviço Kubernetes do Azure.
    • Assinatura do Azure: selecione sua assinatura do Azure.
    • Cluster: Selecione seu cluster AKS.
    • Namespace: Selecione Novo e digite canarydemo.
  4. Selecione Validar e criar.

Adicione o estágio canário

  1. Vá para Pipelines, selecione o pipeline que você criou e selecione Editar.

  2. Substitua todo o pipeline YAML pelo código a seguir.

    Esse código altera a etapa executada Docker@2 anteriormente para usar um estágio e adiciona mais duas etapas para copiar os manifestos e diretórios misc como artefatos para estágios consecutivos a serem usados.

    O código também move alguns valores para variáveis para facilitar o uso posteriormente no pipeline. containerRegistry Na variável, substitua <example> pelo nome do seu registro de contêiner.

    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. Adicione outro estágio no final do arquivo YAML para implantar a versão canária. Substitua os valores my-resource-group pelo my-aks-cluster seu grupo de recursos e pelo nome do cluster do Serviço Kubernetes do Azure.

    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. Selecione Validar e salvar e salve o pipeline diretamente na ramificação principal.

Adicionar aprovação manual para promover ou rejeitar a implantação canária

Você pode intervir manualmente com YAML ou Classic.

  1. Crie um novo ambiente Kubernetes chamado akspromote.
  2. Abra o novo ambiente akspromote na lista de ambientes e selecione Aprovações na guia Aprovações e verificações .
  3. Na tela Aprovações, adicione sua própria conta de usuário em Aprovadores.
  4. Expanda Avançado e certifique-se de que a opção Permitir que os aprovadores aprovem suas próprias execuções esteja selecionada.
  5. Selecione Criar.

Adicionar estágios de promoção e rejeição ao pipeline

  1. Vá para Pipelines, selecione o pipeline que você criou e selecione Editar.

  2. Adicione a seguinte PromoteRejectCanary etapa no final do arquivo YAML que promove as alterações.

    - 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. Adicione o seguinte RejectCanaryestágio no final do arquivo que reverte as alterações.

    - 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. Selecione Validar e salvar e salve o pipeline diretamente na ramificação principal.

Implantar uma versão estável

Para a primeira execução do pipeline, a versão estável das cargas de trabalho e suas versões de linha de base ou canary não existem no cluster. Implante uma versão estável da sampleapp carga de trabalho da seguinte maneira.

Você pode implantar uma versão estável com YAML ou Classic.

  1. No app/app.py, mude success_rate = 50 para success_rate = 100. Essa alteração aciona o pipeline, criando e enviando a imagem para o registro do contêiner, e também dispara o DeployCanary palco.
  2. Como você configurou uma aprovação no akspromote ambiente, a liberação aguarda antes de executar esse estágio. Na página de resumo da execução da compilação, selecione Rever e, em seguida, selecione Aprovar.

Uma vez aprovado, o pipeline implanta a sampleapp versão estável da carga de trabalho em manifestos/deployment.yml no namespace.

Iniciar o fluxo de trabalho canário e rejeitar a aprovação

A versão estável da sampleapp carga de trabalho agora existe no cluster. Em seguida, faça a seguinte alteração no aplicativo de simulação.

  1. No app/app.py, mude success_rate = 50 para success_rate = 100. Essa alteração aciona o pipeline, criando e enviando a imagem para o registro do contêiner, e também dispara o DeployCanary palco.
  2. Como você configurou uma aprovação no akspromote ambiente, a liberação aguarda antes de executar esse estágio.
  3. Na página de resumo da execução da compilação, selecione Revisão e, em seguida, selecione Rejeitar na caixa de diálogo subsequente. Isso rejeita a implantação.

Uma vez rejeitado, o pipeline impede a implantação do código.

Limpeza

Se você não vai continuar a usar esse aplicativo, exclua o grupo de recursos no portal do Azure e o projeto no Azure DevOps.