Metodologia8 min

Autoscaling e Previsibilidade: escalando sem surpresas

Autoscaling promete escalar automaticamente, mas sem configuração adequada pode causar mais problemas. Aprenda a configurar autoscaling previsível.

Autoscaling é a promessa de escalar automaticamente baseado em demanda. Na prática, configurações inadequadas resultam em escalamento tardio, oscilação constante, ou custos descontrolados. Este artigo explora como configurar autoscaling de forma previsível.

Autoscaling não é "configure e esqueça". É "configure, teste, ajuste, monitore".

Como Autoscaling Funciona

O loop básico

1. Métricas coletadas
2. Comparadas com threshold
3. Decisão: scale up, down, ou nada
4. Ação executada
5. Cooldown
6. Repete

Tempo de reação

Evento (pico) → Detecção → Decisão → Provisionamento → Ready

Timeline típica:
0s:    Pico começa
15s:   Métrica reflete pico
30s:   HPA decide escalar
60s:   Pod scheduled
90s:   Container pulled
120s:  App ready

Total: ~2 minutos até nova capacidade

Problema: Se seu pico dura 1 minuto, autoscaling não ajuda.

Horizontal Pod Autoscaler (HPA)

Configuração básica

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Problemas comuns

1. Threshold muito alto:

# ❌ 90% utilização
# Escala só quando já está saturado
averageUtilization: 90

2. Threshold muito baixo:

# ❌ 30% utilização
# Escala com qualquer variação normal
averageUtilization: 30

3. Cooldown inadequado:

# ❌ Sem configurar behavior
# Scale up/down muito rápido = thrashing

Configuração otimizada

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 65    # Margem para reagir
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0    # Escala imediatamente
      policies:
      - type: Percent
        value: 100                      # Pode dobrar
        periodSeconds: 15
      - type: Pods
        value: 4                        # Ou +4 pods
        periodSeconds: 15
      selectPolicy: Max                 # Usa o maior
    scaleDown:
      stabilizationWindowSeconds: 300   # Espera 5 min estável
      policies:
      - type: Percent
        value: 10                       # Reduz 10% por vez
        periodSeconds: 60

Métricas customizadas

CPU nem sempre é o melhor indicador:

metrics:
# Baseado em requests por segundo
- type: Pods
  pods:
    metric:
      name: http_requests_per_second
    target:
      type: AverageValue
      averageValue: 1000

# Baseado em fila
- type: External
  external:
    metric:
      name: queue_messages_ready
      selector:
        matchLabels:
          queue: orders
    target:
      type: Value
      value: 100

Vertical Pod Autoscaler (VPA)

Quando usar

HPA: Adiciona mais pods (horizontal)
VPA: Aumenta recursos de pods existentes (vertical)

HPA: Bom para stateless
VPA: Bom para databases, caches, stateful

Configuração

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "Auto"    # Recreate pods when needed
  resourcePolicy:
    containerPolicies:
    - containerName: app
      minAllowed:
        cpu: 100m
        memory: 128Mi
      maxAllowed:
        cpu: 4
        memory: 8Gi

VPA + HPA

# ❌ VPA e HPA no mesmo recurso (CPU)
# Conflito: ambos tentam ajustar

# ✅ VPA para memória, HPA para CPU
# VPA
resourcePolicy:
  containerPolicies:
  - containerName: app
    controlledResources: ["memory"]

# HPA
metrics:
- type: Resource
  resource:
    name: cpu

Cluster Autoscaler

Como funciona

Pod pending (sem node disponível)
    → Cluster Autoscaler detecta
    → Provisiona novo node
    → Pod scheduled no novo node

Configuração

# Configuração de node pools (GKE exemplo)
gcloud container node-pools create scaling-pool \
  --cluster=my-cluster \
  --enable-autoscaling \
  --min-nodes=1 \
  --max-nodes=10 \
  --machine-type=e2-standard-4

Tempo de provisionamento

AWS:   2-5 minutos
GCP:   1-3 minutos
Azure: 2-4 minutos

→ Para picos rápidos, Cluster Autoscaler é lento demais

Previsibilidade: A Chave do Autoscaling

Problema 1: Thrashing

Carga varia: 60% → 75% → 65% → 80% → 70%

Com threshold 70%:
- Scale up (75%)
- Scale down (65%)
- Scale up (80%)
- Scale down (70%)

= Pods sendo criados e destruídos constantemente

Solução: Stabilization window

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300

Problema 2: Escalamento tardio

Pico às 9:00
HPA detecta às 9:00:30
Novos pods ready às 9:02:00

= 2 minutos de degradação

Solução: Scaling preditivo ou pré-aquecimento

# Scheduled scaling (AWS)
aws autoscaling put-scheduled-action \
  --scheduled-action-name "morning-scale" \
  --auto-scaling-group-name "app-asg" \
  --recurrence "0 8 * * MON-FRI" \
  --min-size 10

Problema 3: Cold start

Novo pod:
- Container start: 5s
- App initialization: 30s
- Warm-up: 60s

Total: ~95s até performance ideal

Solução: Readiness probe adequado + warm-up

readinessProbe:
  httpGet:
    path: /health/ready
    port: 8080
  initialDelaySeconds: 60    # Tempo para warm-up
  periodSeconds: 5

Problema 4: Custos descontrolados

Autoscaling sem limite:
- Pico anômalo ou ataque
- Escala para 100 pods
- Custo: $10,000/dia

→ "Autoscaling funcionou perfeitamente... e faliu a empresa"

Solução: Limites + alertas

maxReplicas: 20    # Limite hard

# Alerta quando próximo do limite
- alert: HPA_NearMaxReplicas
  expr: |
    kube_hpa_status_current_replicas / kube_hpa_spec_max_replicas > 0.8
  for: 5m

Estratégias de Autoscaling

1. Reativo puro

Detecta aumento → Escala → Estabiliza

Prós: Simples, responde a qualquer padrão Contras: Sempre atrasado

2. Preditivo

Analisa histórico → Prevê pico → Escala antes
# AWS Predictive Scaling
aws autoscaling put-scaling-policy \
  --policy-name "predictive" \
  --policy-type "PredictiveScaling" \
  --predictive-scaling-configuration '{
    "MetricSpecifications": [...],
    "Mode": "ForecastAndScale"
  }'

Prós: Escala antes do pico Contras: Só funciona com padrões previsíveis

3. Scheduled

Escala em horários fixos baseado em padrão conhecido
# Kubernetes CronJob para ajustar HPA
apiVersion: batch/v1
kind: CronJob
metadata:
  name: scale-up-morning
spec:
  schedule: "0 8 * * MON-FRI"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: kubectl
            image: bitnami/kubectl
            command:
            - kubectl
            - patch
            - hpa/app-hpa
            - --patch
            - '{"spec":{"minReplicas":10}}'

Prós: Previsível, custos controlados Contras: Não responde a anomalias

4. Híbrido (recomendado)

Base: scheduled scaling para padrões conhecidos
+
Reativo: HPA para variações inesperadas
+
Limites: max replicas + alertas

Testando Autoscaling

Validação obrigatória

# 1. Teste de scale up
# Gera carga gradual, observa scaling

# 2. Teste de scale down
# Remove carga, observa cooldown

# 3. Teste de limite
# Atinge max replicas, observa comportamento

# 4. Teste de cold start
# Mede tempo até pod estar performático

Métricas para validar

1. Tempo para scale up (target < 2 min)
2. Frequência de thrashing (target = 0)
3. % de requests durante scaling (target > 99% success)
4. Custo durante picos (target dentro do budget)

Conclusão

Autoscaling previsível requer:

  1. Thresholds adequados: nem muito alto, nem muito baixo
  2. Behavior configurado: stabilization windows para evitar thrashing
  3. Métricas corretas: CPU nem sempre é o melhor indicador
  4. Limites definidos: max replicas + alertas de custo
  5. Testes validados: nunca confie em autoscaling não testado

Antes de confiar no autoscaling:

  1. Meça tempo de scale up
  2. Simule picos realistas
  3. Valide comportamento em limites
  4. Monitore custos ativamente

Autoscaling é como piloto automático: ótimo quando funciona, desastroso quando falha. Sempre tenha plano B.

autoscalingkubernetescloudelasticidade
Compartilhar:
Read in English

Quer entender os limites da sua plataforma?

Entre em contato para uma avaliação de performance.

Fale Conosco