GPU-автоскейлинг на Kubernetes с KEDA: создание внешнего скейлера. autoscaling.. autoscaling. external scaler.. autoscaling. external scaler. gpu.. autoscaling. external scaler. gpu. GreenOps.. autoscaling. external scaler. gpu. GreenOps. helm.. autoscaling. external scaler. gpu. GreenOps. helm. keda.. autoscaling. external scaler. gpu. GreenOps. helm. keda. Kubernetes.. autoscaling. external scaler. gpu. GreenOps. helm. keda. Kubernetes. nvml.. autoscaling. external scaler. gpu. GreenOps. helm. keda. Kubernetes. nvml. triton.. autoscaling. external scaler. gpu. GreenOps. helm. keda. Kubernetes. nvml. triton. vllm.
GPU-автоскейлинг на Kubernetes с KEDA: создание внешнего скейлера - 1

Если вы запускаете GPU-нагрузки (графические ускорители) на Kubernetes — vLLM, Triton, обучающие задачи или более новые стеки агентного инференса, — вы наверняка сталкивались со знакомой проблемой: стандартный автоскейлинг по-прежнему мыслит в категориях CPU и памяти, а GPU, который реально делает работу, остается невидимым. Из-за этого простаивает дорогая емкость ускорителей, растет задержка инференса и расходуется лишняя энергия — ровно там, где компании пытаются ответственно масштабировать LLM и Agentic Ops (подходы к эксплуатации Agentic-систем).

VK Cloud перевела статью автора, который хотел бы, чтобы KEDA масштабировался по сигналам, которые важны для GPU-нагрузок: утилизации, памяти, температуре и энергопотреблению. На практике это не только вопрос стоимости. Это еще и вопрос GreenOps (экологичный подход к эксплуатации с минимизацией углеродного следа): впустую потраченные GPU-циклы напрямую превращаются в потраченную энергию и более высокие выбросы категории Scope 3 (косвенные выбросы в цепочке создания стоимости).

Оказалось, что это сложнее, чем кажется. Дальше повествование идет от его лица

Проблема

KEDA собирается с CGO_ENABLED=0. NVIDIA Management Library (NVML) — стандартный способ читать метрики GPU — требует CGO (механизм Go для вызова кода на C). Поэтому GPU-скейлер нельзя просто добавить в ядро KEDA так же, как добавляют скейлер для Prometheus или Kafka.

А еще оператор KEDA работает как единый deployment. Вызовы NVML локальны: они читают метрики с GPU на той же ноде. Запросить GPU 0 на ноды-A из пода на ноду-B не получится.

Так что нативный скейлер для KEDA отпадает. Мне нужно что-то, что запускается на каждой GPU-ноде и отдает метрики по сети.

Архитектура

Чтобы решить эту задачу, можно собрать кастомный DaemonSet (мою референсную реализацию смотрите здесь: keda-gpu-scaler), который работает на GPU-ноде. В этой архитектуре каждый под:

  1. Вызывает NVML через go-nvml, чтобы прочитать локальные метрики GPU.

  2. Отдает их по gRPC через интерфейс ExternalScaler от KEDA.

  3. Оператор KEDA подключается к скейлеру и управляет решениями HPA.

Блок-схема GPU-node (DaemonSet)

Блок-схема GPU-node (DaemonSet)

Это тот же паттерн, который Kubernetes использует для device plugins и metrics server: агент на каждой ноде собирает локальные данные оборудования.

По каким метрикам можно масштабировать

Скейлер отдает по каждому GPU такие метрики:

  • gpu_utilization — процент утилизации SM (Streaming Multiprocessor, вычислительное ядро GPU);

  • memory_utilization — утилизация контроллера памяти;

  • memory_used_percent — использование VRAM (видеопамять GPU) в процентах;

  • temperature — температура кристалла GPU в градусах Цельсия;

  • power_draw — текущее энергопотребление в ваттах.

Для multi-GPU ноды вы выбираете агрегацию: max, min, avg или sum — либо нацеливаетесь на конкретный индекс GPU.

Готовые профили

Чаще всего запускают один из нескольких типов GPU-нагрузок, поэтому я добавил профили с разумными значениями по умолчанию:

triggers:

  - type: external

    metadata:

      scalerAddress: "keda-gpu-scaler.gpu-scaler.svc.cluster.local:6000"

      profile: "vllm-inference"

Профиль

Метрика

Цель

Активация

Сценарий

vllm-inference

memory_used_percent

80%

5%

Обслуживание LLM, scale-to-zero

triton-inference

gpu_utilization

75%

10%

Обслуживание моделей Triton

training

gpu_utilization

90%

0%

Обучающие задачи, без scale-to-zero

batch

memory_used_percent

70%

1%

Пакетный инференс, агрессивное уменьшение масштаба

Любое значение можно переопределить или вообще пропустить профили и задать metricType, targetValue, activationThreshold напрямую.

Быстрый старт

Установка через Helm

helm install gpu-scaler deploy/helm/keda-gpu-scaler 

  --namespace gpu-scaler --create-namespace

Chart разворачивает DaemonSet, который нацеливается на ноде с nvidia.com/gpu.present=true и толерирует taint nvidia.com/gpu. По умолчанию он использует NVIDIA container runtime — если в вашем кластере его нет, установите nvmlHostMounts.enabled=true, чтобы примонтировать файлы устройств напрямую.

Создание 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"

Вот и всё. Теперь KEDA будет масштабировать ваш vLLM deployment по использованию памяти GPU, включая scale-to-zero (уменьшение до нуля реплик) при простое.

Тестирование без GPU

У скейлера есть режим мок-коллектора для тестирования. Набор e2e-тестов поднимает реальный gRPC-сервер с фейковыми данными GPU и прогоняет весь поток IsActive → GetMetricSpec → GetMetrics. 11 тестов покрывают профили, пути ошибок, стриминг, режимы агрегации. Все запускаются в CI без какого-либо GPU-оборудования.

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

Что дальше

Создание кастомных external скейлеров — мощный способ расширить экосистему CNCF. Это показывает, как graduated-проект вроде KEDA остается гибким: инженеры собирают кастомные DaemonSet под более новые паттерны AI-инфраструктуры и не вгоняют каждую нагрузку в одну и ту же абстракцию.

Сниппеты кода выше и репозиторий — это open-source референсная реализация архитектуры. Если вы запускаете GPU-нагрузки на Kubernetes и хотите автоскейлинг, который нативно понимает метрики GPU, начните с интерфейса ExternalScaler от KEDA — это отличная отправная точка.

GitHub: keda-gpu-scaler

Автор: levashove

Источник