Criar um pipeline de CI/CD para microsserviços no Kubernetes usando Azure DevOps e Helm

A criação de um processo de CI/CD (integração contínua e entrega contínua) confiável para uma arquitetura de microsserviços pode ser desafiadora. Cada equipe precisa liberar serviços de forma rápida e confiável, sem interromper outras equipes ou desestabilizar o aplicativo como um todo.

Este artigo descreve um exemplo de pipeline de CI/CD para implantar microsserviços no AKS (Serviço de Kubernetes do Azure). Cada equipe e projeto é diferente, sendo assim, não presuma que este artigo contém um conjunto de regras rígidas. Em vez disso, use-o como ponto de partida para criar seu próprio processo de CI/CD.

A lista a seguir resume as metas de um pipeline de CI/CD para microsserviços hospedados no Kubernetes:

  • As equipes podem criar e implantar os serviços de forma independente.
  • Alterações de código que passam o processo de CI são implantadas automaticamente em um ambiente semelhante à produção.
  • Cada estágio do pipeline impõe portões de qualidade.
  • Uma nova versão de um serviço pode ser implantada lado a lado com a versão anterior.

Para obter mais informações, consulte CI/CD para arquiteturas de microsserviços.

Suposições

Para este exemplo, aqui estão algumas suposições sobre a equipe de desenvolvimento e a base de código:

  • O repositório de código é único, com pastas organizadas por microsserviço.
  • A estratégia de ramificação da equipe se baseia no desenvolvimento com base em troncos.
  • A equipe usa branches de lançamento para gerenciar versões. Versões separadas são criadas para cada microsserviço.
  • O processo de CI/CD usa Azure Pipelines para compilar, testar e implantar os microsserviços no AKS.
  • As imagens de contêiner para todos os microsserviços são armazenadas em uma única instância de Registro de Contêiner do Azure compartilhada, com um repositório separado para cada microsserviço. Use as permissões do repositório ABAC do Registro de Contêiner do Azure para restringir a identidade de cada pipeline ao seu próprio repositório ou use registros separados quando forem necessários limites de confiança mais rigorosos.
  • A equipe usa gráficos Helm para empacotar cada microsserviço.
  • Um modelo de implantação por push é usado, em que Azure Pipelines e agentes associados executam implantações conectando-se diretamente ao cluster do AKS.

Essas suposições orientam muitos dos detalhes específicos do pipeline de CI/CD. No entanto, você pode adaptar a abordagem básica descrita aqui para outros processos, ferramentas e serviços, como GitHub Actions, Jenkins ou Docker Hub.

Alternatives

Ao escolher uma estratégia de CI/CD com o AKS, considere as seguintes alternativas comuns:

  • Em vez de usar o Helm como uma ferramenta de gerenciamento e implantação de pacotes, você pode usar o Kustomize, uma ferramenta de gerenciamento de configuração nativa do Kubernetes que apresenta uma maneira livre de modelos para personalizar e parametrizar a configuração do aplicativo.

  • Em vez de usar o Azure DevOps para repositórios Git e pipelines, você pode usar repositórios do GitHub para repositórios Git privados e públicos e GitHub Actions para pipelines de CI/CD.

    O GitHub Actions oferece integração com o AKS por meio de fluxos de trabalho iniciais e oferece suporte ao OpenID Connect (OIDC) para autenticação segura sem segredos no Azure.

  • Em vez de usar um modelo de implantação por push, considere gerenciar a configuração do Kubernetes em grande escala usando um GitOps (modelo de implantação pull). Um operador kubernetes no cluster, como Flux ou Argo CD , sincroniza o estado do cluster com base na configuração armazenada em um repositório Git. O GitOps elimina a necessidade de que os pipelines tenham acesso direto ao cluster, reduz a superfície de ataque e fornece recursos de autorrecuperação e detecção de desvio.

    Dica

    Ao avaliar modelos de implantação baseados em push e baseados em pull (GitOps), considere os requisitos da sua carga de trabalho. Implantações baseadas em push oferecem atualizações determinísticas e controle direto do pipeline, o que é adequado para práticas de implantação seguras. Implantações baseadas em pull (GitOps) oferecem consistência, auditabilidade e autorrecuperação, o que as torna ideais para ambientes em que os clusters precisam convergir para o estado desejado sem acesso direto do pipeline ao cluster.

Compilações de validação

Suponha que um desenvolvedor esteja trabalhando em um microsserviço chamado Serviço de Entrega. Ao desenvolver um novo recurso, o desenvolvedor verifica o código em um branch de recursos. Por convenção, as ramificações de funcionalidade são nomeadas feature/*.

Diagrama de um fluxo de trabalho da ramificação de funcionalidade.

O diagrama mostra duas linhas horizontais de ramificação do Git e um pipeline de compilação abaixo delas. No topo está o ramo principal, representado como uma linha horizontal. A ramificação feature/8150 diverge da principal. Esse ramo tem três pontos posicionados ao longo dele, chamados coletivamente de commits. De cada uma das três confirmações, uma seta aponta para baixo em direção a uma caixa na parte inferior do diagrama. A caixa está identificada como Build pipeline e contém o nome do pipeline ci-delivery-validation. Todas as três setas tracejadas convergem nesta única caixa do pipeline de build, indicando que cada commit na branch feature/8150 dispara uma execução do pipeline ci-delivery-validation.

O arquivo de definição de compilação inclui um gatilho que filtra por nome do branch e por caminho de origem:

trigger:
  batch: true
  branches:
    include:
    # for new release to production: release flow strategy
    - release/delivery/v*
    - refs/release/delivery/v*
    - main
    - feature/delivery/*
    - topic/delivery/*
  paths:
    include:
    - /src/shipping/delivery/

Quando você usa essa abordagem, cada equipe pode ter seu próprio pipeline de build. Somente o código que é adicionado à pasta /src/shipping/delivery aciona uma compilação do Serviço de Entrega. O envio por push confirma para uma ramificação que corresponde ao filtro aciona uma compilação de CI. Agora, no fluxo de trabalho, a compilação de CI executa uma verificação mínima no código:

  1. Compile o código.
  2. Execute os testes de unidade.

O objetivo é manter os tempos de compilação curtos para que o desenvolvedor possa receber comentários rapidamente. Quando o recurso estiver pronto para mesclar na principal, o desenvolvedor abrirá uma PR. Essa operação dispara outra compilação de CI que executa algumas verificações adicionais:

  1. Compile o código.
  2. Execute os testes de unidade.
  3. Execute SAST (teste de segurança de aplicativo estático) no código-fonte.
  4. Crie a imagem de contêiner do runtime.
  5. Execute exames de vulnerabilidade na imagem.

Diagrama mostrando ci-delivery-full no pipeline de compilação.

O diagrama mostra duas linhas horizontais de ramificação do Git e um pipeline de compilação abaixo delas. No topo está o ramo principal, representado como uma linha horizontal. Abaixo dela, a branch feature/8150 corre em paralelo e tem três pontos que representam commits. Na extremidade direita do ramo feature/8150, uma seta tracejada conecta-se a um ponto no ramo principal. Esse ponto é marcado com outro ponto rotulado como PR, indicando que uma solicitação de pull foi aberta em relação à principal. A partir do ponto do PR na ramificação principal, uma seta tracejada aponta para baixo até uma caixa rotulada como Pipeline de compilação, que contém o nome do pipeline ci-delivery-full. Essa linha ilustra que, ao abrir um pull request da branch de funcionalidade para a branch main, o pipeline ci-delivery-full é acionado, executando o conjunto estendido de verificações de CI.

Note

Em Azure Repos, um dos serviços em Azure DevOps, você pode definir políticas para proteger branches. Por exemplo, a política pode exigir um build de CI bem-sucedido e uma aprovação de um aprovador antes de uma mesclagem na principal.

Compilação completa de CI/CD

Quando a equipe estiver pronta para implantar uma nova versão do Serviço de Entrega, o gerenciador de lançamento criará uma ramificação do branch principal usando este padrão de nomenclatura: release/<microservice name>/<semver>. Por exemplo, release/delivery/v1.0.2.

Diagrama mostrando um ramo de lançamento que aciona um pipeline de compilação, seguido por um pipeline de lançamento.

A criação desse branch dispara um build completo de CI que executa todas as etapas anteriores e estas etapas:

  1. Envie a imagem do contêiner por push para o Registro de Contêiner. A imagem é marcada com o número de versão no nome do branch.
  2. Executar helm package para empacotar o gráfico Helm para o serviço. O gráfico também é marcado com um número de versão.
  3. Efetuar push do pacote do Helm para o Registro de Contêiner.

Se esse build for bem-sucedido, ele acionará um processo de implantação (CD) usando um pipeline de release do Azure Pipelines. Este fluxo contém as seguintes etapas:

  1. Implante o gráfico do Helm em um ambiente de QA.
  2. Um aprovador dá a sua aprovação antes que o pacote seja movido para o ambiente de produção. Confira Controle de implantação de versão usando aprovações.
  3. Reetiquete a imagem Docker para o namespace de produção no Registro de Contêiner. Por exemplo, se a etiqueta atual for myrepo.azurecr.io/delivery:v1.0.2, a etiqueta de produção será myrepo.azurecr.io/prod/delivery:v1.0.2.
  4. Implante o gráfico do Helm no ambiente de produção.

Mesmo em um monorepo, delimite essas tarefas a microsserviços individuais para que as equipes possam implantar de forma independente. O processo inclui algumas etapas manuais: aprovar PRs, criar branches de release e aprovar implantações no cluster de produção. As equipes de carga de trabalho podem automatizar essas etapas se desejarem.

Isolamento de ambientes

Você implanta serviços em vários ambientes, incluindo ambientes para desenvolvimento, teste de fumaça, teste de integração, teste de carga e produção. Esses ambientes precisam de algum nível de isolamento. No Kubernetes, você pode escolher entre isolamento físico e isolamento lógico. O isolamento físico é implantado em clusters separados. O isolamento lógico usa namespaces e políticas.

Nossa recomendação é criar um cluster de produção dedicado junto com um cluster separado para seus ambientes de desenvolvimento/teste. Use o isolamento lógico para separar ambientes dentro do cluster de desenvolvimento/teste. Os serviços implantados no cluster de desenvolvimento/teste nunca devem ter acesso a armazenamentos de dados que contêm dados de negócios.

Para impor o isolamento em um cluster, execute as seguintes etapas:

Autenticação e autorização

Use a autenticação sem segredo sempre que possível, tanto para os pipelines que implantam seus microsserviços quanto para as cargas de trabalho que esses pipelines implantam:

  • Federação de identidade de carga de trabalho para pipelines: Para o Azure Pipelines, use uma conexão de serviço de federação de identidade de carga de trabalho para autenticar no Azure sem armazenar segredos de entidades de serviço de longa duração. Para GitHub Actions, configure o OIDC para obter a mesma autenticação sem segredo.
  • ID de carga de trabalho do Microsoft Entra para cargas de trabalho implantadas: configure os microsserviços que o pipeline implanta para usar ID de carga de trabalho do Microsoft Entra em vez de injetar credenciais por meio de manifestos, valores do Helm ou segredos do Kubernetes. O ID de carga de trabalho federa contas de serviço do Kubernetes com o Microsoft Entra ID para que os pods possam autenticar em serviços do Azure (como o Azure Key Vault, o Registro de Contêiner ou o SQL do Azure) sem que o pipeline gerencie quaisquer segredos.

Gerenciamento de segredos

Nunca insira segredos (cadeias de conexão, chaves de API, senhas de banco de dados) diretamente no código-fonte, dockerfiles, arquivos de valores do Helm ou definições de pipeline. Em vez disso:

Importante

Evite armazenar credenciais de longa duração (segredos do cliente, certificados ou senhas) em variáveis de pipeline, variáveis de ambiente ou segredos do Kubernetes. Em vez disso, use identidades gerenciadas e credenciais federadas para reduzir a carga de rotação de credenciais e a superfície de ataque.

Processo de compilação

Quando possível, empacote o processo de compilação em um contêiner do Docker. Essa configuração permite que você crie artefatos de código usando o Docker sem configurar um ambiente de build em cada computador de build. Um processo de build em contêineres simplifica o dimensionamento do pipeline de CI ao adicionar novos agentes de build. Além disso, qualquer desenvolvedor na equipe pode criar o código executando o contêiner de build.

Usando builds de vários estágios no Docker, você pode definir o ambiente de build e a imagem de runtime em um único Dockerfile. Por exemplo, o Dockerfile a seguir cria um aplicativo .NET 10:

FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
USER app
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src/Fabrikam.Workflow.Service

COPY Fabrikam.Workflow.Service/Fabrikam.Workflow.Service.csproj .
RUN dotnet restore Fabrikam.Workflow.Service.csproj

COPY Fabrikam.Workflow.Service/. .
RUN dotnet build Fabrikam.Workflow.Service.csproj -c Release -o /app/build --no-restore

FROM build AS testrunner
WORKDIR /src/tests

COPY Fabrikam.Workflow.Service.Tests/*.csproj .
RUN dotnet restore Fabrikam.Workflow.Service.Tests.csproj

COPY Fabrikam.Workflow.Service.Tests/. .
ENTRYPOINT ["dotnet", "test", "--logger:trx"]

FROM build AS publish
RUN dotnet publish Fabrikam.Workflow.Service.csproj -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Fabrikam.Workflow.Service.dll"]

Este Dockerfile define vários estágios de compilação. Observe que o estágio nomeado base usa o .NET 10 ASP.NET imagem de runtime, enquanto o estágio nomeado build usa o SDK .NET 10 completo. O build estágio cria o projeto .NET. No entanto, o contêiner de tempo de execução final é criado a partir do base, que contém apenas o runtime e é significativamente menor do que a imagem completa do SDK.

Importante

A partir do .NET 8, as imagens oficiais de contêiner do .NET baseadas em Linux incluem um usuário não raiz chamado app. A USER app instrução no Dockerfile executa o contêiner como esse usuário sem privilégios, seguindo o princípio de privilégio mínimo. As imagens de contêiner do ASP.NET Core também alteraram sua porta padrão de escuta de 80 para 8080.

Criação de um executor de testes

Outra boa prática é executar testes de unidade no contêiner. Por exemplo, o código a seguir mostra parte de um Dockerfile que cria um executor de teste:

FROM build AS testrunner
WORKDIR /src/tests

COPY Fabrikam.Workflow.Service.Tests/*.csproj .
RUN dotnet restore Fabrikam.Workflow.Service.Tests.csproj

COPY Fabrikam.Workflow.Service.Tests/. .
ENTRYPOINT ["dotnet", "test", "--logger:trx"]

Um desenvolvedor pode usar esse Dockerfile para executar os testes localmente:

docker build . -t delivery-test:1 --target=testrunner
docker run delivery-test:1

O pipeline de CI também deve executar os testes como parte da etapa de verificação de compilação.

Esse arquivo usa o comando Docker ENTRYPOINT , não o comando Docker RUN , para executar os testes.

  • Se você usar o comando RUN, os testes serão executados toda vez que você criar a imagem. Se você usar ENTRYPOINT, os testes serão opcionais. Eles são executados somente quando você direciona explicitamente o estágio testrunner.
  • Um teste com falha não faz com que o comando build do Docker falhe. Esse comportamento permite distinguir falhas na compilação do contêiner de falhas de teste.
  • Os resultados do teste podem ser salvos em um volume montado.

Práticas recomendadas de contêineres

Aqui estão algumas outras práticas recomendadas a serem consideradas para contêineres:

  • Defina convenções em toda a organização para marcas de contêiner, controle de versão e convenções de nomenclatura para recursos implantados no cluster (por exemplo, pods e serviços). O uso dessas convenções pode facilitar o diagnóstico de problemas de implantação.
  • Durante o ciclo de desenvolvimento e teste, o processo de CI/CD cria muitas imagens de contêiner. Apenas algumas dessas imagens são candidatas à liberação, e apenas algumas dessas candidatas à liberação são promovidas para produção. Tenha uma estratégia de controle de versão clara para que você saiba quais imagens estão implantadas atualmente em produção e pode reverter facilmente para uma versão anterior, se necessário.
  • Sempre implante tags de versão de contêiner específicas, não latest.
  • Use namespaces no Registro de Contêiner para isolar imagens aprovadas para produção de imagens que ainda estão sendo testadas. Não mova uma imagem para o namespace de produção até que você esteja pronto para implantá-la em produção. Combinar essa prática com o versionamento semântico de imagens de contêineres pode reduzir as chances de implantar acidentalmente uma versão que não está aprovada para lançamento.
  • Siga o princípio de privilégio mínimo executando contêineres como um usuário sem privilégios. No Kubernetes, use Padrões de Segurança de Pod com Admissão de Segurança de Pod (que substituiu as Políticas de Segurança de Pod descontinuadas no Kubernetes 1.25) para aplicar restrições, como impedir que contêineres sejam executados como root. Use o perfil restricted para cargas de trabalho de produção.
  • Use imagens base mínimas ou sem distribuição (por exemplo, imagens baseadas em Alpine, imagens base ou sem distribuição do Azure Linux ou imagens .NET otimizadas) para reduzir a superfície de ataque de suas imagens de contêiner.
  • Para registros Premium, configure uma política de retenção do Container Registry para excluir manifestos sem tag. Para limpar tags por idade ou nome, agende uma tarefa do Container Registry para executar acr purge. Preserve as imagens que as implantações ativas e os planos de reversão referenciam.

Gráficos Helm

Considere usar o Helm para gerenciar a construção e implantação de serviços. Os seguintes recursos do Helm dão suporte a um pipeline de CI/CD:

  • Um único microsserviço geralmente é definido por vários objetos kubernetes. O Helm permite que esses objetos sejam empacotados em um único gráfico do Helm.
  • Você pode implantar um gráfico usando um único comando helm em vez de uma série de comandos kubectl.
  • Os gráficos são explicitamente versionados. Use o Helm para lançar uma versão, exibir versões e reverter para uma versão anterior. O Helm usa o controle de versão semântico para acompanhar atualizações e revisões.
  • Os gráficos do Helm usam modelos para evitar a duplicação de informações, como rótulos e seletores, em vários arquivos.
  • O Helm pode gerenciar dependências entre gráficos.
  • Você pode armazenar gráficos em um repositório Helm, como o Registro de Contêiner, e integrá-los ao pipeline de build.

Para obter mais informações, consulte Usar o Registro de Contêiner como um repositório helm para seus gráficos de aplicativos.

Um único microsserviço pode exigir vários arquivos de configuração do Kubernetes. Para atualizar um serviço, talvez seja necessário editar todos esses arquivos para atualizar seletores, rótulos e marcas de imagem. O Helm trata esses arquivos como um único pacote chamado gráfico e facilita a atualização dos arquivos YAML usando variáveis. O Helm usa uma linguagem de modelo (baseada em modelos Go) que permite que você escreva arquivos de configuração YAML parametrizados.

Por exemplo, veja abaixo parte de um arquivo YAML que define uma implantação:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "package.fullname" . | replace "." "" }}
  labels:
    app.kubernetes.io/name: {{ include "package.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
  annotations:
    kubernetes.io/change-cause: {{ .Values.reason }}

...

spec:
  template:
    spec:
      containers:
      - name: &package-container_name fabrikam-package
        image: {{ .Values.dockerregistry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        env:
        - name: LOG_LEVEL
          value: {{ .Values.log.level }}

Você pode ver que o nome da implantação, os rótulos e a especificação de contêiner usam parâmetros de modelo, que você fornece no momento da implantação. Por exemplo, na linha de comando:

helm install <release-name> oci://<registry>/<repository>/<package-chart-name> --version <desiredVersion> \
     --set image.tag=0.1.0 \
     --set image.repository=package \
     --set dockerregistry=$ACR_SERVER \
     --namespace backend

Embora um pipeline de CI/CD possa instalar um chart diretamente no Kubernetes, crie um arquivo de chart (arquivo .tgz) e envie o chart para um repositório Helm, como o Container Registry. Para obter mais informações, consulte Empacotar e implantar gráficos do Helm (tarefa HelmDeploy).

Revisões

Os charts do Helm sempre têm um número de versão que deve seguir o versionamento semântico. Um gráfico também pode ter um appVersion. Esse campo é opcional e não precisa estar relacionado à versão do gráfico. Algumas equipes podem querer fazer a versão de aplicativos separadamente das atualizações para os gráficos. Uma abordagem mais simples é usar um número de versão, portanto, há uma relação 1:1 entre a versão do gráfico e a versão do aplicativo. Dessa forma, você pode armazenar um gráfico por versão e implantar facilmente a versão desejada:

helm install <package-chart-name> --version <desiredVersion>

Outra boa prática é fornecer uma anotação de causa de alteração no modelo de implantação:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "delivery.fullname" . | replace "." "" }}
  labels:
     ...
  annotations:
    kubernetes.io/change-cause: {{ .Values.reason }}

Essa anotação permite que você exiba o campo de causa de alteração para cada revisão usando o kubectl rollout history comando. No exemplo anterior, a causa da alteração é fornecida como um parâmetro de gráfico do Helm.

kubectl rollout history deployments/delivery-v010 -n backend
deployment.apps/delivery-v010
REVISION  CHANGE-CAUSE
1         Initial deployment

Você também pode usar o comando helm list para exibir o histórico de revisões:

helm list -n backend
NAME              NAMESPACE   REVISION    UPDATED                                 STATUS      CHART               APP VERSION
delivery-v0.1.0   backend     1           2024-04-07 00:25:30.000000 +0000 UTC    deployed    delivery-v0.1.0     v0.1.0

Azure Pipelines

Azure Pipelines, um serviço em Azure DevOps, tem dois tipos de pipeline: pipelines de build e pipelines de lançamento. O pipeline de compilação executa o processo de CI e cria artefatos de compilação. Para uma arquitetura de microsserviços no Kubernetes, esses artefatos são as imagens de contêiner e os gráficos Helm que definem cada microsserviço. O pipeline de lançamento executa o processo de CD que implanta um microsserviço em um cluster.

Com base no fluxo de CI descrito anteriormente neste artigo, um pipeline de build pode consistir nas seguintes tarefas:

  1. Crie o contêiner do executor de testes usando a tarefa Docker.
  2. Execute os testes invocando docker run no contêiner do executor de testes usando a tarefa Docker.
  3. Publique os resultados do teste usando a PublishTestResults tarefa. Para obter mais informações, consulte Criar uma imagem.
  4. Execute o SAST no código-fonte.
  5. Crie o contêiner de runtime usando o docker build local e a tarefa Docker ou usando as compilações do Container Registry e a tarefa AzureCLI. Gere uma fatura de software de materiais (SBOM) para a imagem, por exemplo, usando a ferramenta Microsoft SBOM e publique-a como um artefato de pipeline associado ao resumo da imagem ou anexe-a à imagem no Registro de Contêiner.
  6. Execute a verificação de vulnerabilidade de imagem de contêiner (por exemplo, usando Microsoft Defender para contêineres ou uma ferramenta não Microsoft como o Trivy) para detectar vulnerabilidades conhecidas antes da publicação da imagem.
  7. Envie a imagem do contêiner para o Container Registry (ou outro registro de contêiner) usando a tarefa Docker ou AzureCLI.
  8. Assine a imagem enviada com um resumo imutável para garantir sua integridade e autenticidade. No Azure Pipelines, siga as orientações de assinatura do Notation.
  9. Empacote o gráfico do Helm usando a HelmDeploy tarefa.
  10. Envie o pacote Helm para o Container Registry (ou outro repositório Helm) usando a tarefa HelmDeploy.

A saída do pipeline de CI é uma imagem de contêiner pronta para produção e um gráfico Helm atualizado para o microsserviço. Nesse ponto, o pipeline de lançamento pode assumir o controle. Há um pipeline de lançamento exclusivo para cada microsserviço. O pipeline de lançamento está configurado para ter uma origem de gatilho definida para o pipeline de CI que publicou o artefato. Esse pipeline permite que você implante cada microsserviço de forma independente. O fluxo de lançamento executa as seguintes etapas:

  1. Implante o gráfico Helm em ambientes de desenvolvimento/QA/preparo. Você pode usar o helm upgrade comando com o --install sinalizador para dar suporte à primeira instalação e às atualizações subsequentes.
  2. Aguarde até que um aprovador aprove ou rejeite a implantação.
  3. Reetiquete a imagem do contêiner para lançamento.
  4. Envie a tag de lançamento para o registro do contêiner.
  5. Implante o gráfico Helm no cluster de produção. Use Ratificar com o Azure Policy para validar as assinaturas da imagem durante a admissão e configure separadamente uma política de imagens permitidas para restringir as imagens a registros confiáveis.

Note

Para permitir que o AKS extraia imagens do Container Registry sem segredos separados para pull de imagens, use a integração do AKS com o Container Registry para um registro que usa RBAC no escopo de todo o registro. Para um registro habilitado para ABAC, essa integração não é compatível. Em vez disso, atribua a função Container Registry Repository Reader à identidade gerenciada pelo kubelet do cluster.

Para obter mais informações sobre como criar um pipeline de lançamento, consulte Pipelines de lançamento, versões de rascunho e opções de versão.

O diagrama a seguir mostra o processo de CI/CD de ponta a ponta descrito neste artigo:

Diagrama do pipeline de CI/CD de ponta a ponta.

O diagrama mostra o pipeline completo de CI/CD, desde o commit do desenvolvedor até a implantação em produção. À esquerda, ele começa com um desenvolvedor enviando por push uma confirmação para um repositório Git. O repositório Git aciona o primeiro pipeline de CI. O pipeline de CI contém seis etapas sequenciais: Compilar código, Executar testes unitários, Compilar imagem, Enviar imagem, Pacote Helm e Enviar gráfico. Cada uma das três primeiras etapas tem uma caixa de saída correspondente à direita: Compilar código produz artefatos de código, Executar testes unitários produz resultados dos testes, e Criar imagem produz uma imagem de contêiner. A etapa Push image envia a imagem para o Container Registry. A etapa de pacote Helm produz um arquivo de gráfico. A etapa Enviar gráfico envia o gráfico para um repositório Helm. Um segundo pipeline de CI está abaixo do primeiro. Ele contém cinco etapas sequenciais: Implantar em QA, testes de integração, imagem de retag, imagem push e implantar em produção. A partir da etapa Implantação em QA, uma linha rotulada como atualização do Helm leva a um cluster do Kubernetes rotulado como cluster de teste/QA. À esquerda, abaixo do desenvolvedor, uma linha vai de um ícone de aprovador de QA até a etapa Implantar em produção. Essa linha é rotulada como aprovação. A partir da etapa Implantar em produção, uma linha identificada como Helm upgrade leva a um segundo ícone de cluster do Kubernetes identificado como cluster de produção.

alternativa ao GitHub Actions

Se sua equipe usar GitHub para o controle do código-fonte, GitHub Actions fornecerá uma plataforma de CI/CD equivalente. Além dos fluxos de trabalho iniciais e da autenticação OIDC mencionados anteriormente, considere estes recursos específicos do GitHub ao usar o AKS:

  • Ambientes e regras de proteção. Se o seu plano do GitHub e a visibilidade do repositório permitirem esse recurso, use ambientes do GitHub com revisores obrigatórios, temporizadores de espera e branches de implantação para implementar etapas de aprovação.
  • Verificação de contêiner. Use ações do GitHub Actions Marketplace para Trivy, Microsoft Defender para DevOps ou ferramentas semelhantes para verificação de imagens de contêiner diretamente no seu fluxo de trabalho.

Observabilidade e monitoramento

Implementar a observabilidade ao longo de todo o pipeline de CI/CD e do ambiente de execução:

  • Monitoramento do pipeline. Acompanhe as durações de build, as taxas de aprovação de teste, a frequência de implantação e as taxas de falha. Azure DevOps fornece análise interna. As GitHub Actions podem usar painéis que não sejam da Microsoft.
  • Monitoramento em tempo de execução. Use o serviço gerenciado do Azure Monitor para Prometheus e Espaço Gerenciado do Azure para Grafana para monitorar a integridade do cluster AKS e as métricas de carga de trabalho.
  • Telemetria do aplicativo. Instrumente seus microsserviços com Azure Monitor Application Insights para rastreamento distribuído, registro em log de solicitações e acompanhamento de dependência.
  • Alertando. Configure alertas para falhas na implantação, reinicializações de pods, taxas de erro elevadas e saturação de recursos para permitir uma resposta rápida a incidentes.

alinhamento com o Well-Architected Framework

Ao projetar seu pipeline de CI/CD para microsserviços no Kubernetes, considere os pilares do Azure Well-Architected Framework:

Pilar Considerations
Reliability Estratégias de reversão automatizadas, sondagens de integridade nas implantações, estratégias de implantação azul-verde ou canário, orçamentos de interrupção de pods.
Security Autenticação sem segredo (ID da carga de trabalho, OIDC), assinatura de imagem, segurança da cadeia de suprimentos, RBAC de menor privilégio, políticas de rede.
Otimização de custos Dimensionar corretamente os agentes de build, usar executores auto-hospedados efêmeros, implementar políticas de retenção de imagens do registro de contêineres e usar pools de nós spot apenas para cargas de trabalho não produtivas tolerantes a interrupções.
Excelência Operacional GitOps para implantações declarativas, Infraestrutura como Código, YAML (Pipeline como Código), observabilidade e automação de runbook.
Eficiência de desempenho Estágios paralelos de pipeline, cache de compilação (cache de camadas do Docker, cache de dependências), escalonamento horizontal automático de pods.

Contribuidores

A Microsoft mantém este artigo. Os colaboradores a seguir escreveram este artigo.

Autor principal:

  • Ray Kao | Engenheiro de soluções principal

Para ver perfis de LinkedIn não públicos, entre em LinkedIn.

Próximas Etapas