- CLAUDE.md: Atualizar tabela com aulas 12 (Victoria Metrics) e 13 (Container Factory) - aula-11: Melhorias no setup do GitLab Runner
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
- Cluster Talos na Hetzner (aula-08) com:
- NGINX Ingress Controller com LoadBalancer
- Hetzner CSI Driver
- GitLab instalado (aula-10)
- 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:
- GitLab Runner - Executor Kubernetes para pipelines CI
- ArgoCD - GitOps CD para Kubernetes
- 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:
- Acesse https://argocd.{domain}
- Settings → Repositories → Connect Repo
- Method: SSH
- URL:
git@git.{domain}:{usuario}/gitops-demo.git - 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:
- Copie
.gitlab-ci.ymldenode-bugado/.gitlab-ci.yml - Configure variáveis em Settings → CI/CD → Variables:
GITOPS_REPO:git@git.kube.quest:usuario/gitops-demo.gitDEPLOY_KEY: Chave SSH privada (com write access ao repo gitops)
Fluxo de Deploy
- Desenvolvedor faz push no repositório
node-bugado - GitLab CI dispara pipeline:
- Build: Constrói imagem Docker
- Push: Envia para GitLab Registry
- Deploy: Atualiza
deployment.yamlno repo GitOps
- ArgoCD detecta mudança no repo GitOps
- ArgoCD sincroniza com cluster Kubernetes
- 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:
- Privileged mode: Acesso ao kernel para criar containers
- 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.shjá 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
- GitOps: Git como fonte única de verdade para estado do cluster
- Separação CI/CD: GitLab CI = build, ArgoCD = deploy
- Runner Kubernetes: Jobs como pods efêmeros e escaláveis
- Docker-in-Docker: Build de imagens em containers privilegiados
- Auditoria: Histórico de deploys = histórico Git
- Self-Heal: ArgoCD corrige drift automaticamente
- 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