Files
workshop/aula-05/README.md
ArgoCD Setup d3656fdce9 docs(aula-05): atualizar README com nova lógica de scaling
- Documentar trigger único (unavailable) em vez de restarts
- Explicar fórmula intuitiva: 5 + (unavailable * 2)
- Adicionar seção sobre scrape interval de 5s
- Documentar fluxo de detecção (~6-7s)
- Explicar por que não usar restarts (CrashLoopBackOff)
- Atualizar lições e trade-offs
2026-01-23 11:15:20 -03:00

284 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Aula 05 - KEDA + Victoria Metrics (Auto-scaling por Métricas)
Auto-scaling inteligente baseado em métricas customizadas usando KEDA e Victoria Metrics.
## O Problema
HPA padrão do Kubernetes escala apenas por CPU/memória:
```yaml
# HPA tradicional - limitado
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 70
```
**Limitações:**
- App pode estar "saudável" em CPU mas travada
- Não detecta pods indisponíveis
- Reação lenta (~15-30s)
## A Solução: KEDA
KEDA (Kubernetes Event-driven Autoscaling) permite escalar baseado em **qualquer métrica**:
```
Victoria Metrics ──► KEDA ──► HPA ──► Deployment
│ │
│ └─ Consulta métricas a cada 1s
└─ Coleta métricas do cluster a cada 5s (kube-state-metrics)
```
## Arquitetura
```
┌─────────────────────────────────────────────────────────────┐
│ Victoria Metrics │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ kube_deployment_status_replicas_unavailable = 3 │ │
│ │ Scrape interval: 5s (detecção rápida) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Query PromQL a cada 1s
┌─────────────────────────────────────────────────────────────┐
│ KEDA │
│ ┌────────────────────────────────────────────────────────┐│
│ │ Query: 5 + (unavailable * 2) ││
│ │ ││
│ │ 0 unavailable → 5 réplicas (mínimo) ││
│ │ 3 unavailable → 11 réplicas (5 + 6) ││
│ │ 5 unavailable → 15 réplicas (5 + 10) ││
│ └────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
Cria/Atualiza
┌─────────────────────────────────────────────────────────────┐
│ HPA │
│ minReplicas: 5 ──────► maxReplicas: 30 │
└─────────────────────────────────────────────────────────────┘
Escala
┌─────────────────────────────────────────────────────────────┐
│ Deployment │
│ [Pod1] [Pod2] [Pod3] [Pod4] [Pod5] ... [Pod30] │
└─────────────────────────────────────────────────────────────┘
```
## Instalação
```bash
cd aula-05
# Instala Victoria Metrics, KEDA e NGINX Ingress
./setup.sh
```
O setup.sh instala:
1. **Victoria Metrics** - Coleta e armazena métricas
2. **kube-state-metrics** - Expõe métricas do Kubernetes (scrape 5s)
3. **KEDA** - Event-driven autoscaler
4. **NGINX Ingress** - Load balancer
## Trigger: Pods Indisponíveis (Instantâneo)
```yaml
- type: prometheus
metricType: AverageValue
metadata:
serverAddress: http://vmsingle-vm-victoria-metrics-k8s-stack.monitoring:8428
# Query que calcula réplicas desejadas diretamente
query: |
5 + (kube_deployment_status_replicas_unavailable{
deployment="node-bugado",
namespace="default"
} * 2)
threshold: '1'
```
### Como funciona a fórmula
| Pods Unavailable | Query Retorna | Réplicas Desejadas |
|------------------|---------------|-------------------|
| 0 | 5 + (0 × 2) = 5 | 5 (mínimo) |
| 1 | 5 + (1 × 2) = 7 | 7 |
| 3 | 5 + (3 × 2) = 11 | 11 |
| 5 | 5 + (5 × 2) = 15 | 15 |
**Vantagem**: Detecção **instantânea** - não precisa de janela de tempo como métricas de restarts.
## Configuração de Velocidade
### Scrape Rápido (5s)
```yaml
# vmservicescrape-kube-state-metrics.yaml
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMServiceScrape
spec:
endpoints:
- port: http
interval: 5s # Default é 30s - muito lento para workshop!
```
### Scale UP - Agressivo
```yaml
scaleUp:
stabilizationWindowSeconds: 0 # Sem espera
policies:
- type: Pods
value: 5 # +5 pods por vez
periodSeconds: 1 # A cada 1s
```
### Scale DOWN - Agressivo
```yaml
scaleDown:
stabilizationWindowSeconds: 0 # Sem espera
policies:
- type: Pods
value: 10 # -10 pods por vez
periodSeconds: 1 # A cada 1s
```
## Fluxo de Detecção
```
Tempo 0.0s: Pod crasha
Tempo 0.0s: kube-state-metrics atualiza (imediato)
Tempo 5.0s: Victoria Metrics coleta (scrape interval)
Tempo 6.0s: KEDA consulta (polling interval)
Tempo 6.0s: HPA escala (imediato)
─────────────────────────────────────────────────
Total: ~6-7 segundos de reação
```
## Exemplo de Scaling
```
Tempo 0s: 5 pods, 0 unavailable
Tempo 6s: Pod1 trava → detectado → escala para 7 pods
Tempo 7s: Pod2 trava → detectado → escala para 9 pods
Tempo 8s: Pod3 trava → detectado → escala para 11 pods
...
Tempo 15s: Pods reiniciaram, 0 unavailable
Tempo 16s: Scale down: 15 → 5 (instantâneo)
```
## Teste de Stress
```bash
# Terminal 1: Monitorar pods
watch kubectl get pods -l app=node-bugado
# Terminal 2: Monitorar HPA
watch kubectl get hpa
# Terminal 3: Teste de stress
./teste-stress.sh
```
## Comandos Úteis
```bash
# Ver ScaledObject
kubectl get scaledobject
kubectl describe scaledobject node-bugado-scaledobject
# Ver HPA criado pelo KEDA
kubectl get hpa
kubectl describe hpa keda-hpa-node-bugado-scaledobject
# Testar query no Victoria Metrics
kubectl run curl --rm -it --restart=Never --image=curlimages/curl -- \
-s 'http://vmsingle-vm-victoria-metrics-k8s-stack.monitoring:8428/api/v1/query' \
--data-urlencode 'query=5 + (kube_deployment_status_replicas_unavailable{deployment="node-bugado"} * 2)'
# Logs do KEDA
kubectl logs -n keda -l app=keda-operator -f
```
## Queries PromQL Úteis
```promql
# Pods indisponíveis (usado pelo KEDA)
kube_deployment_status_replicas_unavailable{deployment="node-bugado"}
# Query completa do KEDA
5 + (kube_deployment_status_replicas_unavailable{deployment="node-bugado"} * 2)
# Pods prontos
kube_deployment_status_replicas_ready{deployment="node-bugado"}
# Total de restarts (para debug)
sum(kube_pod_container_status_restarts_total{pod=~"node-bugado.*"})
```
## Por que não usar Restarts como trigger?
O trigger de restarts usa `increase([window])` que requer uma janela de tempo:
```yaml
# ❌ Problema: CrashLoopBackOff usa backoff exponencial
# Restart 1: imediato
# Restart 2: espera 10s
# Restart 3: espera 20s
# Restart 4: espera 40s
#
# Com janela de 15s, após restart 3+, o backoff > janela
# → increase([15s]) = 0 → KEDA não detecta!
```
**Solução**: Usar `kube_deployment_status_replicas_unavailable` que é **instantâneo**.
## Victoria Metrics vs Prometheus
| Aspecto | Prometheus | Victoria Metrics |
|---------|------------|------------------|
| Recursos | Alto consumo | Baixo consumo |
| Armazenamento | Local apenas | Distribuído opcional |
| API | Nativa | Compatível 100% |
| Performance | Boa | Excelente |
| Para este workshop | Funciona | Recomendado |
## Cleanup
```bash
./cleanup.sh
```
## Lições
1. **Métrica instantânea**: Use `unavailable` em vez de `restarts` para detecção imediata
2. **Scrape rápido**: Configure 5s em vez do default 30s
3. **Query intuitiva**: `5 + (unavailable * 2)` calcula réplicas diretamente
4. **Scale agressivo**: `stabilizationWindow: 0` para reação imediata
5. **metricType correto**: `AverageValue` para cálculo proporcional
## Trade-offs
| Aspecto | HPA Padrão | KEDA (esta aula) |
|---------|------------|------------------|
| Configuração | Simples | Mais complexa |
| Métricas | CPU/Mem | Qualquer |
| Latência | ~15-30s | ~6-7s |
| Dependências | Nenhuma | Victoria Metrics |
| Flexibilidade | Baixa | Alta |
## Próxima Aula
**Aula 06**: Deploy do n8n via Helm em ambiente local.