Como configurar autoscaling baseado em métricas customizadas no Kubernetes
1. Fundamentos do Autoscaling no Kubernetes
O Kubernetes oferece três mecanismos principais de autoscaling: o Horizontal Pod Autoscaler (HPA), que ajusta o número de réplicas de pods; o Vertical Pod Autoscaler (VPA), que ajusta recursos de CPU e memória dos pods; e o Cluster Autoscaler, que dimensiona o número de nós do cluster.
O HPA padrão utiliza métricas de recursos como CPU e memória, coletadas pelo Metrics Server. No entanto, essas métricas são insuficientes para cenários onde o comportamento da aplicação depende de indicadores mais específicos, como:
- Tamanho de filas de mensagens (RabbitMQ, Kafka)
- Latência de requisições HTTP
- Throughput de processamento por segundo
- Número de conexões simultâneas ativas
Para esses casos, o Kubernetes permite o uso de métricas customizadas, que podem ser expostas pela própria aplicação ou por sistemas externos, e consumidas pelo HPA para decisões de escalonamento mais precisas.
2. Arquitetura de Métricas Customizadas
A arquitetura típica envolve três componentes principais:
- Metrics Server: Coleta métricas padrão de recursos (CPU/memória) de cada nó e pod.
- Prometheus Adapter: Implementa a API de métricas customizadas do Kubernetes, traduzindo consultas PromQL em métricas que o HPA pode consumir.
- KEDA (Kubernetes Event-driven Autoscaling): Alternativa que simplifica o autoscaling baseado em eventos de fontes como Kafka, RabbitMQ, AWS SQS, entre outras.
O fluxo de dados segue esta sequência:
Aplicação → Endpoint /metrics (Prometheus) → Prometheus Server → Prometheus Adapter → API de Métricas Customizadas → HPA
A API de métricas customizadas se divide em três tipos:
- Resource Metrics: CPU e memória (Metrics Server)
- Custom Metrics: Métricas da própria aplicação, acessíveis via
custom.metrics.k8s.io - External Metrics: Métricas de sistemas externos ao cluster, via
external.metrics.k8s.io
3. Instalação e Configuração do Prometheus Adapter
Primeiro, certifique-se de que o Prometheus está instalado no cluster. Caso não esteja, utilize o Helm para instalar:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/prometheus --namespace monitoring --create-namespace
Em seguida, instale o Prometheus Adapter:
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring \
--set prometheus.url=http://prometheus-server.monitoring.svc \
--set prometheus.port=80
Para mapear queries PromQL para métricas customizadas, edite o values.yaml do adapter:
rules:
default: false
custom:
- seriesQuery: '{__name__=~"http_requests_total"}'
resources:
overrides:
namespace:
resource: namespace
pod:
resource: pod
name:
matches: "^(.*)_total$"
as: "${1}_per_second"
metricsQuery: 'rate(<<.Series>>{<<.LabelMatchers>>}[2m])'
Esse exemplo converte a métrica http_requests_total em uma taxa por segundo, acessível como http_requests_per_second.
4. Criando Métricas Customizadas na Aplicação
Sua aplicação precisa expor métricas no formato OpenMetrics. Exemplo em Node.js usando a biblioteca prom-client:
const client = require('prom-client');
const gauge = new client.Gauge({
name: 'app_queue_size',
help: 'Current queue size of pending messages',
labelNames: ['queue_name']
});
// Atualizar o valor periodicamente
setInterval(() => {
gauge.set({ queue_name: 'orders' }, getCurrentQueueSize());
}, 5000);
// Endpoint /metrics
app.get('/metrics', async (req, res) => {
res.set('Content-Type', client.register.contentType);
res.end(await client.register.metrics());
});
Boas práticas para evitar explosão de séries temporais:
- Limitar cardinalidade de labels (evitar
user_id,request_id) - Usar labels com valores previsíveis e controlados
- Preferir métricas de taxa (
rate()) sobre contadores absolutos
Teste localmente:
curl http://localhost:3000/metrics | grep app_queue_size
5. Configuração do HPA com Métricas Customizadas
O HPA pode usar três tipos de métricas: Pods (média por pod), Object (valor absoluto de um objeto) e External (métricas externas ao cluster).
Exemplo prático: autoscaling baseado em tamanho de fila (tipo Object, referenciando um serviço):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: worker-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: worker
minReplicas: 2
maxReplicas: 10
metrics:
- type: Object
object:
metric:
name: app_queue_size
describedObject:
apiVersion: v1
kind: Service
name: worker-service
target:
type: AverageValue
averageValue: 100
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
Neste exemplo, o HPA mantém a média de mensagens na fila em torno de 100. Se o valor ultrapassar, mais pods são criados; se ficar abaixo, pods são removidos gradualmente.
6. Estratégias Avançadas e Boas Práticas
Múltiplas métricas no mesmo HPA
É possível combinar métricas de CPU com métricas customizadas:
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: app_queue_size
target:
type: AverageValue
averageValue: 200
O HPA escolhe a métrica que requer mais réplicas em cada ciclo de avaliação.
Configuração de cooldown e stabilization
Para evitar thrashing (oscilação rápida entre escalar para cima e para baixo), configure:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
Isso permite escalonamento rápido para cima, mas reduz gradualmente para baixo.
Monitoramento do comportamento
Use kubectl describe hpa para ver eventos recentes e condições:
kubectl describe hpa worker-hpa
Exiba métricas em tempo real com:
kubectl get hpa worker-hpa --watch
7. Troubleshooting e Validação
Verifique se a API de métricas customizadas está disponível:
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq .
Teste uma consulta específica:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/services/worker-service/app_queue_size" | jq .
Erros comuns e soluções:
- Métrica não encontrada: Verifique se a query PromQL está correta e se as labels correspondem
- Labels ausentes: O Prometheus Adapter precisa de labels
namespaceepodpara métricas do tipoPods - Timeout na consulta: Aumente o tempo limite no adapter ou otimize a query PromQL
Para testes de carga simulados, use ferramentas como hey ou wrk:
hey -n 10000 -c 50 http://worker-service:3000/process
8. Integração com CICD e Observabilidade
No pipeline de CI/CD, adicione validações antes do deploy:
# Verificar se a métrica customizada existe
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/staging/services/worker-service/app_queue_size"
# Validar o YAML do HPA
kubectl apply --dry-run=client -f hpa.yaml
Configure alertas no Prometheus para falhas de autoscaling:
groups:
- name: autoscaling-alerts
rules:
- alert: HPAStuck
expr: kube_horizontalpodautoscaler_spec_target_replicas != kube_horizontalpodautoscaler_status_current_replicas
for: 15m
labels:
severity: warning
annotations:
summary: "HPA {{ $labels.horizontalpodautoscaler }} não está convergindo"
Documente um runbook para incidentes:
Runbook: Falha no Autoscaling Baseado em Métricas Customizadas
1. Verificar disponibilidade do Prometheus Adapter:
kubectl get pods -n monitoring | grep prometheus-adapter
2. Verificar logs do adapter:
kubectl logs -n monitoring deployment/prometheus-adapter
3. Testar consulta direta à API custom metrics:
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1
4. Verificar se a aplicação está expondo métricas:
kubectl port-forward pod/worker-pod 3000:3000
curl http://localhost:3000/metrics
5. Reiniciar o Prometheus Adapter se necessário:
kubectl rollout restart deployment/prometheus-adapter -n monitoring
Referências
- Kubernetes Horizontal Pod Autoscaler Documentation — Documentação oficial sobre HPA, incluindo métricas customizadas e exemplos de configuração.
- Prometheus Adapter for Kubernetes Metrics APIs — Repositório oficial com documentação, exemplos de regras e guias de instalação.
- KEDA: Kubernetes Event-driven Autoscaling — Documentação oficial do KEDA, alternativa para autoscaling baseado em eventos de filas, bancos de dados e serviços cloud.
- Prometheus Best Practices for Metric and Label Naming — Guia oficial sobre boas práticas para nomeação de métricas e labels, essencial para evitar alta cardinalidade.
- Horizontal Pod Autoscaler Walkthrough with Custom Metrics — Tutorial prático passo a passo da documentação oficial do Kubernetes sobre configuração de HPA com métricas customizadas.
- Grafana Dashboards for Kubernetes Autoscaling — Repositório de dashboards prontos para monitorar métricas de autoscaling, HPA e performance do cluster.