27 de maio de 20267 min de leitura

Autoscaling de GPU no Kubernetes com KEDA: Construindo um external scaler para workloads de IA

epower

Cloud Native Computing Foundation

Banner - Autoscaling de GPU no Kubernetes com KEDA: Construindo um external scaler para workloads de IA

TL;DR: Este artigo mostra como construir um external scaler para KEDA que lê métricas diretamente das GPUs via NVML, algo que o scaler nativo não permite por restrições de CGO e localidade. A solução é um DaemonSet que expõe dados como utilização, memória e temperatura via gRPC. Para empresas brasileiras que rodam LLMs e agentic inference, isso reduz custos com GPUs ociosas e melhora a eficiência energética (GreenOps).

Se você roda workloads de GPU no Kubernetes — vLLM, Triton, jobs de treinamento ou as novas stacks de agentic inference — já deve ter esbarrado em um problema clássico: o caminho padrão de autoscaling ainda raciocina sobre CPU e memória, enquanto a GPU que realmente está fazendo o trabalho fica oculta. Esse desalinhamento desperdiça capacidade de aceleradores caros, aumenta a latência de inferência e gera consumo de energia desnecessário exatamente no momento em que as empresas estão tentando escalar LLMs e Agentic Ops de forma responsável.

Eu queria que o KEDA escalasse com base nos sinais que importam para workloads de GPU: utilização, memória, temperatura e consumo de energia. Na prática, isso não é só um problema de custo. É também um problema de GreenOps, porque ciclos de GPU desperdiçados se traduzem diretamente em energia desperdiçada e maiores emissões de Escopo 3.

Acontece que isso é mais difícil do que parece.

O problema

O KEDA é compilado com CGO_ENABLED=0. A NVIDIA Management Library (NVML) — a forma padrão de ler métricas da GPU — exige CGO. Então você não pode simplesmente adicionar um scaler de GPU no core do KEDA como faria com um scaler de Prometheus ou Kafka.

Há um segundo problema: o operador do KEDA roda como um único deployment. As chamadas NVML são locais — elas leem métricas da GPU no mesmo node. Você não consegue consultar a GPU 0 do node-A a partir de um pod rodando no node-B.

Portanto, um scaler nativo do KEDA estava fora de cogitação. Eu precisava de algo que rodasse em cada node com GPU e expusesse métricas pela rede.

A arquitetura

Para resolver isso, construímos um DaemonSet personalizado (veja a implementação de referência aqui: keda-gpu-scaler) que roda nos nodes com GPU. Nessa arquitetura, cada pod:

  1. Chama NVML via go-nvml para ler métricas locais da GPU.
  2. Serve essas métricas via gRPC usando a interface ExternalScaler do KEDA.
  3. O operador KEDA se conecta ao scaler e conduz as decisões do HPA.

Imagem: Fluxograma do GPU Node (DaemonSet)

Esse é o mesmo padrão que o Kubernetes usa para device plugins e o metrics server — um agente por node que coleta dados de hardware local.

Em quais métricas você pode escalar?

O scaler expõe estas métricas por GPU:

  • gpu_utilization – percentual de utilização SM (compute)
  • memory_utilization – utilização do controlador de memória
  • memory_used_percent – uso de VRAM como percentual
  • temperature – temperatura do die da GPU em Celsius
  • power_draw – consumo atual de energia em watts

Para nodes multi-GPU, você escolhe uma agregação: max, min, avg ou sum. Ou pode mirar em um índice específico de GPU.

Perfis pré-construídos

A maioria das pessoas roda um de poucos tipos de workload de GPU, então adicionei perfis que definem defaults sensíveis:

triggers:
  - type: external
    metadata:
      scalerAddress: "keda-gpu-scaler.gpu-scaler.svc.cluster.local:6000"
      profile: "vllm-inference"
Perfil Métrica Target Activation Uso
vllm-inference memory_used_percent 80% 5% LLM serving, scale-to-zero
triton-inference gpu_utilization 75% 10% Triton model serving
training gpu_utilization 90% 0% Treinamento, sem scale-to-zero
batch memory_used_percent 70% 1% Inferência em lote, scale-down agressivo

Você pode sobrescrever qualquer valor. Ou ignorar os perfis e definir metricType, targetValue e activationThreshold diretamente.

Início rápido

Instalar com Helm

helm install gpu-scaler deploy/helm/keda-gpu-scaler \
  --namespace gpu-scaler --create-namespace

O chart cria um DaemonSet que mira nodes com nvidia.com/gpu.present=true e tolera o taint nvidia.com/gpu. Ele usa o container runtime NVIDIA por padrão — se seu cluster não tiver isso, defina nvmlHostMounts.enabled=true para montar os device files diretamente.

Criar um ScaledObject

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: vllm-gpu-scaler
spec:
  scaleTargetRef:
    name: vllm-deployment
  minReplicaCount: 0
  maxReplicaCount: 8
  triggers:
    - type: external
      metadata:
        scalerAddress: "keda-gpu-scaler.gpu-scaler.svc.cluster.local:6000"
        profile: "vllm-inference"

Pronto. Agora o KEDA vai escalar seu deployment vLLM com base no uso de memória da GPU, incluindo scale-to-zero quando ocioso.

Testando sem GPUs

O scaler tem um modo mock para testes. A suíte de testes e2e sobe um servidor gRPC real com dados falsos de GPU e exercita o fluxo completo: IsActive → GetMetricSpec → GetMetrics. São 11 testes cobrindo perfis, caminhos de erro, streaming e modos de agregação. Tudo roda em CI sem hardware de GPU.

go test -v -tags=e2e -race ./tests/e2e/

O que vem a seguir

Construir external scalers personalizados é uma forma poderosa de estender o ecossistema CNCF. Mostra como um projeto graduado como o KEDA pode permanecer flexível, permitindo que engenheiros criem DaemonSets customizados que se adaptam a padrões mais recentes de infraestrutura de IA, sem forçar toda workload à mesma abstração.

Os trechos de código e o repositório compartilhados acima servem como uma implementação de referência open-source dessa arquitetura. Se você está rodando workloads de GPU no Kubernetes e quer autoscaling que entenda nativamente métricas de GPU, explorar a interface ExternalScaler do KEDA é um excelente ponto de partida.

GitHub: keda-gpu-scaler

Perguntas Frequentes

  • Como o KEDA consegue escalar GPUs se ele não suporta NVML nativamente?
    KEDA é compilado com CGO_ENABLED=0, o que impede o uso direto da biblioteca NVML (que exige CGO). A solução é rodar um DaemonSet em cada node com GPU, que chama NVML localmente e expõe as métricas via gRPC usando a interface ExternalScaler do KEDA. O KEDA então consulta esse serviço para tomar decisões de scaling.

  • Quais métricas de GPU o external scaler expõe?
    O scaler expõe cinco métricas por GPU: gpu_utilization (percentual de utilização SM), memory_utilization (utilização do controlador de memória), memory_used_percent (uso de VRAM), temperature (temperatura do die em °C) e power_draw (consumo em watts). Para nós multi-GPU, é possível agregar com max, min, avg ou sum, ou mirar em um índice específico.

  • É possível testar o scaler sem ter GPUs físicas?
    Sim. O scaler inclui um modo mock que gera dados falsos de GPU. O conjunto de testes e2e sobe um servidor gRPC real com esses dados e exercita todo o fluxo (IsActive, GetMetricSpec, GetMetrics). São 11 testes que cobrem perfis, caminhos de erro, streaming e modos de agregação, executados em CI sem hardware de GPU.

  • Como configurar perfis pré-definidos para vLLM ou Triton?
    O scaler oferece perfis como vllm-inference (baseado em memory_used_percent com target 80%), triton-inference (gpu_utilization 75%), training (gpu_utilization 90%) e batch (memory_used_percent 70%). Basta definir o campo profile no ScaledObject, podendo sobrescrever qualquer valor ou definir metricType e targetValue manualmente.

  • Quais as vantagens desse scaler para empresas brasileiras?
    Empresas que rodam LLMs ou agentic inference em clusters Kubernetes podem reduzir drasticamente o custo com GPUs ociosas, já que o scaling é baseado em métricas reais de utilização e memória. Além disso, a economia de energia (GreenOps) é tangível, pois GPU parada consome energia sem produzir throughput, algo crítico em ambientes com restrições orçamentárias e de sustentabilidade.


Artigo originalmente publicado por epower em Cloud Native Computing Foundation.

Gostou? Compartilhe:
Precisa de ajuda?Fale com nossos especialistas 👋
Avatar Walcew - Headset