Autoscaling de pods no EKS: como escalar aplicações com HPA, KEDA e VPA
Sua aplicação no AWS EKS roda com o mesmo número de réplicas de madrugada e no pico? Neste artigo, você vai entender o autoscaling de pods no EKS: como o HPA calcula réplicas, como usar métricas customizadas e externas, como o KEDA escala por eventos e até zero, e quando o VPA entra. Inclui exemplos em YAML, boas práticas e um checklist para começar.
Series: Otimização de custos com AWS EKS (5 articles)
- …
- 4Autoscaling de pods no EKS: como escalar aplicações com HPA, KEDA e VPA This article
No post sobre application profiling e rightsizing , ajustamos o tamanho de cada pod do AWS EKS ao consumo real da aplicação. No entanto, a demanda muda ao longo do dia. Um serviço que precisa de 20 réplicas no pico pode precisar de 3 de madrugada. Se as réplicas não acompanham essa variação, você paga por pods ociosos fora do pico ou fica sem capacidade no pico. É isso que o autoscaling de pods no EKS resolve.
Um post da série "Otimização de custos com AWS EKS".
Neste post, você vai entender como o Horizontal Pod Autoscaler (HPA) calcula as réplicas e como escalar por métricas customizadas e externas. Em seguida, vai ver como o KEDA escala por eventos e até zero e, por fim, quando faz sentido usar o Vertical Pod Autoscaler (VPA) .
Por que escalar pods reduz desperdício
Num cluster EKS, as réplicas de cada aplicação reservam capacidade dos nós pelos seus requests. Assim, cada réplica a mais que fica rodando sem carga ocupa capacidade de nós AWS EC2 que você paga, mesmo sem processar nada.
O autoscaling de pods no EKS resolve uma parte do problema: ajusta quantas réplicas existem a cada momento. A outra parte, que é ajustar quantos nós existem, fica com o Karpenter ou o Cluster Autoscaler, assunto do próximo post. Na prática, os dois trabalham juntos: o HPA cria ou remove pods, e o autoscaler de nós cria ou remove os nós para acomodá-los.
Há ainda uma dependência importante com o post anterior. O HPA mede a utilização de CPU e memória como porcentagem do request. Se o request está inflado, a utilização parece baixa e o HPA demora a escalar. Por isso, o rightsizing vem antes do autoscaling.

Horizontal Pod Autoscaler (HPA): como funciona
O HPA é um recurso nativo do Kubernetes, então você não precisa instalá-lo. Ele só depende de uma fonte de métricas: segundo a documentação do EKS sobre o HPA , é o Metrics Server que fornece esses dados — e ele não vem instalado por padrão no EKS.
O cálculo das réplicas
O controlador do HPA compara o valor atual da métrica com o valor desejado e calcula:
réplicas desejadas = arredondar para cima ( réplicas atuais × valor atual ÷ valor desejado )
Por exemplo, se o alvo é 50% de CPU e as 4 réplicas estão em 100%, o HPA dobra o número de réplicas, indo para 8, atingindo o alvo de 50%. Se estão em 25%, ele reduz pela metade a quantidade de réplicas, respeitando o mínimo e o máximo configurados. A documentação do Kubernetes sobre o HPA detalha o algoritmo.
Estabilização: evitando o efeito sanfona
Se a métrica oscila, o HPA pode criar e remover pods o tempo todo. Para evitar isso, a API
autoscaling/v2 tem o bloco behavior:- Scale down: por padrão, o HPA usa uma janela de estabilização de 300 segundos. Ou seja, ele considera as recomendações dos últimos 5 minutos e escolhe a maior, para só reduzir quando a queda se mantém.
- Scale up: por padrão, não há janela de estabilização. Assim que a métrica sobe, o HPA escala.
- Políticas: você pode limitar quantos pods (ou que porcentagem) entram e saem por período.
Exemplo: HPA por CPU com comportamento controlado
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: checkout
namespace: ecommerce
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: checkout
minReplicas: 2 # mínimo para alta disponibilidade
maxReplicas: 20 # teto para proteger o orçamento
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # porcentagem do request de CPU
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50 # remove no máximo 50% das réplicas por minuto
periodSeconds: 60
Métricas de recurso, customizadas e externas
CPU e memória nem sempre representam bem a carga. Uma API, por exemplo, pode ficar lenta por excesso de requisições antes de a CPU subir. Por isso o HPA não lê de um componente específico, e sim de três APIs de métricas agregadas do Kubernetes — e para cada uma há uma implementação que a serve:
| API | Para quê | Quem serve |
|---|---|---|
| metrics.k8s.io (Resource Metrics) | CPU e memória por pod | Metrics Server (padrão); ou o Prometheus Adapter |
| custom.metrics.k8s.io (Custom Metrics) | métricas de dentro do cluster (ex.: requisições por segundo, conexões ativas) | o Prometheus Adapter |
| external.metrics.k8s.io (External Metrics) | métricas de fora do cluster (ex.: tamanho de uma fila, métrica de outro sistema) | o KEDA |
O Metrics Server implementa só a primeira — CPU e memória. Para escalar por requisições por segundo ou por profundidade de fila, você precisa de um adaptador que sirva as outras duas APIs. Num cluster que já roda Prometheus, o Prometheus Adapter pode inclusive servir também a
metrics.k8s.io e dispensar o Metrics Server.Para métricas do AWS CloudWatch , o caminho mais simples hoje é o KEDA, que tem um scaler específico para o CloudWatch.
Vários sinais no mesmo HPA: o maior vence
Essas APIs não são excludentes. Um único HPA pode declarar várias métricas ao mesmo tempo — CPU, uma métrica customizada e uma externa, misturadas. Quando há mais de uma, o HPA calcula as réplicas desejadas para cada métrica isoladamente e fica com o maior resultado.
Imagine um HPA com 4 réplicas e três métricas: CPU a 90% (alvo 70%), 30 requisições por segundo por pod (alvo 50) e uma fila com 120 mensagens (alvo de 10 por pod). As contas dão, respectivamente, 6, 3 e 12 réplicas — então o HPA vai para 12. A lógica é de segurança: se qualquer dimensão pede mais capacidade, o HPA atende a mais exigente.
Há duas consequências práticas:
- O "maior vence" só vale para subir. Para o HPA reduzir réplicas, todas as métricas precisam concordar que dá para descer — e ainda respeitando a janela de estabilização. Uma métrica alta sozinha segura os pods lá em cima.
- Se uma métrica fica indisponível, o HPA é conservador: pode seguir com um scale-up, mas evita o scale-down enquanto não tiver todas as leituras.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: checkout
namespace: ecommerce
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: checkout
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource # CPU — metrics.k8s.io (Metrics Server)
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods # req/s por pod — custom.metrics.k8s.io (Prometheus Adapter)
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "50"
- type: External # fila — external.metrics.k8s.io (KEDA)
external:
metric:
name: sqs_queue_length
target:
type: AverageValue
averageValue: "10"
É exatamente esse mecanismo que o KEDA usa por baixo: ao criar um
ScaledObject, ele gera um HPA com a métrica externa nessa lista. Assim, CPU (Metrics Server) e fila (KEDA) podem escalar o mesmo Deployment lado a lado.KEDA: autoscaling de pods no EKS orientado a eventos
Já encontramos o KEDA na seção anterior, como a peça que serve as métricas externas ao HPA. Agora vamos aprofundar. O KEDA (Kubernetes Event-Driven Autoscaling) é um projeto da CNCF que trabalha junto com o HPA, sem substituí-lo — foi ele que, no exemplo das três métricas, entregou o tamanho da fila. O que ainda não vimos é o que ele faz além de servir métricas: escala até zero quando não há eventos e traz o workload de volta quando eles chegam, algo que o HPA sozinho não faz. Os detalhes estão nos conceitos do KEDA .
Por isso, esse comportamento é especialmente útil para consumidores de filas e jobs em lote. Um consumidor que fica com 3 réplicas paradas a noite inteira à espera de mensagens passa a ficar com zero.
Exemplo: escalar um consumidor pelo tamanho de uma fila AWS SQS
O scaler
aws-sqs-queue usa a profundidade de uma fila do AWS SQS . O parâmetro queueLength diz quantas mensagens cada pod consegue processar: se o alvo é 10 e a fila tem 30 mensagens, o KEDA escala para 3 pods.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-aws-auth
namespace: pagamentos
spec:
podIdentity:
provider: aws # usa a identidade IAM configurada para o KEDA
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: consumidor-pedidos
namespace: pagamentos
spec:
scaleTargetRef:
name: consumidor-pedidos # Deployment que lê a fila
minReplicaCount: 0 # sem mensagens, nenhum pod
maxReplicaCount: 30
triggers:
- type: aws-sqs-queue
authenticationRef:
name: keda-aws-auth
metadata:
queueURL: https://sqs.us-east-1.amazonaws.com/111122223333/pedidos
queueLength: "10" # mensagens por pod
awsRegion: us-east-1
Por padrão, o KEDA conta as mensagens visíveis e as que estão em processamento. A identidade usada precisa de permissão de leitura dos atributos da fila. Veja os parâmetros e as opções de autenticação na documentação do scaler de SQS .
KEDA com métricas do Prometheus
O KEDA também escala por consultas PromQL. Um blog da AWS mostra o KEDA escalando um microsserviço por requisições por segundo, uma métrica guardada no AWS Managed Service for Prometheus . Nesse padrão, o KEDA cria e alimenta o HPA por baixo, e os painéis do AWS Managed Grafana mostram o escalonamento acontecendo.
KEDA e Karpenter juntos
O blog da AWS Brasil sobre KEDA e Karpenter mostra o ciclo completo com uma fila SQS. À medida que a fila cresce, o KEDA cria novos pods; os pods que não cabem ficam pendentes, e o Karpenter provisiona os nós. Quando a fila esvazia, os pods saem e os nós ociosos são removidos. Além disso, num caso de produção mais recente , o time de tecnologia financeira das lojas da Amazon usa KEDA e Karpenter para escalar um banco analítico em picos de fechamento mensal, com centenas de usuários simultâneos.
VPA: quando ajustar o tamanho em vez do número de pods
O Vertical Pod Autoscaler, que vimos no post sobre application profiling e rightsizing, ajusta o tamanho de cada pod, e não o número de réplicas. Ele é útil em workloads que não escalam horizontalmente, como alguns bancos e serviços com estado, e para gerar recomendações de requests.
O ponto de atenção é a combinação com o HPA. O EKS Best Practices Guide sobre aplicações altamente disponíveis recomenda não usar HPA e VPA na mesma métrica. Se o HPA escala por CPU e o VPA também ajusta a CPU, os dois reagem ao mesmo sinal e entram em conflito. Na prática:
- Use o HPA para o número de réplicas;
- Use o VPA em modo
Offpara gerar recomendações de requests e aplicá-las pelo seu pipeline; - Se precisar dos dois automáticos, faça o HPA escalar por uma métrica diferente, como requisições por segundo ou tamanho de fila.
Boas práticas de autoscaling de pods no EKS
- Faça o rightsizing antes. O HPA mede utilização como porcentagem do request; requests errados distorcem o autoscaling.
- Defina
minReplicaspensando em disponibilidade. Em produção, pelo menos 2 réplicas, distribuídas entre zonas. - Defina
maxReplicaspensando no orçamento. O teto evita que um pico anômalo ou um erro escale a aplicação sem limite. - Escolha a métrica certa. Para APIs, requisições por segundo ou latência costumam ser melhores que CPU. Para consumidores, o tamanho da fila.
- Controle o
behavior. Suba rápido e desça devagar, para não remover pods no meio de uma oscilação. - Prepare a aplicação para escalar. Readiness probes corretas, inicialização rápida e encerramento gracioso evitam erros durante o scale up e o scale down.
- Use PodDisruptionBudgets equilibrados. Eles protegem a aplicação, mas não podem impedir o autoscaler de nós de remover nós ociosos.
- Combine com o autoscaler de nós. Sem ele, os pods novos ficam pendentes e os nós vazios continuam na conta.
Por onde começar
Para colocar o autoscaling de pods no EKS em prática:
- Instale o Metrics Server como add-on do EKS.
- Comece pelos workloads com demanda variável, que aparecem na visibilidade de custos com grande diferença entre pico e vale.
- Crie um HPA por CPU com
minReplicas,maxReplicasebehavior, e acompanhe por alguns dias. - Troque para métricas de negócio onde a CPU não representa bem a carga, usando o KEDA ou um adaptador de métricas.
- Use o KEDA com
minReplicaCount: 0em consumidores de fila e workloads que podem ficar parados.
Checklist do post
- O Metrics Server está instalado no cluster
- Os workloads com HPA têm requests ajustados ao uso real
- Todo HPA tem
minReplicas,maxReplicasebehaviordefinidos - A métrica de escala representa a carga real da aplicação
- Consumidores de fila e jobs avaliados para o KEDA com escala até zero
- HPA e VPA não atuam na mesma métrica do mesmo workload
- Readiness probes e encerramento gracioso estão configurados
- Existe um autoscaler de nós para acompanhar o número de pods
Perguntas frequentes
Preciso instalar o HPA no EKS?
Não. O HPA é um recurso nativo do Kubernetes. Você só precisa de uma fonte de métricas, como o Metrics Server, que pode ser instalado como add-on do EKS.
Qual a diferença entre HPA e VPA?
O HPA muda o número de réplicas de um workload. O VPA muda o tamanho (requests e limits) de cada réplica. Eles resolvem problemas diferentes e não devem atuar na mesma métrica.
O KEDA substitui o HPA?
Não. O KEDA trabalha junto com o HPA: ele fornece métricas externas para o HPA e cuida da escala entre zero e uma réplica, que o HPA sozinho não faz.
Dá para escalar um deployment até zero no EKS?
Sim, com o KEDA e
minReplicaCount: 0. Quando não há eventos, o KEDA remove todas as réplicas e as recria quando os eventos voltam.Por que o meu HPA demora para escalar?
As causas mais comuns são requests de CPU acima do uso real, que fazem a utilização parecer baixa, e uma janela de estabilização longa demais. Também vale conferir se o Metrics Server está funcionando.
Próximo post
O autoscaling de pods decide quantos pods você precisa. Mas, se os nós não acompanharem, os pods novos ficam pendentes e os nós vazios continuam na conta. No próximo post da série, vamos comparar o Cluster Autoscaler e o Karpenter e mostrar como a consolidação de nós reduz o custo do cluster.
Series: Otimização de custos com AWS EKS (5 articles)
- …
- 4Autoscaling de pods no EKS: como escalar aplicações com HPA, KEDA e VPA This article
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article