O Kubernetes HPA no Node.js aumenta ou reduz réplicas de uma API ou worker conforme métricas observadas. HPA significa HorizontalPodAutoscaler e atua sobre recursos escaláveis, como Deployment e StatefulSet, ajustando a quantidade de Pods dentro de limites definidos.
Autoscaling não corrige uma aplicação lenta nem substitui planejamento de capacidade. Para funcionar bem, cada Pod precisa ter requests coerentes, startup previsível, métricas confiáveis e comportamento seguro ao entrar ou sair do conjunto. Caso contrário, o HPA pode oscilar, reagir tarde ou escalar uma dependência já saturada.
Neste guia, você aprenderá a configurar HPA com CPU, memória e métricas customizadas, controlar scale-up e scale-down, evitar flapping, escolher min e max replicas, observar decisões e adaptar aplicações Node.js.
Como o HPA funciona?
A documentação de Horizontal Pod Autoscaling explica que o controlador consulta métricas periodicamente e calcula uma nova quantidade de réplicas. Para uma métrica média, a ideia básica é:
réplicas desejadas = ceil(
réplicas atuais × métrica atual / métrica alvo
)Se quatro Pods consomem, em média, o dobro da meta, a recomendação tende a ser oito. O algoritmo também considera métricas ausentes, Pods não prontos e janelas de estabilização.
Pré-requisitos
Para CPU e memória, o cluster precisa oferecer a API metrics.k8s.io, normalmente por meio do Metrics Server. Verifique:
kubectl get apiservice v1beta1.metrics.k8s.io
kubectl top pods -n productionA documentação do Metrics Server descreve instalação e requisitos. Métricas customizadas usam adaptadores para custom.metrics.k8s.io ou external.metrics.k8s.io.
Deployment de destino
O HPA altera spec.replicas do Deployment. Consulte Kubernetes Deployment no Node.js.
apiVersion: apps/v1
kind: Deployment
metadata:
name: orders-api
spec:
replicas: 3
selector:
matchLabels:
app: orders-api
template:
metadata:
labels:
app: orders-api
spec:
containers:
- name: api
image: registry.example.com/orders-api:1.4.3
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1
memory: 512MiRequests são essenciais
CPU em porcentagem é calculada em relação ao request. Se um container usa 200m e solicita 250m, a utilização é 80%. Sem request de CPU, o HPA não consegue calcular essa métrica para o Pod.
Requests muito baixos produzem porcentagens infladas e escala excessiva. Requests altos demais escondem pressão. Defina valores com dados de produção.
HPA por CPU
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: orders-api
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: orders-api
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60O objetivo é manter a média de CPU em 60% do request. Isso não significa 60% de um core, a menos que o request seja um core.
Escolhendo a meta de CPU
Deixe margem para picos e para o tempo de criação de novos Pods. Em APIs Node.js, CPU pode subir por serialização, compressão, criptografia, validação e garbage collection. Uma meta entre 50% e 70% é comum como ponto inicial, mas precisa de teste de carga.
HPA por memória
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70Memória é uma métrica perigosa para scale-down. O heap pode permanecer grande mesmo após a carga cair, e vazamentos fazem o HPA criar mais Pods sem resolver a causa. Use memória junto com alertas e análise de heap.
Múltiplas métricas
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70O HPA calcula uma recomendação para cada métrica e usa a maior. Se uma métrica sugere oito réplicas e outra cinco, o destino será oito.
Métrica por container
Quando existe sidecar, a métrica do Pod pode misturar consumos diferentes. A API autoscaling/v2 suporta ContainerResource:
- type: ContainerResource
containerResource:
name: cpu
container: api
target:
type: Utilization
averageUtilization: 60Se renomear o container, atualize o HPA de forma compatível durante o rollout.
Métricas customizadas
CPU nem sempre representa demanda. Workers podem escalar pela profundidade de uma fila; APIs, por requisições em andamento ou latência.
- type: External
external:
metric:
name: queue_messages_ready
selector:
matchLabels:
queue: invoices
target:
type: AverageValue
averageValue: "20"Esse exemplo tenta manter vinte mensagens por Pod. O adaptador precisa expor a métrica ao Kubernetes.
Prometheus Adapter
Prometheus pode alimentar custom metrics por meio de um adapter. A métrica deve ter labels estáveis e cardinalidade controlada. Consulte Prometheus no Node.js.
Não escale por latência isoladamente
Latência alta pode ser causada por banco, cache ou serviço externo. Criar mais Pods aumenta conexões e pode piorar a dependência. Combine latência com concorrência, fila, saturação e erros.
Scale-up rápido
behavior:
scaleUp:
stabilizationWindowSeconds: 0
selectPolicy: Max
policies:
- type: Percent
value: 100
periodSeconds: 60
- type: Pods
value: 4
periodSeconds: 60O controlador pode dobrar a quantidade ou adicionar quatro Pods por minuto, escolhendo a política mais permissiva.
Scale-down conservador
behavior:
scaleDown:
stabilizationWindowSeconds: 300
selectPolicy: Min
policies:
- type: Percent
value: 20
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60A janela de cinco minutos reduz flapping. selectPolicy: Min escolhe a redução menor entre as políticas.
Por que o scale-down deve ser lento?
Remover Pods rapidamente pode:
- encerrar requisições em andamento;
- redistribuir conexões de forma brusca;
- provocar rebalances em consumidores;
- eliminar cache quente;
- reagir a uma queda temporária.
A aplicação deve implementar Graceful Shutdown no Node.js.
Readiness e startup
Pods novos não devem entrar na média antes de estarem realmente prontos. Configure startup e readiness para excluir warm-up, migrations e conexão inicial. Veja Probes Kubernetes em Node.js.
Cold start
Se um Pod demora quarenta segundos para atender, o HPA sempre reage atrasado. Reduza tempo de imagem, imports, inicialização, consultas e carregamento de configuração. Mantenha minReplicas suficiente para absorver o pico durante o scale-up.
MinReplicas
Não use um como padrão para serviços críticos. Duas ou três réplicas permitem rollout, falha de nó e capacidade imediata. O mínimo também deve considerar PodDisruptionBudget.
MaxReplicas
O máximo é um limite de segurança e custo. Defina a partir de:
- conexões máximas do banco;
- partições de fila;
- capacidade do cluster;
- rate limits externos;
- orçamento;
- limites de licença.
Vinte Pods com pool de vinte conexões podem abrir quatrocentas conexões. Ajuste o pool por réplica.
HPA e Cluster Autoscaler
O HPA cria demanda por Pods. Se não houver capacidade nos nós, eles ficam Pending. O autoscaler de cluster precisa adicionar nós, o que leva mais tempo. Monitore os dois loops.
HPA e rollout
Durante rolling update, o HPA altera o total do Deployment e o controlador distribui réplicas entre ReplicaSets. maxSurge pode aumentar temporariamente o número de Pods e o consumo.
Não edite replicas manualmente
Quando HPA controla um Deployment, alterações manuais em spec.replicas serão substituídas. Em GitOps, normalmente omita replicas do manifesto ou coordene a ferramenta para evitar drift contínuo.
Aplicando o HPA
kubectl apply -f hpa.yaml
kubectl get hpa -n production
kubectl describe hpa orders-api -n productionO describe mostra métricas atuais, metas, condições e eventos.
Condições importantes
- AbleToScale: o controlador consegue ler e alterar o alvo.
- ScalingActive: existe métrica válida.
- ScalingLimited: a recomendação atingiu min ou max.
Diagnóstico
kubectl get hpa orders-api -n production -o yaml
kubectl top pods -l app=orders-api -n production
kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/production/podsVerifique requests ausentes, adapter indisponível, selector errado, métricas atrasadas e Pods não prontos.
Teste de carga
Valide com carga progressiva:
- observe a linha de base;
- aumente RPS gradualmente;
- meça o atraso até a primeira escala;
- confirme que Pods ficam Ready;
- verifique banco e fila;
- reduza a carga;
- observe a estabilização e o scale-down.
Compare p95, erros, CPU, event loop lag e quantidade de réplicas.
Node.js e CPU
Um processo Node.js executa JavaScript principalmente em uma thread. Quando um core fica saturado, latência e event loop lag sobem. Várias réplicas distribuem conexões, mas não corrigem código síncrono pesado. Use Worker Threads ou serviços especializados quando necessário.
Workers e filas
Para consumidores, limite concorrência por Pod e use fila como métrica. Mais Pods do que partições ou mensagens disponíveis não aumenta throughput. Garanta idempotência e shutdown correto durante scale-down.
Observabilidade
Monitore:
- réplicas atuais, desejadas, mínimas e máximas;
- motivo da última escala;
- CPU e memória por Pod;
- Pods Pending e tempo de scheduling;
- tempo até readiness;
- event loop lag;
- latência, erros e throughput;
- conexões do banco;
- profundidade e idade da fila.
Erros comuns
- Sem requests: utilização de CPU fica indefinida.
- Meta baixa: o HPA escala continuamente.
- Scale-down agressivo: o serviço oscila.
- Max sem considerar banco: conexões esgotam.
- CPU para fila: demanda fica invisível enquanto o consumidor espera I/O.
- Min igual a um: não existe margem para picos.
- Startup lento: réplicas chegam tarde.
- Escalar vazamento: mais Pods apenas adiam a falha.
Conclusão
O Kubernetes HPA no Node.js ajusta réplicas com base em CPU, memória ou métricas de negócio. O resultado depende de requests realistas, métricas disponíveis, min e max seguros e comportamento de escala bem configurado.
Use scale-up rápido e scale-down estabilizado, mantenha capacidade mínima e observe dependências. Para workers, prefira fila; para APIs, combine saturação e demanda. Com testes de carga e shutdown gracioso, o HPA melhora elasticidade sem transformar cada variação em instabilidade.



