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
123 lines
2.9 KiB
Markdown
123 lines
2.9 KiB
Markdown
# Aula 01 - O Problema: Apps que Travam mas Nao Morrem
|
|
|
|
## Objetivo
|
|
|
|
Demonstrar uma limitacao comum em ambientes de producao: aplicacoes que param de responder mas continuam com o processo rodando. O Docker nao consegue detectar esse tipo de falha.
|
|
|
|
## O Problema
|
|
|
|
Imagine uma aplicacao que:
|
|
- Tem um memory leak que causa travamento
|
|
- Entra em deadlock
|
|
- Perde conexao com o banco e fica em loop infinito
|
|
|
|
O processo continua vivo, mas a aplicacao nao responde. O Docker ve o processo rodando e nao faz nada.
|
|
|
|
## A Aplicacao "Bugada"
|
|
|
|
Nossa app Node.js simula esse comportamento:
|
|
|
|
```javascript
|
|
// Apos MAX_REQUESTS, para de responder mas continua rodando
|
|
if (requestCount > MAX_REQUESTS) {
|
|
console.log('App travado apos 3 requests');
|
|
return; // Nao responde, mas processo vivo
|
|
}
|
|
```
|
|
|
|
## Arquivos
|
|
|
|
```
|
|
aula-01/
|
|
├── docker-compose.yml # Configuracao do container
|
|
├── app.js # Aplicacao Node.js "bugada"
|
|
└── .env # MAX_REQUESTS=3
|
|
```
|
|
|
|
## Comandos
|
|
|
|
```bash
|
|
# Iniciar a aplicacao
|
|
docker compose up
|
|
|
|
# Parar a aplicacao
|
|
docker compose down
|
|
```
|
|
|
|
## Teste Pratico
|
|
|
|
1. Inicie a aplicacao:
|
|
```bash
|
|
docker compose up
|
|
```
|
|
|
|
2. Faca 3 requests (funcionam normalmente):
|
|
```bash
|
|
curl localhost:3000 # Req -> 1/3
|
|
curl localhost:3000 # Req -> 2/3
|
|
curl localhost:3000 # Req -> 3/3
|
|
```
|
|
|
|
3. Faca mais um request (vai travar):
|
|
```bash
|
|
curl localhost:3000 # Fica esperando para sempre...
|
|
```
|
|
|
|
4. Observe os logs - a app diz que travou:
|
|
```
|
|
App travado apos 3 requests
|
|
```
|
|
|
|
5. O container continua rodando:
|
|
```bash
|
|
docker ps # Container esta "Up", mas nao responde
|
|
```
|
|
|
|
## A Limitacao do `restart: always`
|
|
|
|
No `docker-compose.yml` temos:
|
|
|
|
```yaml
|
|
restart: always
|
|
```
|
|
|
|
Isso reinicia o container apenas quando o **processo morre**. Como nossa app trava mas o processo Node.js continua rodando, o Docker nao faz nada.
|
|
|
|
| Situacao | Processo | Docker reinicia? |
|
|
|----------|:--------:|:----------------:|
|
|
| App crasha (exit 1) | Morto | Sim |
|
|
| App trava (nosso caso) | Vivo | Nao |
|
|
|
|
## Healthcheck do Docker: Detecta mas Nao Resolve
|
|
|
|
Adicionamos um healthcheck no `docker-compose.yml`:
|
|
|
|
```yaml
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"]
|
|
interval: 2s
|
|
timeout: 2s
|
|
retries: 2
|
|
start_period: 5s
|
|
```
|
|
|
|
Apos a app travar, veja o status mudar para `unhealthy`:
|
|
|
|
```bash
|
|
docker ps
|
|
# STATUS: Up 1 minute (unhealthy)
|
|
```
|
|
|
|
**Porem, o Docker apenas DETECTA o problema - nao reinicia o container!**
|
|
|
|
O healthcheck serve para:
|
|
- Monitoramento e alertas
|
|
- Orquestradores externos tomarem acao
|
|
- Load balancers removerem o container do pool
|
|
|
|
Mas sozinho, nao resolve o problema.
|
|
|
|
## Proximo Passo
|
|
|
|
Na **Aula 02**, vamos resolver esse problema usando Kubernetes com **Liveness Probes** - verificacoes periodicas que detectam quando a aplicacao parou de responder **E reiniciam o container automaticamente**.
|