Estratégias de escalonamento com HPA e VPA no Kubernetes
1. Fundamentos do escalonamento automático no Kubernetes
1.1. Conceitos de escalonamento horizontal (HPA) vs. vertical (VPA)
O escalonamento automático no Kubernetes permite adaptar dinamicamente os recursos dos workloads às demandas reais. O Horizontal Pod Autoscaler (HPA) ajusta o número de réplicas de um deployment, enquanto o Vertical Pod Autoscaler (VPA) ajusta os limites de CPU e memória dos contêineres individuais.
Enquanto o HPA adiciona ou remove pods para distribuir a carga, o VPA modifica os recursos solicitados por cada pod, otimizando a utilização de recursos sem alterar a quantidade de réplicas. A escolha entre eles depende do perfil da aplicação e das métricas monitoradas.
1.2. Métricas base para decisão de escala
As métricas mais comuns para decisão de escala incluem:
- CPU: Utilização percentual em relação ao request definido
- Memória: Consumo absoluto ou percentual
- Métricas customizadas: QPS (queries por segundo), latência, tamanho de fila
O Metrics Server coleta essas métricas dos nós e as expõe via API de métricas, que é consumida pelos controladores HPA e VPA.
1.3. Componentes do ecossistema
Os principais componentes são:
- Metrics Server: Coleta métricas de recursos (CPU/memória) dos nós e pods
- API de métricas: Endpoint
/apis/metrics.k8s.io/que expõe dados em tempo real - Controlador HPA: Loop de reconciliação que calcula o número desejado de réplicas
- Controlador VPA: Recomenda e aplica ajustes de recursos nos contêineres
2. Configurando o Horizontal Pod Autoscaler (HPA) na prática
2.1. Sintaxe e parâmetros essenciais do manifesto HPA
Um manifesto HPA básico utiliza os seguintes parâmetros:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
2.2. Estratégias de comportamento avançado
Para evitar oscilações (thrashing), o HPA permite configurar políticas de estabilização:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Pods
value: 4
periodSeconds: 60
A janela de estabilização (stabilizationWindowSeconds) impede que o HPA reduza réplicas imediatamente após uma queda momentânea de carga.
2.3. Exemplo completo: HPA para um deployment web com base em CPU e requisições HTTP
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: 100
behavior:
scaleDown:
stabilizationWindowSeconds: 180
policies:
- type: Percent
value: 20
periodSeconds: 120
3. Vertical Pod Autoscaler (VPA): quando e como usar
3.1. Modos de operação do VPA
O VPA oferece quatro modos de operação:
- Off: Apenas recomendações, sem aplicar mudanças
- Auto: Aplica recomendações automaticamente, reiniciando pods quando necessário
- Recreate: Similar ao Auto, mas sempre recria o pod (não usa atualização in-place)
- Initial: Aplica recomendações apenas na criação do pod
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: app-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: app
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: "*"
minAllowed:
cpu: 100m
memory: 50Mi
maxAllowed:
cpu: 1
memory: 500Mi
3.2. Limitações do VPA
O VPA apresenta limitações importantes:
- Reinicialização de pods: No modo Auto, o VPA precisa recriar o pod para aplicar novas recomendações
- Conflitos com HPA: Nunca use VPA e HPA baseados na mesma métrica (CPU/memória)
- Workloads stateful: Podem sofrer interrupções durante a reinicialização
3.3. Casos de uso ideais
O VPA é ideal para:
- Workloads stateful com picos imprevisíveis de memória
- Bancos de dados que precisam de ajuste fino de recursos
- Aplicações com perfis de consumo variáveis ao longo do dia
- Ambientes onde o custo de recursos é crítico e precisa ser otimizado
4. Estratégias combinadas: HPA + VPA em harmonia
4.1. Regra de ouro
A regra fundamental é: nunca usar VPA e HPA baseados na mesma métrica. Se o HPA escala por CPU e o VPA também ajusta CPU, haverá conflitos e comportamento imprevisível.
4.2. Padrão de arquitetura recomendado
A arquitetura ideal combina:
- HPA baseado em métricas de aplicação (QPS, latência, tamanho de fila)
- VPA em modo "Off" para fornecer recomendações de recursos
- Ajustes manuais periódicos baseados nas recomendações do VPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa-qps
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app
minReplicas: 3
maxReplicas: 15
metrics:
- type: Pods
pods:
metric:
name: qps
target:
type: AverageValue
averageValue: 500
4.3. Exemplo de deployment com HPA customizado e VPA em modo "Off"
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: app-vpa-recommender
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: app
updatePolicy:
updateMode: "Off"
Com essa configuração, o VPA gera recomendações que podem ser consultadas via kubectl describe vpa app-vpa-recommender, sem interferir no escalonamento horizontal.
5. Métricas customizadas e escalonamento baseado em eventos
5.1. Integrando Prometheus Adapter
O Prometheus Adapter permite expor métricas customizadas do Prometheus para o HPA:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa-custom
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app
metrics:
- type: Object
object:
metric:
name: requests_per_second
describedObject:
apiVersion: v1
kind: Service
name: app-service
target:
type: Value
value: 1000
5.2. Uso do KEDA para escalonamento por eventos
O KEDA (Kubernetes Event-driven Autoscaling) estende o HPA para escalonar baseado em eventos de fontes externas:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-scaler
spec:
scaleTargetRef:
name: consumer-app
triggers:
- type: kafka
metadata:
topic: orders
bootstrapServers: kafka-cluster:9092
consumerGroup: order-consumers
lagThreshold: "100"
5.3. Comparação entre HPA nativo e KEDA
| Característica | HPA Nativo | KEDA |
|---|---|---|
| Métricas suportadas | CPU, memória, custom | 50+ fontes (Kafka, RabbitMQ, AWS SQS) |
| Complexidade | Baixa | Média |
| Flexibilidade | Limitada | Alta |
| Manutenção | Nativo do Kubernetes | Componente externo |
6. Troubleshooting e boas práticas de escalonamento
6.1. Depuração de HPA
Comandos essenciais para diagnóstico:
# Verificar status do HPA
kubectl get hpa web-app-hpa
# Detalhes completos
kubectl describe hpa web-app-hpa
# Logs do controlador HPA
kubectl logs -n kube-system deployment/controller-manager
# Verificar métricas disponíveis
kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/default/pods
6.2. Evitando thrashing
Para evitar oscilações indesejadas:
- Configure
stabilizationWindowSecondsadequado (180-300s para scale-down) - Defina limites mínimos e máximos realistas (
minReplicas,maxReplicas) - Use políticas de scale-up e scale-down diferentes
- Monitore o comportamento com dashboards
6.3. Monitoramento contínuo
Recomenda-se configurar:
- Dashboards com métricas de escala (réplicas atuais, desejadas, métricas alvo)
- Alertas para anomalias (escalonamento excessivo, falha no HPA)
- Logs centralizados para análise de padrões de escala
7. Cenários avançados e considerações finais
7.1. Escalonamento em clusters multi-nó e com nós spot
Em clusters com nós spot/preemptíveis, configure:
podDisruptionBudgetpara garantir disponibilidade mínima- HPA com
maxReplicasmaior para compensar perda de nós - VPA com limites mínimos para evitar pods muito pequenos em nós instáveis
7.2. Integração com Cluster Autoscaler
O Cluster Autoscaler adiciona ou remove nós quando há pods pendentes. A integração com HPA/VPA funciona assim:
- HPA solicita mais pods → pods ficam pendentes por falta de recursos → Cluster Autoscaler adiciona nós
- VPA aumenta requests de pods → nós podem ficar sobrecarregados → Cluster Autoscaler adiciona nós
7.3. Tendências futuras
As tendências incluem:
- Escalonamento preditivo com machine learning: Prever picos de demanda e escalar antecipadamente
- Karpenter: Substitui o Cluster Autoscaler com provisionamento mais rápido e flexível
- Escalonamento baseado em custo: Otimizar recursos considerando custos de diferentes tipos de nós
Referências
- Kubernetes Horizontal Pod Autoscaler Documentation — Documentação oficial do HPA com exemplos completos e referência de API
- Kubernetes Vertical Pod Autoscaler Documentation — Guia oficial do VPA com modos de operação e limitações
- KEDA Documentation - Event-driven Autoscaling — Documentação oficial do KEDA com exemplos de escalonamento por eventos
- Prometheus Adapter for Kubernetes — Repositório oficial com instruções de instalação e configuração de métricas customizadas
- Cluster Autoscaler Documentation — Guia oficial do Cluster Autoscaler com boas práticas de integração com HPA/VPA
- Karpenter - Node Provisioning for Kubernetes — Documentação do Karpenter para provisionamento eficiente de nós