Files
workshop/aula-11/README.md
ArgoCD Setup 97b4b50c96 refactor: Atualizar CLAUDE.md e melhorias aula-11
- CLAUDE.md: Atualizar tabela com aulas 12 (Victoria Metrics) e 13 (Container Factory)
- aula-11: Melhorias no setup do GitLab Runner
2026-01-08 18:30:08 -03:00

12 KiB

Aula 11 - ArgoCD + GitLab Runner (GitOps)

Deploy de ArgoCD e GitLab Runner para pipeline CI/CD completo com GitOps.

Arquitetura

┌─────────────────────────────────────────────────────────────┐
│                     GitLab (aula-10)                        │
│  ┌─────────────┐    ┌──────────────┐    ┌───────────────┐  │
│  │  git push   │───►│  GitLab CI   │───►│   Registry    │  │
│  │  (código)   │    │  (Runner K8s)│    │ (imagem:tag)  │  │
│  └─────────────┘    └──────┬───────┘    └───────────────┘  │
└────────────────────────────┼────────────────────────────────┘
                             │ atualiza manifests
                             ▼
┌─────────────────────────────────────────────────────────────┐
│                  Repositório GitOps                         │
│  apps/node-bugado/                                          │
│  ├── deployment.yaml  (image: registry.../node-bugado:sha) │
│  ├── service.yaml                                           │
│  └── configmap.yaml                                         │
└─────────────────────────────────────────────────────────────┘
                             │
                             │ sync automático
                             ▼
┌─────────────────────────────────────────────────────────────┐
│                     ArgoCD                                  │
│  ┌─────────────┐    ┌──────────────┐    ┌───────────────┐  │
│  │ Application │───►│    Sync      │───►│  Kubernetes   │  │
│  │  CRD        │    │  Controller  │    │  (deploy)     │  │
│  └─────────────┘    └──────────────┘    └───────────────┘  │
└─────────────────────────────────────────────────────────────┘

Pré-requisitos

  1. Cluster Talos na Hetzner (aula-08) com:
    • NGINX Ingress Controller com LoadBalancer
    • Hetzner CSI Driver
  2. GitLab instalado (aula-10)
  3. kubectl e helm instalados

Contexto do Cluster

# Usar kubeconfig da aula-08
export KUBECONFIG=$(pwd)/../aula-08/kubeconfig
kubectl cluster-info

Instalação

cd aula-11

# Executar setup interativo
chmod +x setup.sh
./setup.sh

O script instala:

  1. GitLab Runner - Executor Kubernetes para pipelines CI
  2. ArgoCD - GitOps CD para Kubernetes
  3. Configura integração SSH com GitLab

Componentes Instalados

Componente Namespace Recursos Função
ArgoCD Server argocd 256Mi/512Mi UI + API
ArgoCD Repo Server argocd 256Mi/512Mi Git clone/sync
ArgoCD Controller argocd 256Mi/512Mi Reconciliation
ArgoCD Redis argocd 64Mi/128Mi Cache
GitLab Runner gitlab 128Mi/256Mi CI jobs como pods
Total ~1.2Gi

Acesso

ArgoCD

URL: https://argocd.{domain}
Username: admin
Senha: kubectl get secret argocd-initial-admin-secret -n argocd \
         -o jsonpath='{.data.password}' | base64 -d

GitLab Runner

Verificar status em: https://{gitlab-host}/admin/runners

# Ver pods do runner
kubectl get pods -n gitlab -l app=gitlab-runner

# Ver logs
kubectl logs -n gitlab -l app=gitlab-runner -f

Configurar Pipeline GitOps

1. Criar Repositório GitOps no GitLab

Crie um repositório gitops-demo com a estrutura:

gitops-demo/
└── apps/
    └── node-bugado/
        ├── configmap.yaml
        ├── deployment.yaml
        ├── service.yaml
        └── ingress.yaml

Use os arquivos de exemplo em node-bugado/k8s/.

2. Configurar Deploy Key

# Gerar par de chaves
ssh-keygen -t ed25519 -f argocd-deploy-key -N ''

# Adicionar chave pública no GitLab:
# Settings → Repository → Deploy Keys
# Marcar "Grant write permissions"

3. Conectar Repositório no ArgoCD

Via UI:

  1. Acesse https://argocd.{domain}
  2. Settings → Repositories → Connect Repo
  3. Method: SSH
  4. URL: git@git.{domain}:{usuario}/gitops-demo.git
  5. SSH private key: (conteúdo de argocd-deploy-key)

Ou via CLI:

argocd repo add git@git.kube.quest:usuario/gitops-demo.git \
  --ssh-private-key-path argocd-deploy-key

4. Criar ArgoCD Application

kubectl apply -f - << 'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: node-bugado
  namespace: argocd
spec:
  project: default
  source:
    repoURL: git@git.kube.quest:usuario/gitops-demo.git
    targetRevision: HEAD
    path: apps/node-bugado
  destination:
    server: https://kubernetes.default.svc
    namespace: demo
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
EOF

5. Configurar Pipeline no Repositório da App

No repositório node-bugado:

  1. Copie .gitlab-ci.yml de node-bugado/.gitlab-ci.yml
  2. Configure variáveis em Settings → CI/CD → Variables:
    • GITOPS_REPO: git@git.kube.quest:usuario/gitops-demo.git
    • DEPLOY_KEY: Chave SSH privada (com write access ao repo gitops)

Fluxo de Deploy

  1. Desenvolvedor faz push no repositório node-bugado
  2. GitLab CI dispara pipeline:
    • Build: Constrói imagem Docker
    • Push: Envia para GitLab Registry
    • Deploy: Atualiza deployment.yaml no repo GitOps
  3. ArgoCD detecta mudança no repo GitOps
  4. ArgoCD sincroniza com cluster Kubernetes
  5. Kubernetes faz rolling update dos pods

GitLab Runner - Executor Kubernetes

O runner usa executor kubernetes, onde cada job CI:

  • Roda como um pod efêmero no cluster
  • Tem acesso a Docker-in-Docker para builds
  • É automaticamente limpo após conclusão
  • Escala conforme demanda de jobs
# gitlab-runner-values.yaml
runners:
  executor: kubernetes
  privileged: true  # Necessário para Docker-in-Docker
  namespace: gitlab

Por que Docker-in-Docker?

Para construir imagens Docker dentro de um container (o job do CI), precisamos:

  1. Privileged mode: Acesso ao kernel para criar containers
  2. Docker daemon: Serviço Docker rodando no job

Alternativas (mais seguras, mas mais complexas):

  • Kaniko: Build sem Docker daemon
  • Buildah: Build rootless

Requisitos para Docker-in-Docker

1. Pod Security (Kubernetes 1.25+)

Kubernetes 1.25+ aplica Pod Security Admission por padrão. O namespace gitlab precisa permitir pods privilegiados:

kubectl label namespace gitlab \
    pod-security.kubernetes.io/enforce=privileged \
    pod-security.kubernetes.io/warn=privileged \
    --overwrite

Nota: O setup.sh já configura isso automaticamente.

2. Helper Image para ARM64

Em clusters com nodes ARM64 (como Hetzner CAX), o runner precisa usar o helper image correto. Configure em gitlab-runner-values.yaml:

# Dentro de runners.config
[[runners]]
  [runners.kubernetes]
    helper_image = "gitlab/gitlab-runner-helper:arm64-latest"

Sem isso, você verá erros como:

no match for platform in manifest: not found

Troubleshooting

ArgoCD não sincroniza

# Verificar status da Application
kubectl get applications -n argocd

# Ver detalhes
kubectl describe application node-bugado -n argocd

# Ver logs do controller
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller

Runner não aparece no GitLab

# Verificar pod do runner
kubectl get pods -n gitlab -l app=gitlab-runner

# Ver logs
kubectl logs -n gitlab -l app=gitlab-runner

# Verificar registration token
kubectl get secret gitlab-gitlab-runner-secret -n gitlab -o yaml

Jobs CI falham

# Ver pods dos jobs
kubectl get pods -n gitlab

# Ver logs de um job específico
kubectl logs -n gitlab runner-xxxxx-project-xxx-concurrent-xxx

Erro "violates PodSecurity"

violates PodSecurity "baseline:latest": privileged
(containers must not set securityContext.privileged=true)

Solução: Configure o namespace para permitir pods privilegiados:

kubectl label namespace gitlab \
    pod-security.kubernetes.io/enforce=privileged \
    --overwrite

Erro "no match for platform in manifest"

image pull failed: no match for platform in manifest: not found

Causa: O runner está tentando usar imagem x86_64 em node ARM64.

Solução: Configure o helper image ARM64 no gitlab-runner-values.yaml:

[[runners]]
  [runners.kubernetes]
    helper_image = "gitlab/gitlab-runner-helper:arm64-latest"

Depois faça upgrade do runner:

helm upgrade gitlab-runner gitlab/gitlab-runner \
  -n gitlab --reuse-values \
  -f gitlab-runner-values.yaml

Erro SSH ao conectar repositório

# Verificar known hosts
kubectl get configmap argocd-ssh-known-hosts-cm -n argocd -o yaml

# Adicionar manualmente
ssh-keyscan git.kube.quest | kubectl create configmap argocd-ssh-known-hosts-cm \
  --from-file=ssh_known_hosts=/dev/stdin -n argocd --dry-run=client -o yaml | kubectl apply -f -

Comandos Úteis

# ArgoCD
kubectl get applications -n argocd
kubectl get pods -n argocd
argocd app list
argocd app sync node-bugado

# GitLab Runner
kubectl get pods -n gitlab -l app=gitlab-runner
kubectl logs -n gitlab -l app=gitlab-runner -f

# Ver todos os recursos do demo
kubectl get all -n demo

# Forçar re-sync
argocd app sync node-bugado --force

# Ver diff antes de sync
argocd app diff node-bugado

Lições do Workshop

  1. GitOps: Git como fonte única de verdade para estado do cluster
  2. Separação CI/CD: GitLab CI = build, ArgoCD = deploy
  3. Runner Kubernetes: Jobs como pods efêmeros e escaláveis
  4. Docker-in-Docker: Build de imagens em containers privilegiados
  5. Auditoria: Histórico de deploys = histórico Git
  6. Self-Heal: ArgoCD corrige drift automaticamente
  7. Segurança: Deploy Keys com permissão mínima

Cleanup

./cleanup.sh

Remove ArgoCD e GitLab Runner. Não remove GitLab ou infraestrutura base.

Custos

Recurso Custo/mês
ArgoCD + Runner (~1.2Gi) Usa workers existentes
Total Adicional ~$0

Próximos Passos

  • Aula 12: eStargz + Lazy Pulling
    • Converter imagens para formato eStargz
    • Demonstrar startup mais rápido com lazy pulling
    • Medir diferença de performance

Referências