Files
workshop/aula-02
Allyson de Paula 07b7ee62d3 Workshop completo: aulas 08-10 com Talos, n8n e GitLab na Hetzner
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
2025-12-31 17:57:02 -03:00
..

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:

  1. Kubernetes faz GET em /health a cada 2 segundos
  2. Se falhar 2 vezes seguidas, o container é reiniciado
  3. Diferente do restart: always, detecta processos "vivos mas travados"

Teste Prático

  1. Aplique os recursos:

    kubectl apply -f .
    
  2. Acompanhe os pods:

    kubectl get pods -w
    
  3. Em outro terminal, faça requests até travar:

    curl localhost:3000
    curl localhost:3000
    curl localhost:3000
    curl localhost:3000  # Este vai travar
    
  4. Observe o pod ser reiniciado automaticamente (RESTARTS aumenta)

  5. 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.