GitOps com ArgoCD ou Flux: declarando o estado desejado

1. Introdução ao GitOps no ecossistema Kubernetes

1.1. O que é GitOps: princípios fundamentais

GitOps é um padrão operacional para Kubernetes que coloca o repositório Git como a única fonte da verdade para infraestrutura e aplicações. Seus três pilares são:

  • Declaratividade: todo o estado do cluster é descrito em arquivos YAML ou JSON no Git
  • Imutabilidade: alterações nunca são feitas diretamente no cluster; apenas via pull requests no repositório
  • Pull-based: um agente dentro do cluster puxa as alterações do Git, em vez de um CI/CD externo fazer push

1.2. Benefícios para pipelines DevOps

  • Auditoria completa: cada alteração fica registrada no histórico do Git com autor, timestamp e mensagem
  • Rastreabilidade: é possível saber exatamente o que mudou entre duas versões usando git diff
  • Rollback simplificado: basta reverter um commit ou apontar para um commit anterior

1.3. Comparação com abordagens tradicionais

Abordagem Mecanismo Risco de drift
Push-based (CI/CD clássico) Pipeline externo aplica kubectl apply Alto (alterações manuais não são detectadas)
Pull-based (GitOps) Agente no cluster observa o Git Baixo (reconciliação contínua)

2. Arquitetura e componentes do GitOps com Kubernetes

2.1. Repositório Git como fonte única da verdade

O repositório deve conter:

.
├── apps/
│   ├── frontend/
│   │   ├── deployment.yaml
│   │   └── service.yaml
│   └── backend/
│       ├── deployment.yaml
│       └── configmap.yaml
├── infrastructure/
│   ├── ingress-nginx/
│   └── cert-manager/
└── clusters/
    ├── dev/
    └── prod/

2.2. Agentes GitOps: ArgoCD vs Flux

ArgoCD é mais opinativo e focado em interface web rica, com sincronização automática e rollback visual. Flux é mais modular, integrado nativamente com o ecossistema CNCF e usa o toolkit GitOps do Kubernetes.

2.3. Sincronização pull-based vs push-based

No modelo pull-based, o agente (ArgoCD ou Flux) consulta periodicamente o Git e aplica as diferenças. No push-based, um pipeline externo envia as alterações. O modelo pull-based é mais seguro porque não requer credenciais de cluster expostas.

3. ArgoCD: implantação e configuração prática

3.1. Instalação do ArgoCD no cluster

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

Para expor a interface web:

kubectl port-forward svc/argocd-server -n argocd 8080:443

3.2. Criação de uma Application declarativa

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: guestbook
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

3.3. Recursos avançados: sync waves e hooks

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  annotations:
    argocd.argoproj.io/sync-options: Prune=false
    argocd.argoproj.io/hook: PreSync
spec:
  source:
    path: manifests/
    repoURL: https://github.com/meuapp.git
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

4. Flux: implantação e configuração prática

4.1. Instalação do Flux CLI e bootstrap do cluster

curl -s https://fluxcd.io/install.sh | sudo bash
flux bootstrap github \
  --owner=meuusuario \
  --repository=meu-repo-gitops \
  --branch=main \
  --path=./clusters/prod \
  --personal

4.2. Estrutura de diretórios com Kustomize e HelmRelease

clusters/
├── prod/
│   ├── flux-system/
│   │   └── gotk-components.yaml
│   └── apps/
│       ├── podinfo/
│       │   ├── kustomization.yaml
│       │   └── release.yaml
│       └── nginx/
│           └── helmrelease.yaml

Exemplo de helmrelease.yaml:

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: nginx
  namespace: flux-system
spec:
  interval: 5m
  chart:
    spec:
      chart: nginx
      sourceRef:
        kind: HelmRepository
        name: bitnami
        namespace: flux-system
      interval: 1m
  values:
    replicaCount: 3

4.3. Mecanismos de reconciliação e alertas

apiVersion: notification.toolkit.fluxcd.io/v1beta2
kind: Alert
metadata:
  name: slack-alert
  namespace: flux-system
spec:
  providerRef:
    name: slack
  eventSeverity: info
  eventSources:
    - kind: Kustomization
      name: '*'
    - kind: HelmRelease
      name: '*'

5. Estratégias de gerenciamento de estado e secrets

5.1. Tratamento de secrets

Sealed Secrets:

kubeseal --format yaml < secret.yaml > sealed-secret.yaml

External Secrets Operator:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-creds
spec:
  secretStoreRef:
    name: aws-secret-store
    kind: SecretStore
  target:
    name: database-creds
  data:
    - secretKey: password
      remoteRef:
        key: /prod/database/password

5.2. Gerenciamento de múltiplos ambientes

Estratégia de diretórios:

clusters/
├── dev/
│   └── apps/
└── prod/
    └── apps/

Ou estratégia de branches: main para prod, dev para desenvolvimento.

5.3. Estratégias de rollback e drift detection

  • Rollback via Git: git revert HEAD + push
  • Drift detection: ArgoCD e Flux detectam automaticamente alterações manuais e as corrigem (auto-healing)

6. Integração com Service Mesh e Network Policies

6.1. Declarando Service Mesh via GitOps

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: myapp-vs
spec:
  hosts:
  - myapp.example.com
  http:
  - route:
    - destination:
        host: myapp
        port:
          number: 80

6.2. Aplicando Network Policies

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - port: 8080

6.3. Pipeline GitOps com ArgoCD + Istio

  1. Desenvolvedor faz PR no repositório Git
  2. CI valida os manifests (lint, teste)
  3. Merge na branch main
  4. ArgoCD detecta mudança e sincroniza
  5. Istio atualiza VirtualService e DestinationRule automaticamente

7. Boas práticas, monitoramento e troubleshooting

7.1. Estrutura de repositório recomendada

App-of-apps pattern (ArgoCD):

├── apps/
│   ├── app1.yaml
│   └── app2.yaml
└── root.yaml  # Application que gerencia outras Applications

Multi-tenancy (Flux):

clusters/
├── team-a/
└── team-b/

7.2. Monitoramento da sincronização

Métricas importantes no Prometheus:

argocd_app_info{sync_status="Synced"}
flux_kustomization_condition{type="Ready"}

Dashboards no Grafana: use os dashboards oficiais do ArgoCD e Flux.

7.3. Troubleshooting comum

  • Conflitos de sync: verifique se há alterações manuais no cluster
  • Permissões: certifique-se de que o service account do agente tem permissões adequadas
  • Conectividade Git: configure proxies ou webhooks para reduzir latência

8. Conclusão e próximos passos

8.1. Resumo das diferenças entre ArgoCD e Flux

Característica ArgoCD Flux
Interface web Rica, nativa CLI + extensões
Complexidade Média Baixa
Integração com Helm Nativa Via HelmRelease
Suporte a Kustomize Sim Sim
Multi-cluster Sim (via cluster secrets) Sim (via Kustomization)

Quando escolher ArgoCD: times que preferem interface visual e recursos avançados de sincronização.

Quando escolher Flux: times que buscam simplicidade e integração nativa com o ecossistema Kubernetes.

8.2. Integração com Kubernetes Operators

GitOps funciona perfeitamente com operators como cert-manager, prometheus-operator e strimzi. Basta declarar os Custom Resources no repositório Git.

8.3. Referências e recursos para aprofundamento