Files
workshop/aula-05
ArgoCD Setup e15138a734 fix(aula-05): otimizar KEDA para detecção instantânea de crashes
- Simplificar ScaledObject: usar apenas trigger de pods unavailable
  (instantâneo) em vez de restarts (requeria janela de tempo)
- Adicionar VMServiceScrape com scrape interval de 5s para detecção
  rápida pelo Victoria Metrics (default era 30s)
- Acelerar scale down: stabilizationWindow=0, remove 10 pods/s
- Query intuitiva: 5 + (unavailable * 2) = réplicas desejadas
- Usar metricType AverageValue para cálculo correto de réplicas
- Limpar mensagem desnecessária do teste de stress
2026-01-23 11:07:33 -03:00
..

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:

# 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
  • Não reage a restarts frequentes

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 (kube-state-metrics)

Arquitetura

┌─────────────────────────────────────────────────────────────┐
│                    Victoria Metrics                         │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  kube_deployment_status_replicas_unavailable = 2     │  │
│  │  kube_pod_container_status_restarts_total = 5        │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                              │
                    Query PromQL a cada 1s
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                         KEDA                                │
│  ┌────────────────┐    ┌─────────────────────────────────┐ │
│  │ ScaledObject   │───►│ unavailable >= 1 ? SCALE UP    │ │
│  │                │    │ restarts >= 1    ? SCALE UP    │ │
│  └────────────────┘    └─────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              │
                         Cria/Atualiza
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                          HPA                                │
│           minReplicas: 5  ──────►  maxReplicas: 30          │
└─────────────────────────────────────────────────────────────┘
                              │
                           Escala
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                      Deployment                             │
│    [Pod1] [Pod2] [Pod3] [Pod4] [Pod5] ... [Pod30]          │
└─────────────────────────────────────────────────────────────┘

Instalação

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
  3. KEDA - Event-driven autoscaler
  4. NGINX Ingress - Com suporte a Lua (Keep Request)

Triggers Configurados

Trigger 1: Pods Indisponíveis

query: |
  kube_deployment_status_replicas_unavailable{
    deployment="node-bugado",
    namespace="default"
  }
threshold: '1'

Comportamento: Se 1 ou mais pods estão indisponíveis → SCALE UP

Trigger 2: Restarts Frequentes

query: |
  sum(increase(
    kube_pod_container_status_restarts_total{
      namespace="default",
      pod=~"node-bugado.*"
    }[2m]
  ))
threshold: '1'

Comportamento: Se houve 1+ restart nos últimos 2 min → SCALE UP

Configuração de Scaling

# Limites
minReplicaCount: 5     # Alta disponibilidade
maxReplicaCount: 30    # Limite de recursos

# Velocidade
pollingInterval: 1     # Verifica a cada 1s

# Scale UP - Agressivo
scaleUp:
  stabilizationWindowSeconds: 0   # Imediato
  policies:
    - type: Pods
      value: 5                    # +5 pods por vez
      periodSeconds: 1            # A cada 1s

# Scale DOWN - Conservador
scaleDown:
  stabilizationWindowSeconds: 10  # Aguarda 10s
  policies:
    - type: Percent
      value: 50                   # -50% por vez
      periodSeconds: 5            # A cada 5s

Exemplo de Scaling

Tempo 0s:   5 pods, 0 unavailable
Tempo 1s:   Pod1 trava, 1 unavailable → KEDA detecta
Tempo 2s:   Escala para 10 pods (+5)
Tempo 3s:   Pod2 trava, 2 unavailable
Tempo 4s:   Escala para 15 pods (+5)
...
Tempo 10s:  30 pods (máximo)
Tempo 20s:  Pods reiniciaram, 0 unavailable
Tempo 30s:  Scale down: 30 → 15 → 8 → 5

Teste de Stress

# Terminal 1: Monitorar pods
watch kubectl get pods

# Terminal 2: Monitorar HPA
watch kubectl get hpa

# Terminal 3: Teste de stress
./teste-stress.sh

# Ou manualmente - 1000 requests
for i in {1..1000}; do
  curl -s http://localhost/ &
done

Comandos Úteis

# 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?query=kube_deployment_status_replicas_unavailable"

# Logs do KEDA
kubectl logs -n keda -l app=keda-operator -f

# Métricas em tempo real
watch -n1 'kubectl get pods | grep node-bugado | wc -l'

Queries PromQL

# Pods indisponíveis
kube_deployment_status_replicas_unavailable{deployment="node-bugado"}

# Total de restarts
sum(kube_pod_container_status_restarts_total{pod=~"node-bugado.*"})

# Restarts nos últimos 2 minutos
sum(increase(kube_pod_container_status_restarts_total{pod=~"node-bugado.*"}[2m]))

# Pods prontos
kube_deployment_status_replicas_ready{deployment="node-bugado"}

# Réplicas desejadas vs disponíveis
kube_deployment_status_replicas{deployment="node-bugado"}
kube_deployment_status_replicas_available{deployment="node-bugado"}

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

./cleanup.sh

Lições

  1. Métricas customizadas: Escale por qualquer métrica, não só CPU/memória
  2. Reação rápida: KEDA pode verificar a cada 1 segundo
  3. Scale UP agressivo: Adicione capacidade rapidamente quando necessário
  4. Scale DOWN conservador: Evite oscilação (flapping)
  5. Observabilidade: Métricas são a base para automação inteligente

Trade-offs

Aspecto HPA Padrão KEDA
Configuração Simples Mais complexa
Métricas CPU/Mem Qualquer
Dependências Nenhuma Victoria Metrics/Prometheus
Flexibilidade Baixa Alta
Latência ~15s ~1s (configurável)

Próxima Aula

Aula 06: Deploy do n8n via Helm em ambiente local (OrrStack/k3s/Docker Desktop/minikube/kind/etc).