Ajuste Automático de Réplicas de Pods com Base no Tamanho da Fila de Mensagens

O Horizontal Pod Autoscaler (HPA) no Kubernetes permite dimensionar automaticamente o número de réplicas de um Pod com base em métricas de utilização de recursos. Nas versões anteriores à 1.6, o HPA limitava-se a métricas de CPU e memória. Contudo, esta abordagem muitas vezes não reflete a carga real da aplicação, especialmente para cargas de trabalho intensivas em I/O ou rede. Com a introdução do HPA v2, tornou-se possível utilizar métricas personalizadas provenientes de sistemas de monitorização externos, como o Prometheus, para orientar o escalonamento.

Este guia aborda um cenário prático: o dimensionamento automático de Pods de consumidor numa aplicação produtor-consumidor, com base no comprimento de uma fila de mensagens. A aplicação de exemplo compreende dois módulos:

  • Produtor: Expõe um endpoint HTTP que produz mensagens para uma fila. Disponibiliza as métricas Prometheus hpa_app_queue_length (Gauge) e hpa_app_produce_count (Counter).
  • Consumidor: Consome mensagens da fila, simulando um processamento de 10ms. Disponibiliza a métrica hpa_app_consume_count (Counter).

Ambiente Inicial

Assumindo que um Prometheus Operator já está instalado no cluster, procedemos com a implantação da aplicação de exemplo.

# Clonar o repositório e instalar o Chart
git clone https://github.com/yxwuxuanl/hpa-example.git
cd hpa-example/deploy
helm dep build
helm install hpa-app . -n default

# Verificar os Pods em execução
kubectl get pods -l "app.kubernetes.io/instance=hpa-app" -n default

Este comando implenta um Pod de produtor e dois Pods de consumidor. Ao executar helm test hpa-app, uma carga de trabalho simulada gera tráfego crescente (de 100 para 500 QPS). Como a taxa máxima de consumo com duas réplicas é de 200 mensagens/segundo, a fila acumula rapidamente mensagens, revelando a necessidade de um escalonamento automático.

Configuração do Prometheus Adapter para a Metrics API

O Prometheus Adapter atua como uma ponte, traduzidno consultas ao Prometheus em respostas compatíveis com a Metrics API do Kubernetes, que é o padrão para métricas personalizadas (custom.metrics.k8s.io) e externas. Ativamos este componente e atualizamos o release do Helm.

# Atualizar o release com o Prometheus Adapter habilitado
helm upgrade hpa-app . -n default \
  --set prometheus-adapter.enabled=true \
  --set prometheus-adapter.prometheus.url="http://prometheus-server.monitoring.svc"

# Verificar se o endpoint da Metrics API foi registado
kubectl get apiservice v1beta1.custom.metrics.k8s.io

Após a implantação bem-sucedida, podemos inspecionar os recursos de métricas disponíveis:

kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq '.resources[].name'

Definição do Recurso HorizontalPodAutoscaler

O próximo passo é criar o recurso HPA que escalará os Pods do consumidor com base na métrica hpa_app_queue_length. O objetivo (targetAverageValue) define o limiar desejado de comprimento médio da fila por Pod.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-app-consumer-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hpa-app-consumer
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Pods
      pods:
        metric:
          name: hpa_app_queue_length
        target:
          type: AverageValue
          averageValue: 500

Aplicar este manifesto:

kubectl apply -f hpa-consumer.yaml

Verificação do Comportamento de Escalonamento

Com o HPA ativo, ao observar o seu estado e os eventos, devemos testemunhar o Kubrenetes a adicionar novas réplicas do consumidor à medida que a fila de mensagens excede o limiar de 500 mensagens em média por Pod. Isto permite que a taxa de consumo acompanhe dinamicamente a taxa de produção durante picos de tráfego.

# Monitorizar o HPA e os Pods
kubectl get hpa hpa-app-consumer-hpa -n default -w
kubectl get pods -l "app.kubernetes.io/instance=hpa-app" -n default -w

Tags: kubernetes HPA Autoscaling Prometheus Metrics API

Publicado em 6-7 06:47 por Thomas