Как масштабировать рабочие нагрузки AMD GPU на DOKS с использованием KEDA

Как масштабировать рабочие нагрузки AMD GPU на DOKS с использованием KEDA


Введение

По мере того как облачные приложения растут в масштабе и сложности, возможность динамически выделять вычислительные ресурсы становится критически важной — особенно для рабочих нагрузок, требующих GPU. Kubernetes предоставляет встроенное автоскейлирование, но оно часто оказывается недостаточным, когда вам нужно масштабироваться на основе внешних или пользовательских метрик. Здесь на помощь приходит KEDA (автоскейлирование на основе событий Kubernetes). KEDA позволяет вашим рабочим нагрузкам в Kubernetes масштабироваться на основе метрик в реальном времени из таких источников, как Prometheus.

В этом руководстве мы пройдемся по тому, как автоматизировать масштабирование рабочей нагрузки на базе GPU AMD, работающей на DigitalOcean Kubernetes (DOKS), с использованием Prometheus и KEDA. Эта настройка позволяет вам реагировать на актуальные метрики и эффективно и экономично оптимизировать использование GPU.

Ключевые выводы

  • Автоматическое масштабирование GPU по событиям: Узнайте, как использовать KEDA для автоматического масштабирования рабочих нагрузок на AMD GPU в DigitalOcean Kubernetes (DOKS) на основе метрик в реальном времени от Prometheus, что позволяет настраиваемое и экономически эффективное масштабирование сверх стандартного автоматического масштабирования на основе CPU.
  • Разделение рабочей нагрузки: Изучите лучшие практики изоляции задач с использованием GPU и без GPU с помощью нескольких пулов узлов, оптимизации распределения ресурсов и снижения операционных затрат.
  • Поддержка нативных GPU AMD: Воспользуйтесь встроенной поддержкой графических процессоров AMD MI300X в DOKS, с активированным плагином устройства GPU от AMD и экспортером метрик по умолчанию для бесшовной интеграции и наблюдаемости.
  • Пользовательские метрики для масштабирования: Узнайте, как настроить Prometheus для сбора пользовательских метрик GPU и использовать их в качестве триггеров для масштабирования, позволяя сопоставить распределение ресурсов с фактическим спросом на рабочую нагрузку (например, выводы машинного обучения, обработка видео, аналитика в реальном времени).
  • Практическое пошаговое руководство: Следуйте практическому руководству, охватывающему настройку кластера, конфигурацию пула узлов, включение метрик GPU, развертывание образца нагрузки и реализацию автомасштабирования на основе KEDA.
  • Тестирование и валидация: Узнайте, как симулировать нагрузку на GPU, наблюдать за работой автоматического масштабирования и проверять, что новые узлы GPUProvisioning и рабочие нагрузки автоматически переназначаются по мере увеличения спроса.
  • Готовые к производству шаблоны: Получите информацию о создании надежных, масштабируемых и экономически эффективных приложений на базе GPU в Kubernetes, используя инструменты с открытым исходным кодом и лучшие практики облачных технологий.

К концу этого учебника вы сможете с уверенностью развернуть и автоматически масштабировать задачи на GPU в DOKS, используя масштабирование, основанное на событиях, для оптимизации производительности и затрат для требовательных AI/ML и вычислительно интенсивных приложений.

Предварительные требования

  • Учетная запись DigitalOcean с доступом к кластеру DOKS.
  • Токен API DO с правами на запись
  • Базовые знания Kubernetes и Helm

Шаг 1 — Создайте кластер DOKS с поддержкой графических процессоров AMD.

Вы можете создать новый кластер DOKS, нажав кнопку Создать в правом верхнем углу вашей панели управления DigitalOcean или перейдя в раздел Ресурсы в вашем проекте и выбрав:

  1. Kubernetes → Создать кластер Kubernetes.

    • Выберите версию Kubernetes и регион

      • Версия Kubernetes: Выберите последнюю стабильную версию для обеспечения безопасности и соответствия функциям.
  2. Выберите версию Kubernetes и регион
  3. Версия Kubernetes: Выберите последнюю стабильную версию для обеспечения безопасности и соответствия функционалу.
  4. Регион: Выберите регион, который поддерживает GPU Droplets — TOR1, NYC2 или ATL1 рекомендуются, если вы планируете развертывание AMD MI300X или других рабочих нагрузок на GPU.
  5. Далее укажите VPC и сервисные сети
  6. После того как вы назвали свой кластер и выбрали регион, следующим шагом будет настройка пула узлов — именно там будут работать ваши приложения.

Примечание: Мы рекомендуем создать два пула узлов.

Пул узлов #1: Для загрузок GPU

  • Тип GPU: В разделе Выберите емкость кластера перейдите на вкладку GPU.
  • Тип машины: Выберите GPU-дроплет, такой как AMD MI300X.
  • Минимум/Максимум узлов: Установите минимальное значение 0 (чтобы сэкономить затраты в нерабочее время) и более высокое максимальное значение в зависимости от потребностей нагрузки.

Пул узлов №2: Для общих/периферийных рабочих нагрузок

  • Тип капли: Выберите Стандартный, Выделенный ЦП или Оптимизированный по памяти в зависимости от потребностей вашего приложения.
  • Цель: Этот пул идеально подходит для запуска Prometheus, панелей управления (например, Grafana), KEDA, веб-API, а также компонентов kube-system.
  • Автоматическое масштабирование: Вы также можете по желанию включить автоматическое масштабирование.

Почему два пула узлов?

Изолирование вычислительных нагрузок с GPU и без GPU позволяет лучше контролировать масштабирование, снижает потери ресурсов и избегает конфликтов в расписании. Вспомогательные службы не нуждаются в дорогих узлах GPU.

Примечание: Для графических процессоров AMD плагин устройства графического процессора AMD включен по умолчанию.

Шаг 2 — Настройка пулов узлов

  • Пересмотрите ваши выборы.
  • Нажмите Создать кластер Kubernetes.

Примечание: для графических процессоров AMD плагин устройства GPU AMD включен по умолчанию. Включите экспортёр метрик устройства GPU AMD, затем вы сможете использовать API.

  -H "Content-Type: application/json"    -H "Authorization: Bearer  <your-api-token>"    -d '{"name": "<your_cluster_name.", "amd_gpu_device_metrics_exporter_plugin": {"enabled": true}}'    "https://api.linux-console.net/v2/kubernetes/clusters/<your-cluster-uuid>" 

Шаг 3 — Установите kube-prometheus-stack через Helm

  1. Prometheus будет отслеживать и собирать пользовательские метрики, необходимые KEDA.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm install prometheus prometheus-community/kube-prometheus-stack -n kube-system 

Шаг 3: Установите KEDA с помощью Helm KEDA будет оценивать метрики Prometheus и масштабировать ваши рабочие нагрузки соответственно.

helm repo add kedacore https://kedacore.github.io/charts helm repo update helm install keda kedacore/keda 

Шаг 4 — Развертывание нагрузки на GPU с пользовательскими метриками

Мы развернем пример приложения Go, которое предоставляет метрику шлюза Prometheus. Эта нагрузка требует GPU и будет масштабироваться в зависимости от значения метрики.

Создайте файл с именем resources.yaml и вставьте в него следующие манифесты:

apiVersion: v1 kind: ConfigMap metadata:  name: go-program data:  main.go: |    package main     import (        "log"        "net/http"        "strconv"        "github.com/prometheus/client_golang/prometheus"        "github.com/prometheus/client_golang/prometheus/promhttp"    )       var customGauge = prometheus.NewGauge(prometheus.GaugeOpts{        Name: "my_custom_gauge",        Help: "This is a custom gauge metric",    })     func init() {        prometheus.MustRegister(customGauge)    }       func handler(w http.ResponseWriter, r *http.Request) {        value := r.URL.Query().Get("value")        floatVal, err := strconv.ParseFloat(value, 64)        if err != nil {            http.Error(w, "Bad Request: invalid input", http.StatusBadRequest)            return       }        customGauge.Set(floatVal)        w.Write([]byte("Hello, from the handler!"))    }     func main() {        http.HandleFunc("/", handler)        http.Handle("/metrics", promhttp.Handler())        log.Fatal(http.ListenAndServe(":8080", nil))    } --- apiVersion: apps/v1 kind: Deployment metadata:  name: go-from-configmap spec:  replicas: 1  selector:    matchLabels:      app: go-from-configmap  template:    metadata:      labels:        app: go-from-configmap    spec:      nodeSelector:        doks.linux-console.net/gpu-brand: amd      tolerations:        - key: CriticalAddonsOnly          operator: Exists        - key: amd.com/gpu          operator: Exists      containers:        - name: go-runner          image: golang:1.24          command: ["/bin/sh", "-c"]          resources:            requests:              amd.com/gpu: "1"            limits:              amd.com/gpu: "1"          ports:            - containerPort: 8080          args:            - |              set -e                                                 cp /config/*.go /app/              cd /app              [ -f go.mod ] || go mod init temp              go mod tidy                                           go run .                                           volumeMounts:            - name: go-code              mountPath: /config            - name: app-dir              mountPath: /app      volumes:        - name: go-code          configMap:            name: go-program        - name: app-dir          emptyDir: {} --- apiVersion: v1 kind: Service metadata:  name: go-from-configmap  labels:    app: go-from-configmap spec:  selector:    app: go-from-configmap  ports:    - name: metrics      port: 8080      targetPort: 8080 --- apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata:  name: go-from-configmap  labels:    release: prometheus spec:  selector:    matchLabels:      app: go-from-configmap  endpoints:    - port: metrics      path: /metrics      interval: 30s  namespaceSelector:    matchNames:      - kube-system --- apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata:  name: go-from-configmap spec:  scaleTargetRef:    name: go-from-configmap  pollingInterval: 30  cooldownPeriod: 30  minReplicaCount: 1  maxReplicaCount: 8  triggers:    - type: prometheus      metadata:        serverAddress: http://prometheus-operated.kube-system.svc.cluster.local:9090        metricName: my_custom_gauge        threshold: '80'        query: sum(my_custom_gauge{}) / sum(kube_deployment_status_replicas{deployment="go-from-configmap"}) 

Примените ресурсы:

kubectl apply -f resources.yaml -n <your-namespace> 

Шаг 5 — Что вы только что развернули

ConfigMap

Мы создали ConfigMap, который хранит простой Go HTTP сервер в виде строки. Это приложение

  • HTTP-сервер на порту 8080.
  • Определяет метрику гейджи Prometheus: my_custom_gauge. Эта метрика представляет собой смоделированное значение нагрузки и будет основным двигателем для нашей логики автомасштабирования.
  • Представляет собой конечную точку /metrics, совместимую с извлечением данных Prometheus
  • Предлагает корневую конечную точку /, где пользователь может обновить метрику гейджи, вызвав /?value=123.

Примечание: Эта настройка предназначена только для демонстрационных целей и не предназначена для использования в производстве.

Развертывание

Мы определяем Deployment, который использует официальный образ golang:1.24. При запуске он:

  • Монтирует ConfigMap и динамически компилирует код сервера на Go.
  • Запускает программу, которая открывает HTTP-эндпойнты.
  • Запросы 1 AMD GPU через запросы ресурсов и ограничения (amd.com/gpu: 1)

Служба

  • Ресурс Service позволяет Prometheus получить доступ к нашему /metrics конечному пункту.
  • Он нацелен на поды, помеченные app: go-from-configmap
  • Открывает порт 8080.

ServiceMonitor

Чтобы сделать Prometheus осведомленным о нашей конечной точке распарсивания, мы определяем ServiceMonitor. Этот ресурс:

  • Сообщает Прометею собрать данные сервиса, соответствующего метке app: go-from-configmap
  • Настраивает путь для сборки как /metrics
  • Устанавливает интервал сборки на 30s

Теперь Prometheus будет постоянно собирать последние значения my_custom_gauge.

МасштабируемыйОбъект (KEDA)

Объект ScaledObject KEDA связывает все воедино. Он настраивает KEDA для того, чтобы:

  • Используйте Prometheus в качестве источника метрик
  • Скажи Кеде следить за метрикой my_custom_gauge, хранящейся в Prometheus.
  • И используйте следующий запрос для событий авто-масштабирования

Короче говоря, Кеда будет:

  • Каждые 30 секунд опрашивайте Прометея
  • Масштабируйте между 1 и 8 экземплярами развертывания go-from-configmap.
  • Охладитесь (уменьшите мощность) через 30 секунд, если нагрузка уменьшается.

Шаг 6 — Тестирование автомасштабирования GPU

Получите имя пода и выполните команду внутри него:

kubectl get pods -l app=go-from-configmap  kubectl exec -it <go-pod-name> -- bash 

Установите измерительный прибор на высокое значение (например, 160):

curl http://127.0.0.1:8080/?value=160 exit 

Следите за масштабированием подов:

kubectl get pods -w -l app=go-from-configmap 

KEDA оценит запрос:

160 (значение измерения)/1 (реплика)=160, что превышает пороговое значение 80
→ Активируется вторая реплика.

На этом этапе новый под должен находиться в состоянии ожидания, так как у нас недостаточно графических процессоров (GPU) на основе запрашиваемых ресурсов AMD GPU для этого развертывания. В облачном интерфейсе вы должны увидеть новое событие автоподстройки (новый узел) в пуле узлов AMD GPU. Дождитесь завершения загрузки нового GPU и проверьте под. Под должен был перейти из состояния ожидания в состояние работы.

Запрос непрерывно оценивается, и масштабирование останавливается или продолжается в зависимости от поведения метрики.

Часто задаваемые вопросы

1. Могу ли я использовать KEDA для автоматического масштабирования любых типов нагрузок на GPU в DOKS?

Да. KEDA является независимой от типа нагрузки, если вы можете предоставить метрику (например, использование GPU, длину очереди или пользовательские метрики приложения), которую может собирать Prometheus. Для рабочих нагрузок на GPU AMD убедитесь, что плагин устройства AMD и экспортер метрик включены (по умолчанию на узлах GPU DOKS).

2. Какие регионы DigitalOcean поддерживают узлы AMD GPU для DOKS?

На момент написания этой статьи, узлы GPU AMD MI300X доступны в некоторых регионах, таких как TOR1, NYC2 и ATL1. Всегда проверяйте документацию DigitalOcean для получения самой последней информации о поддерживаемых регионах и типах GPU.

3. Чем KEDA отличается от встроенного Horizontal Pod Autoscaler (HPA) в Kubernetes?

KEDA расширяет автоматическое масштабирование Kubernetes, позволяя вам масштабировать рабочие нагрузки на основе внешних или пользовательских метрик (таких как запросы Prometheus, длина очереди или облачные события), а не только на основе ЦП или памяти. Это особенно полезно для рабочих нагрузок с графическими процессорами, где модели использования могут не совпадать с использованием ЦП.

4. Что произойдет, если в пуле узлов недостаточно доступных графических процессоров?

Если ваша логика масштабирования запускает больше подов, чем доступно GPU, новые поды останутся в состоянии Ожидание, пока не будут выделены дополнительные узлы GPU. DOKS автоматически масштабирует пул узлов GPU (если включено автомасштабирование) для удовлетворения возросшего спроса, с учетом ваших настроенных ограничений.

5. Могу ли я использовать этот подход для других типов ускорителей (например, NVIDIA GPU) или на других платформах Kubernetes?

Да. Шаблон KEDA + Prometheus не зависит от платформы и поставщика. Вы можете адаптировать этот подход для процессоров NVIDIA или других ускорителей, используя соответствующий плагин устройства и экспортёр метрик для вашего оборудования и дистрибутива Kubernetes.

Заключение

Этот гид показал, как построить автомационный рабочий процесс GPU на DOKS с использованием KEDA и Prometheus, все с использованием встроенных конструкций Kubernetes и инструментов с открытым исходным кодом.

Эта архитектура позволяет вашим рабочим нагрузкам:

  • Автоматически масштабироваться в ответ на реальные метрики — не только CPU
  • Оптимизируйте расходы на GPU, динамически управляя репликами.
  • Легко адаптироваться к таким случаям использования, как инференс машинного обучения, обработка видео или анализ в реальном времени.

Объединив масштабирование, основанное на событиях, с пользовательской видимостью, команды могут эффективно управлять ресурсами GPU и обеспечивать высокопроизводительные вычислительные нагрузки с минимальным вмешательством человека.

Дополнительная литература и ссылки

AMD GPU Дроплеты: MI300X

AMD101: Рабочие нагрузки на базе AMD GPU

DigitalOcean App Platform против DOKS против Дроплетов: Окончательное сравнение для команд разработчиков

Как установить стек мониторинга Prometheus для кластера DOKS

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *