Num pipeline clássico, o CI constrói o código e depois empurra o resultado para o cluster com kubectl apply ou helm upgrade. Funciona, mas o pipeline precisa de credenciais de administrador para cada cluster, ninguém consegue dizer com certeza o que está rodando sem perguntar ao cluster, e um deployment editado à mão se afasta em silêncio do que o repositório diz.
O GitOps inverte a direção. O Git guarda o estado desejado, e um agente dentro do cluster o puxa continuamente e faz o cluster ficar igual a ele. Este artigo explica os princípios, o fluxo com dois repositórios que a maioria dos times usa, como funcionam a promoção e o rollback, e desenha o fluxo inteiro.
Os quatro princípios
O projeto OpenGitOps, da CNCF, define o GitOps com quatro princípios:
- Declarativo: o estado desejado do sistema é expresso de forma declarativa.
- Versionado e imutável: esse estado é guardado de um jeito que mantém um histórico de versões completo e imutável, o que na prática significa Git.
- Puxado automaticamente: agentes de software puxam o estado desejado da fonte.
- Reconciliado continuamente: os agentes comparam o tempo todo o estado real com o desejado e corrigem a diferença.
O terceiro ponto é o que separa o GitOps de "deploy a partir de um pipeline que lê o Git". O cluster puxa; nada de fora empurra para dentro dele.
Dois repositórios: código e configuração
A maioria dos times separa dois tipos de mudança:
- O repositório da aplicação guarda o código-fonte. O CI o constrói, roda os testes, faz a varredura e publica uma tag de imagem imutável num registry.
- O repositório de configuração guarda os manifestos do Kubernetes, os values do Helm ou os overlays do Kustomize de cada ambiente. Ele descreve o que deve rodar onde, incluindo as tags de imagem.
A ligação entre os dois é uma mudança pequena e explícita: o CI, ou uma ferramenta de automação de imagens, abre um pull request no repositório de configuração que sobe a tag da imagem de staging. Esse pull request é o pedido de deploy, com revisão e trilha de auditoria.
O controller no cluster
O Argo CD e o Flux são os dois controllers GitOps mais usados. Os dois rodam dentro do cluster, consultam o repositório de configuração ou recebem webhooks dele, renderizam os manifestos, comparam com os objetos em execução e aplicam a diferença.
As configurações de reconciliação decidem o quão rígido o sistema é:
- Sync automático: aplicar commits novos sem ninguém apertar um botão.
- Pruning: apagar objetos que foram removidos do Git.
- Self-heal: desfazer mudanças feitas direto no cluster. Nas opções de sync automático do Argo CD, o self-heal é uma chave separada do auto-sync.
O self-heal é a configuração que transforma o Git na verdadeira fonte da verdade. Sem ele, um kubectl edit às 3 da manhã fica permanente e invisível.
Promoção e rollback
Os ambientes são pastas, overlays ou arquivos no repositório de configuração. Promover significa copiar uma versão de um para o próximo:
- O pull request sobe a tag de staging; staging se atualiza minutos depois do merge.
- Testes e verificações rodam contra staging.
- Um segundo pull request sobe produção para a mesma tag. Fazer o merge dele é o deploy em produção.
O rollback é um git revert desse merge. O controller vê a tag antiga e a aplica. Como todo o histórico está no Git, a pergunta "o que estava rodando em produção na terça passada às 14:00?" tem uma resposta exata.
Quem abre o pull request
Há duas formas comuns de ligar uma imagem nova ao repositório de configuração:
- O CI abre. A última etapa do pipeline clona o repositório de configuração, muda uma linha, faz commit num branch e abre um pull request. É explícito e fácil de depurar, e o pipeline só precisa de um token para aquele único repositório.
- Uma ferramenta de automação de imagens faz o commit. Os controllers de automação de imagens do Flux e o projeto Argo CD Image Updater conseguem observar um registry, escolher tags novas que atendam a uma política e gravá-las de volta no Git. Útil para ambientes de staging que devem sempre rodar o build mais recente.
Muitos times combinam os dois: a automação mantém staging em dia, enquanto as mudanças de produção sempre chegam como um pull request revisado, aberto por uma pessoa ou por um job de release. Seja qual for a escolha, escreva no diagrama, porque "como uma versão nova chega aqui?" é a primeira pergunta que todo mundo faz sobre um setup GitOps.
Uma release de ponta a ponta
Siga a versão 1.8.0 de um serviço shop, do commit até a produção:
- Um desenvolvedor faz o merge de uma mudança no repositório da aplicação. O CI roda os testes, constrói a imagem, faz a varredura e publica
shop:1.8.0no registry. - O CI abre no repositório de configuração um pull request que muda a tag de staging de 1.7.3 para 1.8.0. Um revisor aprova e faz o merge.
- Em um ou dois minutos, o controller percebe o commit novo, renderiza os manifestos de staging e atualiza o deployment. O Kubernetes sobe pods novos, que puxam a imagem do registry.
- Os smoke tests passam em staging. A responsável pela release abre um segundo pull request que coloca produção em 1.8.0.
- Depois desse merge, produção é atualizada do mesmo jeito. Se as taxas de erro subirem, reverter o commit de merge traz a 1.7.3 de volta.
Em nenhum momento algo fora do cluster precisou de credenciais do cluster, e cada etapa deixou um commit para trás.
Secrets
Secrets em texto puro não podem ir para o Git. Abordagens comuns:
- Criptografados no Git, com ferramentas como Sealed Secrets ou SOPS, descriptografados só dentro do cluster.
- Referências no Git, valores em outro lugar, com um operador como o External Secrets, que lê de um gerenciador de secrets.
Em qualquer caso, o repositório de configuração continua revisável e os valores dos secrets nunca aparecem num diff.
O diagrama de arquitetura
Conteúdo do diagrama
- Developer
- App repo: code
- CI: build, test, scan
- Container registry
- Config repo: desired state
- Kubernetes cluster
- GitOps controller
- staging
- shop v1.8.0
- production
- shop v1.7.3
- push
- trigger
- image 1.8.0
- PR: bump staging tag
- pull every few minutes
- apply
- nodes pull images
Como ler:
- Linha de cima, o build: um desenvolvedor faz push no repositório da aplicação, o CI constrói e testa a imagem 1.8.0 e a publica no registry.
- Meio: o CI abre um pull request que sobe a tag de staging no repositório de configuração. É o único lugar em que o CI toca no deploy.
- Embaixo, o cluster: o controller GitOps faz pull do repositório de configuração (tracejado) e o aplica ao namespace de staging, que agora roda a 1.8.0, e à produção, que continua na 1.7.3 até o merge do próprio pull request. Os nós puxam as imagens do registry (pontilhado).
- O bloco Markdown enuncia as regras do fluxo: promoção por pull request, rollback por revert, desvios desfeitos pelo self-heal.
O que muda para o time
- O CI perde as credenciais do cluster. É o cluster que busca; o pipeline só precisa de acesso de escrita a um repositório.
- As revisões cobrem os deploys. Quem fez o deploy de quê, quando e por quê fica no histórico de pull requests.
- Os desvios ficam visíveis. O controller mostra os recursos fora de sincronia em vez de escondê-los.
- A depuração muda de lugar. "Por que isso não foi para o ar?" se responde com o status de sync e os eventos do controller, então deixe-os visíveis para quem faz o merge.
O que colocar num diagrama GitOps
- Os dois repositórios, e o pull request que os conecta.
- A direção do pull, do controller para o repositório de configuração, não do pipeline para o cluster.
- Cada ambiente com a versão que roda, para que a promoção fique visível.
- As configurações de sync: auto-sync, prune, self-heal.
O diagrama de estratégias de deploy mostra como o próprio rollout pode ser canary ou blue-green, o diagrama de pipeline de CI/CD cobre as etapas de build em detalhe, o diagrama de arquitetura do Kubernetes mostra o próprio cluster, e o artigo de YAML do Kubernetes para diagrama mostra como transformar os manifestos do repositório de configuração numa imagem.
Monte no Archboard
- Entre com Google ou GitHub e crie um diagrama.
- Adicione uma Pessoa do pack Modelo C4, dois nós Repositório e um Pipeline de CI/CD do pack DevOps, e um Registro do pack Docker.
- Adicione uma Moldura do pack Básico para o cluster, com um Contêiner para o controller GitOps.
- Adicione dois nós Namespace do pack Kubernetes com um Deployment em cada um, rotulado com a versão que roda.
- Desenhe o pull como uma aresta tracejada do controller para o repositório de configuração e adicione um bloco Markdown do pack Básico com as regras do fluxo.
O exemplo usa 12 nós de diagrama e fica dentro do plano Free.
Perguntas frequentes
Qual a diferença entre GitOps e CI/CD? O CI/CD constrói, testa e entrega o software. O GitOps é uma forma de fazer a parte da entrega: o estado desejado fica no Git e um agente no ambiente de destino o puxa e o reconcilia, em vez de um pipeline empurrar as mudanças para dentro.
Devo usar Argo CD ou Flux? Os dois implementam o mesmo modelo. O Argo CD tem uma interface web rica e visões centradas em aplicações; o Flux é um conjunto de controllers combináveis que muitos times operam inteiramente pelo Git e pela CLI.
Preciso de repositórios separados para a aplicação e a configuração? É uma convenção comum, não uma regra. Repositórios separados mantêm limpo o histórico de deploys e deixam a configuração mudar sem reconstruir o código.
Como faço rollback com GitOps? Reverta o commit que mudou a versão no repositório de configuração. O controller aplica o estado anterior.
Como os secrets são tratados no GitOps? Guarde-os criptografados no Git, ou guarde referências no Git e deixe um operador buscar os valores num gerenciador de secrets dentro do cluster.