Pular para o conteúdo

Escala automática

Avançado16 min de leiturakubernetes

Escalar automaticamente é ajustar capacidade a demanda sem alguém acordado para isso. São duas camadas independentes e que precisam funcionar juntas: mais réplicas do Pod (HPA, KEDA) e mais nós para receber essas réplicas (Cluster Autoscaler, Karpenter). Ligar a primeira sem a segunda produz Pods em Pending; ligar a segunda sem limites produz fatura.

O HPA precisa de duas coisas para funcionar: resources.requests declarado no Pod e o metrics-server instalado. Sem request, a porcentagem alvo não tem denominador e o HPA fica <unknown>.

Janela do terminal
kubectl top pods -n loja # falha aqui = metrics-server ausente
kubectl autoscale deployment loja -n loja \
--cpu-percent=70 --min=3 --max=20
kubectl get hpa loja -n loja -w
kubectl describe hpa loja -n loja # os eventos explicam por que não escalou

O alvo de 70% é ponto de partida, não regra: com alvo alto demais a escala chega tarde; baixo demais você paga por réplicas ociosas. --min deve suportar o tráfego normal com uma réplica fora do ar.

CPU raramente é o gargalo de um serviço web. Fila crescente, latência p95 e requisições por segundo descrevem melhor a dor do usuário. Com o adapter de métricas instalado:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: loja, namespace: loja }
spec:
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: loja }
minReplicas: 3
maxReplicas: 20
metrics:
- type: Pods
pods:
metric: { name: http_requests_per_second } # exposta pelo seu app
target: { type: AverageValue, averageValue: "80" }
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # evita subir e descer a cada pico curto

behavior é a diferença entre escala útil e oscilação. Subir rápido e descer devagar é o padrão sensato: o custo de uma réplica sobrando por cinco minutos é menor que o de uma faltando por trinta segundos.

O VPA ajusta requests e limits observando consumo real. Não use VPA em modo Auto sobre a mesma métrica do HPA — um muda o denominador que o outro usa e a escala entra em laço. A combinação segura é VPA em Off (recomendação apenas) para você calibrar requests, com HPA cuidando das réplicas.

Para consumidores de fila, o sinal certo é o tamanho da fila, não a CPU do worker. O KEDA traduz esse sinal em HPA e é o caminho para escalar a zero quando não há mensagem.

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata: { name: processador, namespace: loja }
spec:
scaleTargetRef: { name: processador }
minReplicaCount: 0
maxReplicaCount: 30
cooldownPeriod: 300
triggers:
- type: aws-sqs-queue
metadata:
queueURL: https://sqs.sa-east-1.amazonaws.com/000000000000/pedidos
queueLength: "20"
awsRegion: sa-east-1

Escalar a zero só vale se a partida a frio couber no seu SLO: contar imagem, agendamento e readiness costuma dar dezenas de segundos. Para tráfego síncrono de usuário, prefira minReplicaCount: 1.

O Cluster Autoscaler cresce e encolhe node groups pré-definidos; o Karpenter provisiona o nó pelo formato do Pod pendente, o que reduz desperdício e acelera. Em qualquer um:

  • Defina PodDisruptionBudget, ou consolidar nós derruba seu serviço.
  • Sem requests corretos não há decisão correta — o autoscaler só enxerga requests.
  • Teto explícito de nós e de tipos de instância é o seu limite de fatura.
  • Spot exige tolerância a interrupção; misture com sob demanda para a carga crítica.

Se o Pod fica Pending com o autoscaler ligado, leia os eventos antes de mexer em tamanho: taint sem toleration, zona sem volume e topologySpreadConstraints impossíveis bloqueiam o agendamento por motivos que capacidade nenhuma resolve.

Próximo passo: para automatizar operação que não cabe em réplicas, veja Operators e CRDs. Se a escala não acontece, siga o Diagnóstico em Kubernetes.