Files
workshop/aula-04/README.md
ArgoCD Setup 1b520c7be7 fix(aula-04): corrigir porta do teste de stress para 3000
URL default estava sem porta, causando conexão na porta 80 ao invés da 3000.
2026-01-23 08:31:53 -03:00

214 lines
5.6 KiB
Markdown

# Aula 04 - NGINX Ingress com Keep Request (Lua)
Zero-downtime absoluto usando Lua para segurar requisições enquanto pods reiniciam.
## O Problema
Mesmo com 5 réplicas e readiness probe (aula-03), existe uma janela de tempo onde:
```
Tempo 0.0s: Pod1 trava, readinessProbe ainda não detectou
Tempo 0.5s: Request chega, NGINX roteia para Pod1 → 502 Bad Gateway
Tempo 1.0s: readinessProbe falha, Pod1 removido do Service
```
**Resultado:** Usuário vê erro 502 durante ~1 segundo.
## A Solução: Keep Request
```
Tempo 0.0s: Pod1 trava
Tempo 0.5s: Request chega → NGINX tenta Pod1 → erro 502
Lua intercepta o 502
Loop: tenta conectar no backend a cada 1s
Tempo 2.0s: Pod1 reinicia, responde OK
Lua faz redirect interno → usuário recebe resposta
```
**Resultado:** Usuário espera 1.5s mas recebe resposta válida (não erro).
## Arquitetura
```
Cliente
┌────────────────┐
│ NGINX Ingress │
│ + Lua │
└───────┬────────┘
┌─────────┼─────────┐
│ 502/503/504? │
│ │ │
│ ┌────▼────┐ │
│ │ Lua │ │
│ │ Loop │◄───┼── Aguarda até 99s
│ └────┬────┘ │
│ │ │
└─────────┼─────────┘
┌───────────────┐
│ Service │
│ node-bugado │
└───────┬───────┘
┌───────────┼───────────┐
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│ Pod 1 │ │ Pod 2 │ │ Pod 3 │
└───────┘ └───────┘ └───────┘
```
## Como Funciona o Lua
```lua
-- 1. Intercepta erros 502, 503, 504
error_page 502 503 504 = @wait_for_backend;
-- 2. Location interno que aguarda
location @wait_for_backend {
content_by_lua_block {
local max_wait = 99 -- segundos máximos de espera
while (ngx.now() - start) < max_wait do
-- Tenta conexão TCP com o backend
local ok = sock:connect(backend_host, backend_port)
if ok then
-- Backend disponível! Redirect interno
return ngx.exec(ngx.var.request_uri)
end
-- Aguarda 1 segundo e tenta novamente
ngx.sleep(1)
end
-- Timeout: retorna 503 após 99s
ngx.exit(503)
}
}
```
## Instalação
```bash
cd aula-04
# Instalar NGINX Ingress com suporte a Lua
./setup.sh
# Aplicar recursos
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress-nginx.yaml
```
## Pré-requisitos
O NGINX Ingress Controller precisa de suporte a Lua (snippets habilitados):
```yaml
# No Helm values do ingress-nginx
controller:
config:
allow-snippet-annotations: "true"
extraArgs:
enable-ssl-passthrough: "true"
```
## Teste de Stress
```bash
# Terminal 1: Monitorar pods
kubectl get pods -w
# Terminal 2: Teste de stress
./teste-stress.sh
# Ou manualmente:
for i in {1..100}; do
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:3000/
sleep 0.1
done
```
### Resultado Esperado
```
# Sem Keep Request (aula-03):
200 200 200 502 502 200 200 200 502 200
^^^ ^^^ erros visíveis
# Com Keep Request (aula-04):
200 200 200 200 200 200 200 200 200 200
^^^ request demorou 2s mas retornou 200
```
## Configuração
| Parâmetro | Valor | Descrição |
|-----------|-------|-----------|
| `max_wait` | 99s | Tempo máximo de espera |
| `interval` | 1s | Intervalo entre tentativas |
| `proxy-connect-timeout` | 2s | Timeout de conexão (falha rápido) |
| `proxy-read-timeout` | 3s | Timeout de leitura |
## Logs do NGINX
```bash
# Ver logs do Lua
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -f | grep KeepRequest
# Exemplo de output:
[KeepRequest] Aguardando backend por ate 99s...
[KeepRequest] Backend indisponivel: connection refused
[KeepRequest] Backend indisponivel: connection refused
[KeepRequest] Backend ready apos 2s
```
## Trade-offs
| Aspecto | Sem Keep Request | Com Keep Request |
|---------|------------------|------------------|
| Latência normal | ~10ms | ~10ms |
| Latência durante restart | Erro 502 | +1-5s espera |
| Experiência usuário | Vê erro | Espera mais, sem erro |
| Recursos NGINX | Baixo | Conexões mantidas |
| Complexidade | Simples | Lua/snippets |
## Quando Usar
**Use Keep Request quando:**
- Zero tolerância a erros visíveis
- Operações críticas (pagamentos, submissões)
- SLA exige 99.99% de disponibilidade
**Evite quando:**
- Aplicações real-time (latência crítica)
- Alto volume de requests (conexões acumulam)
- Backend demora muito para reiniciar (>30s)
## Cleanup
```bash
./cleanup.sh
```
## Lições
1. **Probes não são instantâneos**: Há sempre uma janela de falha
2. **Lua no NGINX**: Poderoso para lógica customizada
3. **Trade-off latência vs erro**: Usuário prefere esperar a ver erro
4. **Defense in depth**: Múltiplas camadas de resiliência
## Próxima Aula
**Aula 05**: KEDA + Victoria Metrics para auto-scaling baseado em métricas customizadas.