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
- Em seu projeto do Azure DevOps, vá para Configurações>do projeto Conexões do Serviço de Pipelines.>
- 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.
- 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
Em seu projeto do Azure DevOps, vá para Pipelines>Create Pipeline ou New pipeline.
Selecione GitHub para seu local de código e selecione seu repositório azure-pipelines-canary-k8s bifurcado.
Na guia Configurar, escolha Pipeline inicial.
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 comoexample.azurecr.io/azure-pipelines-canary-k8s:$(Build.BuildId)
.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.
- No seu projeto de DevOps do Azure, vá para Ambientes de Pipelines>e selecione Criar ambiente ou Novo ambiente.
- Na primeira tela Novo ambiente, digite akscanary em Nome, selecione Kubernetes em Recurso e selecione Avançar.
- 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.
- Selecione Validar e criar.
Adicione 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 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
Adicione outro estágio no final do arquivo YAML para implantar a versão canária. Substitua os valores
my-resource-group
pelomy-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/*'
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.
- Crie um novo ambiente 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 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' ```
Adicione o seguinte
RejectCanary
está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/*' ```
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.
- No app/app.py, mude
success_rate = 50
parasuccess_rate = 100
. Essa alteração aciona o pipeline, criando e enviando a imagem para o registro do contêiner, e também dispara oDeployCanary
palco. - 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.
- No app/app.py, mude
success_rate = 50
parasuccess_rate = 100
. Essa alteração aciona o pipeline, criando e enviando a imagem para o registro do contêiner, e também dispara oDeployCanary
palco. - 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 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.