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:
- Declarativo: o sistema inteiro é descrito em manifestos (YAML, Helm, Kustomize), não em scripts de passo a passo.
- Versionado e imutável: cada mudança é um commit, com autor, revisão por pull request e histórico para auditoria.
- Aplicado automaticamente: um agente puxa o estado aprovado, sem que alguém precise rodar comandos contra o cluster.
- 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
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
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}}"
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, umkubectl editem 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
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
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
AppProjectpara restringir repositórios, destinos e tipos de recurso por time. - Desative o usuário
adminlocal 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-servere 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
replicasno StatefulSet e repita o número na variávelARGOCD_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-pathsajuda 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
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
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
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
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
- Altere
replicasnodeployment.yaml, faça commit e push. Em poucos minutos (ou na hora, se houver webhook), a aplicação passa aOutOfSynce logo volta aSynced. - Rode
kubectl scale deployment api -n loja --replicas=1na mão. ComselfHealativo, o Argo CD desfaz a mudança e volta ao valor do Git. - Apague o
service.yamldo repositório. Compruneativo, o Service é removido do cluster. - Use
argocd app history loja-apieargocd 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 é umgit 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
ApplicationSetpara 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 etargetRevisionpor tag ou SHA em produção. -
Automatize com cuidado:
automatedem homologação quase sempre vale a pena; em produção, muitos times preferem sincronização automática compruneeselfHeal, 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
AppProjectpor 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
ApplicationSetpara que a lista de aplicações também seja versionada. - Ative métricas e notificações, e só depois habilite
selfHealepruneem produção.
Top comments (0)