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
This commit is contained in:
122
aula-01/README.md
Normal file
122
aula-01/README.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# 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**.
|
||||
Reference in New Issue
Block a user