Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
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 é um monorepo, 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 o Registro de Contêiner Azure permissões de repositório ABAC para definir o escopo de cada identidade de pipeline para seu próprio repositório ou usar registros separados em que são necessários limites de confiança mais fortes.
- 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 Azure DevOps para repositórios e pipelines do Git, você pode usar GitHub repositórios git privados e públicos e GitHub Actions para pipelines de CI/CD.
GitHub Actions fornece integração com o AKS com fluxos de trabalho interações e dá suporte ao OIDC (OpenID Connect) para autenticação segura e sem segredo para 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 pipelines terem acesso direto ao cluster, reduz a superfície de ataque e fornece recursos de detecção de auto-recuperação e de descompasso.
Dica
Ao avaliar modelos de implantação baseados em push versus GitOps (baseados em pull), considere seus requisitos de carga de trabalho. Implantações baseadas em push oferecem atualizações determinísticas e controle de pipeline direto, o que atende a práticas de implantação seguras. As implantações baseadas em pull (GitOps) oferecem consistência, auditoria e auto-recuperação, o que as torna ideais para ambientes em que os clusters precisam se reconciliar com um estado desejado sem acesso direto de pipeline para 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/*.
O diagrama mostra duas linhas de branch git horizontais e um pipeline de build abaixo delas. Na parte superior está o branch principal, representado como uma linha horizontal. O branch do recurso/8150 diverge da principal. Esse branch tem três pontos posicionados nele, confirmações rotuladas coletivamente. 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 é rotulada como pipeline build e contém o nome do pipeline ci-delivery-validation. Todas as três setas tracejadas convergem nesta única caixa de pipeline de build, indicando que cada confirmação para o branch do recurso/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 é verificado na /src/shipping/delivery pasta dispara um build do Serviço de Entrega. O envio de commits para uma ramificação que corresponde ao filtro aciona um build de CI. Agora, no fluxo de trabalho, a compilação de CI executa uma verificação mínima no código:
- Compile o código.
- 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:
- Compile o código.
- Execute os testes de unidade.
- Execute SAST (teste de segurança de aplicativo estático) no código-fonte.
- Crie a imagem de contêiner do runtime.
- Execute exames de vulnerabilidade na imagem.
O diagrama mostra duas linhas de branch git horizontais e um pipeline de build abaixo delas. Na parte superior está o branch principal, representado como uma linha horizontal. Abaixo dele, o branch do recurso/8150 é executado paralelamente a ele e tem três pontos que representam confirmações. Na extremidade direita do branch do recurso/8150, uma seta tracejada conecta-se a um ponto no branch principal. Esse ponto é marcado com outro ponto rotulado como PR, indicando que uma solicitação de pull foi aberta em relação à principal. Do ponto de PR no branch principal, uma seta tracejada aponta para baixo para um pipeline de build rotulado por caixa, que contém o nome do pipeline ci-delivery-full. Essa linha ilustra que abrir uma solicitação de pull do branch de recursos para o principal dispara o pipeline completo de ci-delivery, que executa 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.
O diagrama mostra três linhas de branch git horizontais e dois pipelines abaixo delas. No meio está o branch principal, representado como uma linha horizontal. Abaixo da principal está a ramificação do recurso/8150, que tem três pontos que representam confirmações. O branch do recurso/8150 conecta-se ao branch principal em um ponto de mesclagem rotulada, indicando que o branch de recursos é mesclado na principal. Acima e à direita do branch principal, uma nova versão/entrega rotulada por branch/v1.0.2 se estende à direita. Esse branch de versão se origina do principal em um ponto à direita da mesclagem. Na ramificação de versão/entrega/v1.0.2, uma linha tracejada aponta para baixo até uma caixa rotulada ci-delivery-full, que está acima do pipeline de build do rótulo. À direita do ci-delivery-full, uma seta horizontal aponta para uma segunda caixa rotulada cd-delivery, que está acima do pipeline de lançamento do rótulo.
A criação desse branch dispara um build completo de CI que executa todas as etapas anteriores e estas etapas:
- 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.
- Executar
helm packagepara empacotar o gráfico Helm para o serviço. O gráfico também é marcado com um número de versão. - Enviar o pacote do Helm para o registro de containers.
Se esse build for bem-sucedido, ele disparará um processo de CD (implantação) usando um pipeline de versão Azure Pipelines. Este pipeline contém as seguintes etapas:
- Implante o gráfico do Helm em um ambiente de QA.
- 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 release usando aprovações.
- Registre novamente a imagem do 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. - Implante o gráfico do Helm no ambiente de produção.
Mesmo em um monorepo, escopo essas tarefas para microsserviços individuais para que as equipes possam implantar de forma independente. O processo inclui algumas etapas manuais: aprovação de PRs, criação de branches de versão e aprovação de 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:
-
Namespaces: use namespaces do Kubernetes para separar logicamente ambientes (por exemplo,
dev, ,staging,qa). - Políticas de rede: aplique políticas de rede do Kubernetes para negar a comunicação pod a pod entre namespaces.
- Cotas de recursos: aplique cotas de recursos por namespace para evitar problemas de vizinhos barulhentos em clusters compartilhados.
- Microsoft Entra ID integração: combine Microsoft Entra ID autenticação com o RBAC do Kubernetes e Microsoft Entra ID para controlar quais usuários e grupos Microsoft Entra podem acessar cada namespace.
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 Azure Pipelines, use uma conexão de serviço de federação de identidade de carga de trabalho para autenticar para Azure sem armazenar segredos de entidade 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. A ID da carga de trabalho federa contas de serviço do Kubernetes com Microsoft Entra ID para que os pods possam se autenticar em serviços de Azure (como Azure Key Vault, Registro de Contêiner ou SQL do Azure) sem que o pipeline gerencie 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:
- Armazene segredos no Key Vault.
- Use o provedor de Key Vault para o driver CSI do Repositório de Segredos para montar segredos diretamente em pods como volumes ou variáveis de ambiente. Essa abordagem mantém segredos fora dos objetos kubernetes
Secret, que são codificados em base64, não criptografados por padrão. - Para segredos de pipeline, use Key Vault integração com segredos Azure Pipelines ou GitHub Actions.
- Habilite Key Vault proteção contra exclusão e limpeza reversível para se proteger contra exclusão de segredo acidental ou mal-intencionada.
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 de contêiner de .NET oficiais 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. ASP.NET Core imagens de contêiner também alteraram sua porta de escuta padrão 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ê usarENTRYPOINT, os testes serão aceitos. Eles são executados somente quando você direciona explicitamente o estágiotestrunner. - Um teste com falha não faz com que o comando
builddo Docker falhe. Esse comportamento permite distinguir falhas de build de 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 ao lançamento, e apenas alguns desses candidatos à versão são promovidos à 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 controle de versão semântico de imagens de contêiner pode reduzir as chances de implantar acidentalmente uma versão que não é 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 a admissão de Segurança de Pod (que substituiu as políticas de segurança de pod preteridas no Kubernetes 1.25) para impor restrições como impedir que contêineres sejam executados como raiz. Use o
restrictedperfil para cargas de trabalho de produção. - Use imagens base mínimas ou sem distribuição (por exemplo, imagens baseadas em Alpine, Azure imagens base ou sem distribuição do Linux ou imagens .NET chiseled) para reduzir a superfície de ataque de suas imagens de contêiner.
- Para registros Premium, configure uma política de retenção do Registro de Contêiner para excluir manifestos não registrados. Para limpar marcas por idade ou nome, agende uma tarefa do Registro de Contêiner que executa a limpeza de acr. Preservar imagens que as implantações ativas e os planos de reversão fazem referência.
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 gráfico diretamente no Kubernetes, crie um arquivo de gráfico (arquivo.tgz) e envie o gráfico por push para um repositório helm, como o Registro de Contêiner. Para obter mais informações, consulte Empacotar e implantar gráficos do Helm (tarefa HelmDeploy).
Revisões
Os gráficos do Helm sempre têm um número de versão que deve usar controle de versão 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:
- Crie o contêiner do executor de teste usando a
Dockertarefa. - Execute os testes invocando
docker runo contêiner do executor de teste usando aDockertarefa. - Publique os resultados do teste usando a
PublishTestResultstarefa. Para obter mais informações, consulte Criar uma imagem. - Execute SAST no código-fonte.
- Crie o contêiner de runtime usando local
docker builde aDockertarefa ou usando builds do Registro de Contêiner e aAzureCLItarefa. 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. - 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.
- Envie a imagem do contêiner para o Registro de Contêiner (ou outro registro de contêiner) usando a tarefa ou
AzureCLIaDockertarefa. - Assine a imagem enviada por push por resumo imutável para garantir sua integridade e autenticidade. Para Azure Pipelines, siga as diretrizes de assinatura de Notação.
- Empacote o gráfico do Helm usando a
HelmDeploytarefa. - Envie o pacote do Helm para o Registro de Contêiner (ou outro repositório helm) usando a
HelmDeploytarefa.
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 com uma fonte de gatilho definida no 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:
- Implante o gráfico Helm em ambientes de desenvolvimento/QA/preparo. Você pode usar o
helm upgradecomando com o--installsinalizador para dar suporte à primeira instalação e às atualizações subsequentes. - Aguarde até que um aprovador aprove ou rejeite a implantação.
- Retag da imagem de contêiner para lançamento.
- Envie a tag de lançamento para o registro do contêiner.
- Implante o gráfico Helm no cluster de produção. Use o Ratify com Azure Policy para validar assinaturas de imagem durante a admissão e configurar separadamente uma política de imagens permitidas para restringir imagens a registros confiáveis.
Note
Para permitir que o AKS efetue pull de imagens do Registro de Contêiner sem segredos de pull de imagem separados, use a integração do AKS paraContainer-Registry para um registro que usa o RBAC em todo o Registro. Para um registro habilitado para ABAC, essa integração não tem suporte. Em vez disso, atribua a Container Registry Repository Reader função à identidade gerenciada por 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:
GitHub Actions alternativa
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 inicial e da autenticação OIDC observados anteriormente, considere esses recursos específicos GitHub quando você direcionar o AKS:
- Ambientes e regras de proteção. Se o plano GitHub e a visibilidade do repositório dão suporte a eles, use GitHub ambientes com revisores, temporizadores de espera e branches de implantação necessários para implementar portões de aprovação.
- Verificação de contêiner. Use GitHub Actions ações do marketplace para Trivy, Microsoft Defender para DevOps ou ferramentas semelhantes para verificação de imagens de contêiner diretamente em seu fluxo de trabalho.
Observabilidade e monitoramento
Implementar a observabilidade em todo o pipeline de CI/CD e o ambiente de runtime:
- Monitoramento de 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. GitHub Actions pode usar dashboards não Microsoft.
- Monitoramento de runtime. Use Azure Monitor serviço gerenciado para Prometheus e Espaço Gerenciado do Azure para Grafana para monitorar a integridade do cluster do 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.
- Alerta Configure alertas para falhas de implantação, reinicializações de pod, altas taxas de erro e saturação de recursos para habilitar a resposta rápida a incidentes.
alinhamento do 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, investigações de integridade em implantações, estratégias de versão azul-verde ou canário, orçamentos de interrupção do pod. |
| 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 | Agentes de build de dimensionamento correto, usando executores auto-hospedados efêmeros, implementando políticas de retenção de imagem do Registro de Contêiner e usando pools de nós spot apenas para cargas de trabalho de não produção 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 de pipeline paralelos, cache de build (cache de camada do Docker, cache de dependência), dimensionamento automático de pod horizontal. |
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
- Adotar uma estratégia de ramificação do Git
- O que é Azure Pipelines?
- Pipelines de lançamento, versões de rascunho e opções de versão
- Controle de implantação usando aprovações
- Introdução ao Registro de Contêiner do Azure
- ID de carga de trabalho do Microsoft Entra com o AKS
- Provedor do Azure Key Vault para o Secrets Store CSI Driver
- DevSecOps no AKS