DEV Community

Cover image for Argo CD a fundo como funciona o GitOps na prática
Kauê Matos
Kauê Matos

Posted on

Argo CD a fundo como funciona o GitOps na prática

O Argo CD resolve um problema simples e caro: garantir que o que está rodando no Kubernetes é exatamente o que está versionado no Git. Ele é um controlador declarativo de entrega contínua (CD) para Kubernetes, mantido pela comunidade Argo e projeto graduado da CNCF.

Sem uma ferramenta assim, o fluxo típico é um pipeline de CI que termina com kubectl apply ou helm upgrade contra o cluster. Isso funciona até o dia em que alguém altera um recurso na mão, o pipeline falha pela metade ou o cluster perde o estado e ninguém sabe qual era a versão "correta". É o chamado configuration drift.

Neste artigo você vai ver:

  • o que é GitOps e por que o modelo pull muda o jogo;
  • como o Argo CD é construído por dentro, componente por componente;
  • o ciclo de reconciliação, do commit até o recurso saudável no cluster;
  • os recursos principais (Application, AppProject, ApplicationSet) com exemplos em YAML;
  • sync policies, waves e hooks para controlar a ordem do deploy;
  • multi-cluster, segurança, escala e observabilidade;
  • um comparativo com Flux e com pipelines push, e um exemplo prático do zero.

GitOps em poucas palavras

GitOps é tratar o Git como a única fonte de verdade do estado desejado da infraestrutura e das aplicações, e deixar um agente dentro do cluster trazer a realidade até esse estado. O Argo CD é uma implementação desse agente.

Os quatro princípios, resumidos:

  1. Declarativo: o sistema inteiro é descrito em manifestos (YAML, Helm, Kustomize), não em scripts de passo a passo.
  2. Versionado e imutável: cada mudança é um commit, com autor, revisão por pull request e histórico para auditoria.
  3. Aplicado automaticamente: um agente puxa o estado aprovado, sem que alguém precise rodar comandos contra o cluster.
  4. Reconciliado continuamente: se o estado real divergir do desejado, o agente detecta e corrige (ou ao menos avisa).

Push versus pull

A diferença central está em quem tem a credencial do cluster. No modelo push, o pipeline de CI fica de fora e precisa de acesso administrativo ao cluster para aplicar mudanças. No modelo pull, o agente já está dentro do cluster e só precisa de permissão de leitura no repositório Git.

Aspecto Push (CI faz o deploy) Pull (Argo CD)
Credenciais do cluster Ficam no sistema de CI Ficam só dentro do cluster
Detecção de drift Não existe, só no próximo deploy Contínua
Rollback Reexecutar pipeline antigo Reverter o commit no Git
Quem aplica Job efêmero do pipeline Controlador sempre ativo
Superfície de ataque Maior (chave do cluster exposta ao CI) Menor

Arquitetura: os componentes por dentro

O Argo CD é um conjunto de serviços pequenos, cada um com uma responsabilidade, que rodam juntos em um namespace (normalmente argocd) e conversam com o repositório Git e com os clusters de destino.

[embedded content: arquitetura do Argo CD · 7 componentes e 2 sistemas externos]

O caminho principal é este: o Application Controller pede ao Repo Server os manifestos renderizados a partir do Git, compara com o que existe no cluster e aplica a diferença. O API Server serve a interface, a CLI e a API, e delega o login ao Dex.

Componente Workload padrão Responsabilidade
argocd-server Deployment Expõe a UI, a CLI e a API; aplica RBAC e valida tokens
argocd-repo-server Deployment Mantém clones locais dos repositórios e gera os manifestos finais (Helm, Kustomize, plugins)
argocd-application-controller StatefulSet Observa as aplicações e o cluster, calcula o diff, executa a sincronização e avalia a saúde dos recursos
argocd-redis Deployment Cache do estado dos recursos e dos manifestos renderizados, para reduzir leituras no Git e na API do Kubernetes
argocd-dex-server Deployment Intermedia o login com provedores de identidade externos
argocd-applicationset-controller Deployment Gera e mantém objetos Application a partir de ApplicationSet
argocd-notifications-controller Deployment Envia alertas quando uma aplicação muda de estado

Uma consequência importante do desenho: o Repo Server só gera manifestos, e quem toca nos clusters é o Application Controller. Isso permite escalar cada parte separadamente e limitar o que cada uma enxerga.

Ciclo de reconciliação: do commit ao cluster

A cada ciclo, o Argo CD compara o Git com o cluster antes de aplicar qualquer coisa, e só age quando encontra diferença e a política permite.

[embedded content: ciclo de reconciliação · 6 etapas e 2 decisões]

Há duas formas de o Argo CD descobrir que algo mudou. A primeira é o polling do repositório, a cada 3 minutos por padrão. A segunda é um webhook (GitHub, GitLab, Bitbucket e outros), que avisa na hora e dispensa a espera. Mudanças feitas direto no cluster são percebidas de outro jeito: o Application Controller observa os recursos vivos continuamente.

Dois eixos de status

Na interface aparecem dois status independentes, e confundi-los é um erro comum.

Eixo Pergunta que responde Valores principais
Sync status O cluster está igual ao Git? Synced, OutOfSync, Unknown
Health status Os recursos estão funcionando? Healthy, Progressing, Degraded, Suspended, Missing, Unknown

Uma aplicação pode estar Synced e Degraded ao mesmo tempo: o manifesto foi aplicado exatamente como está no Git, mas o Pod não sobe. O contrário também vale, com OutOfSync e Healthy, quando alguém alterou algo à mão e o serviço continua funcionando.

O Argo CD sabe avaliar a saúde de recursos nativos (Deployment, StatefulSet, Ingress, Job e outros). Para CRDs, é possível escrever uma verificação de saúde customizada em Lua.

Para ver a diferença antes de sincronizar, use argocd app diff <aplicação>.

Recursos principais: Application, AppProject e ApplicationSet

O Argo CD é configurado por CRDs do próprio Kubernetes, então a configuração do Argo CD também pode (e deve) viver no Git. Três recursos cobrem quase todo o uso.

Application

A Application liga uma origem (repositório, revisão e caminho) a um destino (cluster e namespace). É a unidade que o Argo CD sincroniza e cujo status ele mostra.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: loja-api
  namespace: argocd
spec:
  project: loja
  source:
    repoURL: https://github.com/minha-org/loja-gitops.git
    targetRevision: main
    path: apps/api/overlays/producao
  destination:
    server: https://kubernetes.default.svc
    namespace: loja
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
Enter fullscreen mode Exit fullscreen mode

O campo path pode apontar para YAML puro, um chart Helm, uma pasta Kustomize ou um plugin de geração de manifestos.

AppProject

O AppProject é a fronteira de segurança e de organização. Ele define de quais repositórios um grupo de aplicações pode ler, para quais clusters e namespaces pode implantar e quais tipos de recurso são permitidos.

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: loja
  namespace: argocd
spec:
  sourceRepos:
    - https://github.com/minha-org/loja-gitops.git
  destinations:
    - server: https://kubernetes.default.svc
      namespace: loja
  clusterResourceWhitelist: []
  namespaceResourceBlacklist:
    - group: ""
      kind: ResourceQuota
Enter fullscreen mode Exit fullscreen mode

Com clusterResourceWhitelist vazio, o time dono do projeto não consegue criar recursos de escopo de cluster (como ClusterRole), mesmo que escreva isso no repositório.

ApplicationSet

O ApplicationSet gera várias Application a partir de um modelo e de generators. É a resposta para "preciso da mesma aplicação em 30 clusters" ou "uma aplicação por pasta do repositório".

Generator O que ele faz
List Itera sobre uma lista fixa de valores
Cluster Gera uma aplicação por cluster cadastrado no Argo CD
Git (diretórios) Gera uma aplicação por pasta encontrada no repositório
Git (arquivos) Lê arquivos JSON/YAML e usa o conteúdo como parâmetros
Pull Request Cria um ambiente efêmero por pull request aberto
Matrix / Merge Combina dois generators (por exemplo, cluster × diretório)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: servicos
  namespace: argocd
spec:
  generators:
    - git:
        repoURL: https://github.com/minha-org/loja-gitops.git
        revision: main
        directories:
          - path: apps/*
  template:
    metadata:
      name: "{{path.basename}}"
    spec:
      project: loja
      source:
        repoURL: https://github.com/minha-org/loja-gitops.git
        targetRevision: main
        path: "{{path}}"
      destination:
        server: https://kubernetes.default.svc
        namespace: "{{path.basename}}"
Enter fullscreen mode Exit fullscreen mode

Com isso, criar uma nova pasta em apps/ basta para que uma nova aplicação apareça no Argo CD, sem tocar em nenhum outro arquivo.

Sync policies, waves e hooks

Por padrão a sincronização é manual: o Argo CD mostra OutOfSync e espera alguém clicar em Sync. Três mecanismos controlam o quanto disso é automático e em que ordem as coisas acontecem.

Política de sincronização automática

Quando syncPolicy.automated está ativo, o Argo CD aplica sozinho qualquer diferença entre o Git e o cluster. Duas opções mudam bastante o comportamento:

  • prune: true: remove do cluster recursos que foram apagados do Git. Sem isso, o que sai do repositório continua rodando.
  • selfHeal: true: desfaz alterações feitas diretamente no cluster (por exemplo, um kubectl edit em um Deployment) e volta ao estado do Git.

Outras opções úteis ficam em syncOptions, como CreateNamespace=true, ServerSideApply=true e PruneLast=true. Há também retry, com backoff exponencial, para tentar de novo quando uma sincronização falha por motivo transitório.

Sync waves

Os recursos de uma aplicação são aplicados em ordem de wave, definida pela anotação argocd.argoproj.io/sync-wave. O padrão é 0, valores menores vêm antes e valores negativos são permitidos. O Argo CD só avança para a próxima wave quando todos os recursos da atual estão saudáveis.

metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "-1"   # roda antes dos recursos da wave 0
Enter fullscreen mode Exit fullscreen mode

Um uso típico: Namespace e CRD na wave -2, ConfigMap e Secret na wave -1, o Deployment na wave 0 e um Ingress na wave 1.

Hooks

Hooks são recursos (normalmente Job) que rodam em fases específicas da sincronização, marcados com a anotação argocd.argoproj.io/hook.

Hook Quando roda Uso comum
PreSync Antes de aplicar os manifestos Migração de banco de dados
Sync Junto com a aplicação dos manifestos Passos que dependem da ordem das waves
PostSync Depois que tudo ficou saudável Teste de fumaça, notificação
SyncFail Quando a sincronização falha Limpeza, alerta

A anotação argocd.argoproj.io/hook-delete-policy define quando o Job é apagado (HookSucceeded, HookFailed ou BeforeHookCreation). Se um PreSync falhar, a sincronização é interrompida e os manifestos principais não são aplicados, o que protege contra subir uma versão nova com o banco no estado antigo.

Multi-cluster, RBAC, SSO e segurança

Uma única instância do Argo CD pode gerenciar vários clusters, e é isso que o torna útil em empresas com ambientes separados para desenvolvimento, homologação e produção.

Multi-cluster

O cluster onde o Argo CD roda se chama in-cluster (https://kubernetes.default.svc). Para adicionar outros, usa-se argocd cluster add <contexto>, que cria uma ServiceAccount no cluster remoto e guarda o token em um Secret no namespace argocd. Há dois desenhos comuns:

  • Hub e spokes: um Argo CD central gerencia todos os clusters. É mais simples de operar, mas esse cluster central passa a guardar credenciais de todos os outros e vira um alvo importante.
  • Uma instância por cluster (ou por ambiente): cada Argo CD gerencia só o próprio cluster. Isola o impacto de uma falha ou invasão, ao custo de operar várias instâncias.

RBAC e SSO

A autenticação delega para um provedor externo via Dex (embutido) ou OIDC direto, com suporte a GitHub, GitLab, Google, Okta, Azure AD, Keycloak e LDAP. A autorização usa uma política no estilo Casbin, no ConfigMap argocd-rbac-cm:

p, role:dev-loja, applications, get, loja/*, allow
p, role:dev-loja, applications, sync, loja/*, allow
g, grupo-loja-devs, role:dev-loja
Enter fullscreen mode Exit fullscreen mode

As linhas p definem permissões (papel, recurso, ação, objeto) e as linhas g ligam grupos do provedor de identidade a papéis. O objeto loja/* restringe o acesso às aplicações do projeto loja.

Segredos

O Argo CD não resolve o problema de guardar segredos no Git, ele só aplica o que está lá. Como Secret do Kubernetes é apenas Base64, as abordagens mais comuns são:

Abordagem Como funciona Observação
Sealed Secrets O segredo é cifrado com a chave pública de um controlador e só o cluster consegue abrir Cifrado no próprio Git
External Secrets Operator O Git guarda só a referência; o operador busca o valor no AWS Secrets Manager, Vault etc. Nenhum valor no Git
SOPS com plugin Arquivos cifrados com KMS ou age, decifrados na hora de gerar manifestos Exige configurar o repo server

Outros cuidados

  • Use AppProject para restringir repositórios, destinos e tipos de recurso por time.
  • Desative o usuário admin local depois de configurar o SSO.
  • Use um repositório de leitura (deploy key ou token só de leitura) para o Argo CD.
  • Habilite TLS no argocd-server e limite o acesso à API por rede, já que ele tem poder sobre todos os clusters conectados.

Escala, alta disponibilidade e observabilidade

O Argo CD é em grande parte stateless: o estado vive em objetos do Kubernetes, e o que pesa quando a escala cresce é o Application Controller, que mantém em memória o estado dos clusters que gerencia (documentação de alta disponibilidade).

[embedded content: sharding de clusters no Application Controller · exemplo ilustrativo]

Onde ajustar cada componente

  • Application Controller: quando ele gerencia muitos clusters e consome muita memória, o caminho é distribuir os clusters entre réplicas. Aumente replicas no StatefulSet e repita o número na variável ARGOCD_CONTROLLER_REPLICAS. Cada réplica usa duas filas, uma para reconciliação (milissegundos) e outra para sincronização (segundos), e o número de processors pode ser aumentado para muitas aplicações.
  • Repo Server: guarda em cache os manifestos gerados, por padrão por 24 horas, usando o SHA do commit como chave. Ele mantém um clone local por repositório, o que pode ficar lento em monorepos com muitas aplicações; a anotação argocd.argoproj.io/manifest-generate-paths ajuda a evitar regenerar manifestos à toa.
  • API Server e Redis: o projeto oferece manifests de alta disponibilidade, com réplicas do servidor e uma variante de Redis em HA.

Em uso real, a pesquisa de 2025 com usuários do Argo CD, conduzida pela CNCF e pelos mantenedores, reportou que 97% usam em produção e 42% gerenciam mais de 500 aplicações por instância, e que quase 60% dos clusters dos respondentes usam Argo CD.

Observabilidade

Cada componente expõe métricas no formato Prometheus. Três delas cobrem a maior parte dos painéis e alertas:

Métrica O que mostra Uso típico
argocd_app_info Status de sync e de saúde de cada aplicação Alerta para aplicações OutOfSync ou Degraded por muito tempo
argocd_app_sync_total Quantidade de sincronizações e seus resultados Taxa de falha de deploy
argocd_app_reconcile Duração da reconciliação das aplicações Mapa de calor para detectar controller sobrecarregado

Além das métricas, o Argo CD Notifications envia o evento a Slack, e-mail ou webhook no momento em que a saúde muda ou a sincronização falha.

Argo CD, Flux e pipeline push: como se comparam

Argo CD e Flux são projetos graduados da CNCF que seguem o mesmo modelo pull. A escolha costuma depender do que a equipe valoriza: uma plataforma integrada com interface web (Argo CD) ou um conjunto modular de controllers guiado por linha de comando (Flux), como resume a matéria do The New Stack.

[embedded content: The New Stack, jun/2025 · Octopus Deploy (State of GitOps) e pesquisa da CNCF]

O desnível aparece nas duas pesquisas, mas o valor exato depende de quem foi perguntado e de como a pergunta foi feita.

Aspecto Argo CD Flux Pipeline push (CI)
Modelo de entrega Pull, por um controlador no cluster Pull, por controllers no cluster Push, o CI aplica no cluster
Interface web Embutida Sem UI embutida Depende do CI
Arquitetura Plataforma integrada; instância central ou uma por cluster Conjunto de controllers independentes Job efêmero a cada pipeline
Multi-cluster Clusters registrados e ApplicationSet Repositório organizado e um Flux em cada cluster Credencial de cada cluster guardada no CI
Segredos Via ferramentas externas Suporte nativo a SOPS Segredos do próprio CI
Detecção de drift Contínua Contínua Só no próximo deploy

Um pipeline push costuma bastar para projetos pequenos, com um ou dois ambientes. O GitOps começa a compensar quando surgem vários clusters, vários times e a necessidade de auditoria e de detectar drift.

Exemplo prático: do zero à primeira aplicação

O roteiro abaixo leva cerca de dez minutos em um cluster de testes (kind, minikube ou um cluster gerenciado).

1. Instalar o Argo CD

kubectl create namespace argocd
kubectl apply -n argocd \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Enter fullscreen mode Exit fullscreen mode

Em produção, prefira o chart Helm oficial (argo/argo-cd) com os valores versionados no Git, e fixe a versão em vez de usar stable.

2. Acessar a interface e a CLI

# senha inicial do usuário admin
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d

# encaminhar a porta do servidor
kubectl port-forward svc/argocd-server -n argocd 8080:443

# login pela CLI
argocd login localhost:8080 --username admin --insecure
Enter fullscreen mode Exit fullscreen mode

3. Organizar o repositório

Uma estrutura simples e muito usada separa a base dos ambientes com Kustomize:

loja-gitops/
├── apps/
│   └── api/
│       ├── base/
│       │   ├── deployment.yaml
│       │   ├── service.yaml
│       │   └── kustomization.yaml
│       └── overlays/
│           ├── homologacao/
│           │   └── kustomization.yaml
│           └── producao/
│               └── kustomization.yaml
└── argocd/
    └── applications/
        └── loja-api-producao.yaml
Enter fullscreen mode Exit fullscreen mode

4. Criar a aplicação

argocd app create loja-api \
  --repo https://github.com/minha-org/loja-gitops.git \
  --path apps/api/overlays/producao \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace loja \
  --sync-policy automated --auto-prune --self-heal
Enter fullscreen mode Exit fullscreen mode

O mesmo resultado sai de aplicar o YAML da Application mostrado antes, que é a forma recomendada porque fica versionada.

5. Ver a reconciliação funcionando

  1. Altere replicas no deployment.yaml, faça commit e push. Em poucos minutos (ou na hora, se houver webhook), a aplicação passa a OutOfSync e logo volta a Synced.
  2. Rode kubectl scale deployment api -n loja --replicas=1 na mão. Com selfHeal ativo, o Argo CD desfaz a mudança e volta ao valor do Git.
  3. Apague o service.yaml do repositório. Com prune ativo, o Service é removido do cluster.
  4. Use argocd app history loja-api e argocd app rollback loja-api <id> para voltar a uma revisão anterior. Em modo automático, o rollback pela CLI exige desativar a sincronização automática antes; o caminho mais limpo é um git revert.

Boas práticas e armadilhas comuns

A maior parte dos problemas com Argo CD vem de decisões de organização, não da ferramenta em si.

O que fazer

  • Separe o repositório de código do repositório de configuração. Um commit de código não deve disparar uma mudança de manifesto sem passar por um passo explícito (por exemplo, o CI atualiza a tag da imagem no repositório GitOps por pull request).
  • Use o padrão app of apps ou ApplicationSet para que a própria lista de aplicações esteja no Git, e não cadastrada à mão.
  • Uma pasta por ambiente, com Kustomize overlays ou arquivos de valores do Helm, em vez de branches por ambiente. Branches divergem e a promoção vira merge doloroso.
  • Fixe versões: tags de imagem imutáveis (nunca latest), versões de chart e targetRevision por tag ou SHA em produção.
  • Automatize com cuidado: automated em homologação quase sempre vale a pena; em produção, muitos times preferem sincronização automática com prune e selfHeal, mas com janelas de sincronização (sync windows) e revisão obrigatória de pull request.
  • Ative notificações (Argo CD Notifications) para Slack, e-mail ou webhook nos eventos de falha de sincronização e degradação de saúde.

Armadilhas

Armadilha O que acontece Como evitar
HPA e replicas fixo no Git O Argo CD e o autoscaler brigam pelo número de réplicas Remover replicas do manifesto ou usar ignoreDifferences
Campos gerados por controladores Aplicação fica OutOfSync para sempre por causa de campos que o cluster preenche ignoreDifferences ou RespectIgnoreDifferences=true
CRDs grandes Falha de apply por limite da anotação last-applied ServerSideApply=true
Segredos em texto no Git Vazamento de credenciais Sealed Secrets, External Secrets ou SOPS
Um único repositório gigante Renderização lenta e cache do repo server sempre invalidado Dividir por domínio e usar anotação manifest-generate-paths
prune sem entender o escopo Recursos apagados por engano Testar primeiro com argocd app sync --dry-run e usar Prune=false em recursos críticos

Conclusão e próximos passos

O Argo CD é um laço de controle: ele lê o estado desejado no Git, observa o estado real no cluster e fecha a diferença, com visibilidade, política e auditoria em volta disso. O ganho prático vem de três hábitos: tudo no Git, nada aplicado à mão e sincronização automática onde o risco permite.

Para colocar em prática:

  • Suba o Argo CD em um cluster de testes e siga o exemplo prático deste artigo.
  • Crie um AppProject por time antes de liberar acesso, e configure SSO e RBAC no primeiro dia.
  • Decida como os segredos serão tratados (Sealed Secrets, External Secrets ou SOPS) antes de migrar a primeira aplicação real.
  • Use ApplicationSet para que a lista de aplicações também seja versionada.
  • Ative métricas e notificações, e só depois habilite selfHeal e prune em produção.

Top comments (0)