Как построить масштабируемый кластер Kubernetes с поддержкой GPU — пошагово, без теории

Ты хочешь запустить модели машинного обучения, обрабатывать видео в реальном времени или тренировать нейросети — и тебе нужен кластер Kubernetes, который не только работает с GPU, но и не ломается при росте нагрузки. Ты не хочешь тратить месяцы на эксперименты, чтобы понять, почему твои поды не запускаются, или почему GPU-узлы греются до 90°C и падают. Ты хочешь чёткий путь: что взять, как настроить, где не наделать ошибок — и чтобы через неделю всё работало, а не через месяц с костылями.

Я не буду рассказывать, что такое Kubernetes или что такое GPU-плагин. Я расскажу, как собрать кластер, который выдержит рост от 2 до 50 узлов с GPU, и как не уйти в долгую поддержку из-за неправильных решений на старте.

Что тебе реально нужно на старте

Масштабируемый кластер с GPU — это не просто «запусти Helm-чарт и всё». Это:

  • Узлы с GPU, которые Kubernetes умеет видеть и распределять
  • Планировщик, который не ставит CPU-поды на GPU-узлы
  • Мониторинг, чтобы не терять GPU из-за перегрева или нехватки памяти
  • Автоматическое масштабирование: добавлять узлы при нагрузке, убирать — когда не надо
  • Сетевая идентичность: чтобы поды могли общаться между собой без костылей

Если ты начинаешь с одного узла — ты ещё не в масштабируемом кластере. Ты в эксперименте. Масштабируемость — это когда ты можешь добавить 5 новых узлов с 8 GPU каждый, и кластер не сломается, не перестанет распределять задачи и не начнёт падать от нагрузки.

Выбор железа: не все GPU одинаковы

Ты не можешь просто взять любую карту и подключить её к серверу. Kubernetes требует поддержки драйверов, а драйверы требуют совместимости. Вот что реально работает:

Параметр NVIDIA A100 NVIDIA H100 NVIDIA RTX 4090 NVIDIA T4
Поддержка в Kubernetes Отличная Отличная Плохая (драйверы не стабильны) Отличная
Память (ГБ) 40–80 80 24 16
Поддержка MIG Да Да Нет Нет
Энергопотребление (Вт) 250–400 300–700 450 70
Цена за штуку (USD) 10 000–15 000 25 000+ 1 500–2 000 1 000–1 500
Рекомендация Продакшн, большие модели Продакшн, крупные инференсы Не использовать в продакшне Малый объём, инференс

RTX 4090 — это игровая карта. Она дешёвая, но у неё нет драйверов, которые стабильно работают в Linux-серверах. NVIDIA не сертифицирует их для серверных задач. Ты можешь попробовать — и столкнёшься с тем, что через неделю карта перестаёт отвечать, а кластер начинает падать. Не делай это в продакшне.

Выбирай A100 или H100, если у тебя большие модели и ты готов платить. Выбирай T4, если тебе нужно дешёвое решение для инференса — например, для API, который отвечает на запросы от пользователей. T4 — это «золотая середина»: дешевле A100, но стабильнее RTX.

Как настроить Kubernetes, чтобы он увидел GPU

Кubernetes по умолчанию не знает, что у тебя есть GPU. Ты должен явно сказать ему: «Вот тут карта, вот её драйверы, вот как её использовать».

  1. Установи драйверы NVIDIA на каждый узел с GPU. Используй nvidia-docker и драйверы из официального репозитория NVIDIA — не из Ubuntu-репозиториев. Там старые версии, и они не работают с новыми GPU.
  2. Установи NVIDIA Device Plugin как DaemonSet. Это то, что говорит Kubernetes: «У меня тут есть 4 GPU, вот их ID, вот память».
  3. Убедись, что на узлах установлен nvidia-smi и он возвращает список карт. Если он не работает — кластер не увидит GPU, даже если ты всё настроил.
  4. Добавь в спецификацию пода запросы на GPU:
    resources:
      limits:
        nvidia.com/gpu: 1
      requests:
        nvidia.com/gpu: 1
  5. Проверь, что под запустился на узле с GPU: kubectl describe pod <имя-пода> — ищи в событиях «Scheduled» с указанием узла с GPU.

Если ты пропустишь пункт 2 — всё будет казаться нормальным, но поды просто не будут запускаться. Кластер будет ждать, пока найдёт узел с GPU, а их не будет — потому что драйверы не установлены. Это самая частая ошибка на старте.

Масштабирование: как добавлять узлы автоматически

Ты не можешь вручную добавлять узлы каждый раз, когда нагрузка растёт. Нужен автоматический масштабинг кластера — Cluster Autoscaler.

Но тут важный нюанс: Cluster Autoscaler не знает, что у тебя есть GPU-узлы. Он будет масштабировать только CPU-узлы, если ты не скажешь ему обратное.

Решение:

  • Создай отдельную группу узлов (node pool) только для GPU. Например, в AWS — это отдельный Auto Scaling Group с инстансами типа g5.xlarge или p3.2xlarge.
  • Настрой Cluster Autoscaler, чтобы он знал, что эта группа существует. В Kubernetes это делается через аннотации в конфигурации:
    cluster-autoscaler.kubernetes.io/scale-down-enabled: "true"
    cluster-autoscaler.kubernetes.io/scale-down-unneeded-time: "5m"
  • В спецификации подов используй nodeSelector или nodeAffinity, чтобы поды с GPU запускались только на GPU-узлах:
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: gpu-type
              operator: In
              values:
              - nvidia-a100

Так ты гарантируешь, что CPU-поды не будут мешать GPU-подам, а масштабирование будет работать только на нужных узлах.

Мониторинг: не жди, пока GPU сгорит

GPU — это не CPU. Они не просто «заняты» — они перегреваются, исчерпывают память, зависают. Без мониторинга ты можешь потерять целый узел за час.

Что нужно мониторить:

  • Температура GPU — выше 85°C — это тревога
  • Использование памяти GPU — если 100% и не освобождается — утечка
  • Загрузка GPU — если 100% долго, но поды не завершаются — зависание
  • Количество запущенных подов на узле — больше 4–6 на A100? Ты перегружаешь

Используй Prometheus + Grafana + NVIDIA GPU Monitoring Tools. У NVIDIA есть экспортер, который выдаёт метрики в формате Prometheus. Установи его как DaemonSet на GPU-узлы — и ты получишь метрики по температуре, памяти, загрузке в реальном времени.

Создай алерты:

  • Температура > 85°C — уведомить в Slack
  • Память GPU > 95% > 10 минут — перезапустить под
  • GPU не отвечает > 2 минуты — перезагрузить узел

Это не «хорошо иметь» — это обязательное условие для продакшена. Без этого ты будешь тратить дни на поиск, почему «вчера всё работало, а сегодня — нет».

Частые ошибки — и как их избежать

  1. Нет разделения узлов. Ты запускаешь CPU-поды на GPU-узлах — они занимают память, CPU, сеть. GPU-поды не могут запуститься. Решение: всегда используй nodeSelector и taints/tolerations.
  2. Неправильные драйверы. Установил драйверы из Ubuntu — и они не совместимы с CUDA. Решение: только драйверы с сайта NVIDIA, версии, совместимые с твоей CUDA-версией.
  3. Нет мониторинга. Под упал, но ты не знал — потому что не смотрел температуру. Решение: поставь Prometheus + NVIDIA exporter сразу на старте.
  4. Нет резервирования памяти. Ты запускаешь 8 подов по 10 ГБ памяти на GPU с 40 ГБ — и у тебя остаётся 0. Но CUDA требует резервирования под систему. Оставляй минимум 10–15% свободной памяти. Иначе драйвер начнёт падать.
  5. Нет масштабирования. Ты вручную добавляешь узлы — и забываешь убирать. Решение: настрой Cluster Autoscaler с таймаутом на удаление неиспользуемых узлов.

Что выбрать — в зависимости от ситуации

Ты не одинаков. Твоя задача — тоже не одинакова. Вот как выбрать подход:

  • Ты тестируешь модель на одном узле — возьми T4 на AWS g4dn.xlarge. Дешево, стабильно, можно убрать через час. Не трать деньги на A100.
  • Ты запускаешь инференс для 1000 пользователей в день — T4 или A100 (если модель большая). Используй HPA (Horizontal Pod Autoscaler) + Cluster Autoscaler. Ставь 2–3 узла, чтобы не было single point of failure.
  • Ты тренируешь LLM на 100 ГБ данных — только A100 или H100. Минимум 4 узла. Используй MIG (Multi-Instance GPU), чтобы разбить один A100 на 7 частей — и запускать несколько задач параллельно. Это сэкономит тебе 60% стоимости.
  • Ты в стартапе и не можешь позволить себе $20 000 за узел — используй облако с GPU (AWS, GCP, Lambda Labs). Не покупай железо. Потому что через 6 месяцев ты можешь перейти на другую модель, и твоё железо станет мусором.

Как лучше сделать — практические рекомендации

Вот что я делаю на практике, когда строю кластер с GPU:

  1. Использую Kops или EKSctl — не kubeadm. Они автоматически настраивают сети, IAM, узлы. kubeadm — для экспериментов, не для продакшена.
  2. Всегда создаю две группы узлов: CPU и GPU. GPU-узлы имеют taint gpu=true:NoSchedule. Поды с GPU должны иметь toleration, чтобы их можно было запустить.
  3. Устанавливаю NVIDIA Device Plugin и NVIDIA GPU Monitoring Exporter как DaemonSet на GPU-узлы — и только на них.
  4. Настраиваю Cluster Autoscaler с явным указанием групп узлов и минимальной/максимальной ёмкости.
  5. Создаю Grafana-дашборд с метриками: температура, память, загрузка, количество подов. Показываю его команде — чтобы никто не спрашивал «почему упало?».
  6. Все поды с GPU имеют лимиты памяти и CPU — не больше 10% от доступного на узле. Это предотвращает перегрузку.
  7. Пишу документацию: «Как запустить под с GPU». Даже если ты один — через 3 месяца ты забудешь, как это делается.

Итог: что делать прямо сейчас

Если ты читаешь это — ты уже на шаг вперёд. Теперь сделай это:

  1. Выбери тип GPU: T4 — если инференс, A100 — если тренировка.
  2. Создай кластер через EKSctl или Kops — не вручную.
  3. Установи NVIDIA Device Plugin и NVIDIA GPU Exporter.
  4. Создай отдельную группу узлов для GPU и настрой Cluster Autoscaler.
  5. Сделай простой под с запросом на 1 GPU — и запусти его. Убедись, что он запустился на GPU-узле.
  6. Настрой алерты по температуре и памяти.
  7. Запиши, как запускать под — и положи это в README.

Через 2 дня у тебя будет рабочий кластер. Через неделю — масштабируемый. Через месяц — ты сможешь добавить 10 узлов и не бояться, что всё сломается.

Не ищи «идеальное решение». Ищи «работающее решение, которое можно масштабировать». Остальное придет с опытом.

Информация в этой статье носит ознакомительный характер. Выбор оборудования, настройка кластера и управление ресурсами требуют понимания специфики твоей задачи. Перед внедрением в продакшен проконсультируйся с инженером, специализирующимся на Kubernetes и GPU-инфраструктуре.

Dfncfg.ru