Aula 08 - Cluster Kubernetes HA: - Setup interativo com OpenTofu para Talos na Hetzner - CCM, CSI Driver, Cluster Autoscaler, Metrics Server - NGINX Ingress com LoadBalancer (HTTP/HTTPS/SSH) Aula 09 - n8n na Hetzner: - Deploy via Helm com PostgreSQL e Redis - Suporte multi-tenant com add-client.sh - Integração com Hetzner CSI para volumes persistentes Aula 10 - GitLab na Hetzner: - Setup agnóstico: CloudFlare (trusted proxies) ou Let's Encrypt - Anti-affinity para distribuir webservice/sidekiq em nós diferentes - Container Registry e SSH via TCP passthrough - Documentação do erro 422 e solução com trustedCIDRsForXForwardedFor Melhorias gerais: - READMEs atualizados com arquitetura e troubleshooting - Scripts cleanup.sh para todas as aulas - CLAUDE.md atualizado com contexto do projeto
3.1 KiB
Aula 02 - Do Docker Compose ao Kubernetes
Objetivo
Migrar a aplicação da Aula 01 para Kubernetes, entendendo como os conceitos se traduzem entre as duas tecnologias.
Comparação: Docker Compose vs Kubernetes
| Docker Compose | Kubernetes | Descrição |
|---|---|---|
docker-compose.yml |
deployment.yaml |
Define como rodar o container |
restart: always |
livenessProbe |
Recuperação de falhas |
volumes: (bind mount) |
ConfigMap + volumeMounts |
Injetar arquivos no container |
environment: |
env: + configMapKeyRef |
Variáveis de ambiente |
ports: |
Service |
Expor a aplicação |
Mapeamento de Arquivos
aula-01/ aula-02/
├── docker-compose.yml → ├── deployment.yaml
├── app.js → ├── configmap.yaml (contém o app.js)
└── service.yaml
Na Aula 01, tínhamos 1 arquivo YAML. No Kubernetes, separamos em 3 arquivos com responsabilidades distintas:
- configmap.yaml: Configurações e código da aplicação
- deployment.yaml: Como rodar e monitorar o container
- service.yaml: Como expor a aplicação na rede
Comandos
# Criar todos os recursos
kubectl apply -f .
# Remover todos os recursos
kubectl delete -f .
O Problema do restart: always
Na Aula 01, usamos restart: always no Docker Compose:
services:
node-app:
restart: always # Reinicia quando o processo morre
Problema: Se a aplicação travar mas o processo continuar rodando, o Docker não reinicia o container. É exatamente o que acontece com nossa app "bugada" - ela para de responder mas o processo Node.js continua vivo.
A Solução: Liveness Probe
O Kubernetes resolve isso com Liveness Probes - verificações periódicas de saúde:
livenessProbe:
httpGet:
path: /health # Endpoint a ser testado
port: 3000
initialDelaySeconds: 5 # Espera inicial antes de testar
periodSeconds: 2 # Intervalo entre testes
failureThreshold: 2 # Falhas consecutivas para reiniciar
Como funciona:
- Kubernetes faz GET em
/healtha cada 2 segundos - Se falhar 2 vezes seguidas, o container é reiniciado
- Diferente do
restart: always, detecta processos "vivos mas travados"
Teste Prático
-
Aplique os recursos:
kubectl apply -f . -
Acompanhe os pods:
kubectl get pods -w -
Em outro terminal, faça requests até travar:
curl localhost:3000 curl localhost:3000 curl localhost:3000 curl localhost:3000 # Este vai travar -
Observe o pod ser reiniciado automaticamente (RESTARTS aumenta)
-
Remova tudo:
kubectl delete -f .
Conclusão
| Abordagem | Detecta processo morto | Detecta processo travado |
|---|---|---|
restart: always |
Sim | Nao |
livenessProbe |
Sim | Sim |
O Liveness Probe é a forma do Kubernetes garantir que sua aplicação está realmente funcionando, não apenas rodando.