Tutorial: Use uma estratégia de implantação canária para Kubernetes
Azure DevOps Services | Azure DevOps Server 2022
Este guia passo a passo aborda como usar a tarefa de manifesto do Kubernetes com a estratégia canary
. 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.
Use o fluxo de trabalho associado para implantar o código e comparar as implantações de aplicativos de base e canárias. Com base na avaliação, você decide se deseja promover ou rejeitar 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 AKS (Serviço de Kubernetes do Azure) ou um cluster que tem contas locais desabilitadas, uma conexão de serviço do Azure Resource Manager é uma maneira melhor de se conectar.
Pré-requisitos
Um projeto do Azure DevOps 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 Azure Kubernetes Service (AKS) implantado. Você pode anexar o cluster do AKS ao cluster do Registro de Contêiner do Azure quando você implanta o cluster AKS ou posteriormente.
Uma conta do GitHub. Criar uma conta gratuita do GitHub
Um fork do repositório https://github.com/MicrosoftDocs/azure-pipelines-canary-k8s do 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 efetuar o processo. Para obter mais informações, confira Acesso ao repositórios do GitHub.
Arquivos do repositório do GitHub
O repositório do GitHub contém os seguintes arquivos:
Arquivo | Descrição |
---|---|
./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 variável success_rate . |
./app/Dockerfile | Usado para construir a imagem a cada alteração para app.py. Cada alteração dispara o pipeline de compilação para criar a imagem e enviá-la por push para o registro de contêiner. |
./manifests/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 base e canária das cargas de trabalho. |
./manifests/service.yml | Cria o serviço sampleapp . Esse serviço roteia solicitações para os pods gerados pelas implantações estáveis, de base e canária. |
./misc/fortio.yml | Configura uma implantação do 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 é roteado para pods nas três implantações: estável, de base e canária. |
Criar conexões de serviço
- No seu projeto do Azure DevOps, vá para Configurações do projeto>Pipelines>Conexões de serviço.
- Crie uma conexão de serviço do Registro do Docker chamada azure-pipelines-canary-acr associada à instância do Registro de Contêiner do Azure.
- Crie uma conexão de serviço do Azure Resource Manager com a identidade de carga de trabalho chamada azure-pipelines-canary-k8s para seu grupo de recursos.
Adicione a fase de build
Em seu projeto do Azure DevOps, acesse Pipelines>Criar Pipeline ou Novo pipeline.
Selecione GitHub para o local do código e selecione o repositório azure-pipelines-canary-k8s.
Na guia Configurar, escolha Pipeline inicial.
Na guia Review 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 comoexample.azurecr.io/azure-pipelines-canary-k8s:$(Build.BuildId)
.Selecione Salvar e executar e verifique se o trabalho foi executado com êxito.
Editar o arquivo de manifesto
No fork do repositório, edite manifests/deployment.yml para substituir <foobar>
pela URL do registro de contêiner, por exemplo example.azurecr.io/azure-pipelines-canary-k8s
.
Configurar a implantaçã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 da aprovação manual.
Criar um ambiente
Você pode implantar com YAML ou o Clássico.
- Em seu projeto do Azure DevOps, acesse Ambientes de Pipelines> e selecione Criar ambiente ou Novo ambiente.
- Na primeira tela Novo ambiente, insira akscanary em Nome, selecione Kubernetes em Recurso e selecione Avançar.
- Preencha a tela de recursos do Kubernetes da seguinte maneira:
- Em Provedor: selecione Serviço de Kubernetes do Azure.
- Assinatura do Azure: selecione sua assinatura do Azure.
- Cluster: selecione seu cluster do AKS.
- Namespace: Selecione Novo e insira canarydemo.
- Selecione Validar e criar.
Adicionar o estágio canário
Vá para Pipelines, selecione o pipeline que você criou e selecione Editar.
Substitua todo o pipeline YAML pelo código a seguir.
Esse código altera a etapa
Docker@2
que você executou anteriormente para usar um estágio e adiciona mais duas etapas para copiar os manifestos e diretórios diversos como artefatos para estágios consecutivos a serem usados.O código também move alguns valores para variáveis para facilitar o uso posterior no pipeline. Na variável
containerRegistry
, substitua<example>
pelo nome do 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
Adicione outro estágio no final do arquivo YAML para implantar a versão canário. Substitua os valores
my-resource-group
emy-aks-cluster
com seu grupo de recursos e o nome do cluster do Serviço de 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/*'
Selecione Validar e salvar e salve o pipeline diretamente no branch principal.
Adicionar aprovação manual para promover ou rejeitar a implantação canários
Você pode intervir manualmente com o YAML ou o Clássico.
- Crie um novo ambiente do Kubernetes chamado akspromote.
- Abra o novo ambiente akspromote na lista de ambientes e selecione Aprovações na guia Aprovações e verificações.
- Na tela Aprovações, adicione sua própria conta de usuário em Aprovadores.
- Expanda Avançado e certifique-se de que a opção Permitir que os aprovadores aprovem suas próprias execuções esteja selecionada.
- Selecione Criar.
Adicionar estágios de promoção e rejeição ao pipeline
Vá para Pipelines, selecione o pipeline que você criou e selecione Editar.
Adicione o seguinte estágio
PromoteRejectCanary
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' ```
Adicione o seguinte estágio
RejectCanary
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/*' ```
Selecione Validar e salvar e salve o pipeline diretamente no branch 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 canário não existem no cluster. Implante uma versão estável da carga de trabalho sampleapp
da seguinte maneira.
Você pode implantar uma versão estável com o YAML ou o Clássico.
- Em app/app.py, altere
success_rate = 50
parasuccess_rate = 100
. Essa alteração dispara o pipeline, criando e enviando a imagem para o registro de contêiner e também dispara o estágioDeployCanary
. - Como você configurou uma aprovação no ambiente
akspromote
, a versão aguarda antes de executar esse estágio. Na página de resumo da execução de compilação, selecione Examinar e, em seguida, selecione Aprovar.
Depois de aprovado, o pipeline implanta a versão estável da carga de trabalho sampleapp
em manifestos/deployment.yml no namespace.
Iniciar o fluxo de trabalho canário e rejeitar a aprovação
A versão estável da carga de trabalho sampleapp
agora existe no cluster. Em seguida, faça esta alteração no aplicativo de simulação.
- Em app/app.py, altere
success_rate = 50
parasuccess_rate = 100
. Essa alteração dispara o pipeline, criando e enviando a imagem para o registro de contêiner e também dispara o estágioDeployCanary
. - Como você configurou uma aprovação no ambiente
akspromote
, a versão aguarda antes de executar esse estágio. - Na página de resumo da execução de build, selecione Analisar e, em seguida, selecione Rejeitar na caixa de diálogo subsequente. Isso rejeita a implantação.
Depois de rejeitado, o pipeline impede a implantação do código.
Limpar
Se você não quiser continuar a usar esse aplicativo, exclua o grupo de recursos no portal do Azure e o projeto no Azure DevOps com as etapas a seguir.