ADG Оставить заявку
Блог DevOps 5 мин чтения

Kubernetes 1.32: DRA стабилен, смотрим что это меняет для GPU-нод

Kubernetes 1.32 вышел с GA-статусом DRA и beta 2 для sidecar-контейнеров. Проверяем первый реальный сценарий: GPU-ноды ML-команды без ручного патча device-plugin.

Контекст момента

Kubernetes 1.32 GA: Dynamic Resource Allocation стабилен, sidecar-контейнеры перешли в beta 2

Kubernetes 1.32 вышел в декабре, и по нему мы добрались до реального теста только сейчас - когда появился повод. У клиента на managed-сопровождении есть кластер с GPU-нодами под нужды ML-команды: дообучение моделей, векторизация, периодические batch-задачи. Раньше GPU торчали через NVIDIA device plugin, который требовал ручного патчинга при нескольких версиях драйверов на разных нодах. DRA (Dynamic Resource Allocation) обещал это упростить - и в 1.32 он наконец получил статус GA.

Проверили. Делимся наблюдениями.

Что такое DRA и зачем оно ML-команде

Классический подход к GPU в Kubernetes - nvidia.com/gpu: 1 в requests/limits. Device plugin транслирует это в конкретное устройство на ноде. Схема рабочая, но жёсткая: нельзя запросить GPU с конкретными свойствами (объём памяти, тип, версия драйвера), нельзя легко шарить устройство между контейнерами в поде без хаков.

DRA переворачивает эту логику. Вместо limits - отдельный ресурс ResourceClaim, в котором описываются свойства нужного устройства. Планировщик и драйвер договариваются, какое конкретное устройство удовлетворяет запросу, и только потом под получает ноду. Это не теория - начиная с NVIDIA Driver 550.x и соответствующей версии NVIDIA GPU Operator, DRA-режим поддерживается нативно.

У клиента ситуация была такая: три ноды с A100, две ноды с L40S, и на каждой группе нод - разные версии драйвера из-за поэтапного обновления. Device plugin в такой конфигурации требовал отдельного daemonset на каждую группу нод с nodeSelector-ами, кастомных ресурсных имён и ряда патчей, чтобы один под случайно не улетел на ноду с несовместимым драйвером. Не катастрофа, но муторно - особенно когда ML-команда хочет добавить ещё один тип ноды.

Как переходили

Переход не одноразовый флаг включить. Несколько шагов:

  • Включили feature gate DynamicResourceAllocation. В 1.32 это GA, но gate всё равно нужно явно разрешить на API server и scheduler - по умолчанию выключен для кластеров, обновившихся с более старых версий.
  • Обновили GPU Operator до версии с DRA-поддержкой. Оператор разворачивает ResourceDriver - компонент, который регистрирует доступные GPU как ResourceSlice-объекты. Это замена device plugin; оба механизма можно держать параллельно на период миграции.
  • Написали ResourceClaimTemplate для разных профилей нагрузки: один для задач, которым нужен GPU с памятью не менее 40 GiB, другой - без жёсткого требования по памяти для лёгких inference-задач.

Миграция нод шла поочерёдно: сначала L40S (там драйвер был новее), потом A100. Пока нода работает в DRA-режиме, device plugin на ней отключается - они не конфликтуют, но дублировать смысла нет.

Что реально изменилось

Главное - исчезли ручные nodeSelector-ы на драйверную версию. Раньше в деплойменте ML-задачи приходилось явно указывать, на какую группу нод она может попасть - иначе планировщик мог положить под на несовместимую ноду. Сейчас ResourceClaim описывает требование к устройству, а ResourceDriver от NVIDIA знает, какие устройства на какой ноде с каким драйвером. Планировщик сам разберётся.

Видимость устройств улучшилась. kubectl get resourceslices показывает конкретные GPU с атрибутами - память, тип, версия драйвера, статус. Раньше эту информацию можно было получить только залезши на ноду и запросив device plugin напрямую или через DCGM.

Один момент, который поначалу сбил. В 1.32 DRA не поддерживает structured parameters через все возможные комбинации CEL-выражений - часть сложных фильтров по атрибутам устройства работает, часть даёт ошибку на этапе admission. Мы на это наткнулись, когда ML-команда попробовала написать запрос типа «GPU с CUDA Compute Capability >= 8.0». Пришлось упростить до простой проверки по типу устройства - A100/L40S как отдельные named selectors. Не катастрофа, но документацию по CEL-выражениям в DRA стоит читать внимательно.

Sidecar-контейнеры: beta 2

Отдельно отметим sidecar-контейнеры - они перешли в beta 2 в 1.32. Для GPU-нод прямой связи нет, но ML-пайплайны часто используют sidecar для сбора метрик (DCGM exporter, например) или inject-а конфигурации. В beta 2 исправили несколько граничных случаев с порядком завершения контейнеров: sidecar теперь корректно дожидается завершения основного контейнера перед своим exitом. Раньше при завершении batch-джобы иногда были гонки, из-за которых DCGM exporter успевал упасть раньше, чем метрики дописывались. Это побочная, но приятная фиксация.

Итог на сейчас

DRA в 1.32 - рабочий инструмент, не экспериментальный. Для ML-кластеров с несколькими типами GPU это реальное упрощение операционной модели: меньше ручных nodeSelector-ов, лучше видимость, понятная модель запроса ресурсов. Ограничения CEL-выражений есть, их надо учитывать при проектировании ResourceClaimTemplate-ов.

Полный переход кластера клиента занял около двух дней в рабочем режиме - без остановки нод и без пересоздания существующих ML-задач. Половина времени ушла на тестирование и итерацию по ResourceClaimTemplate-ам, вторая половина - на обновление GPU Operator и проверку что старые задачи работают корректно.

Если у вас кластер с GPU под managed-сопровождением и вы присматривались к DRA - сейчас нормальный момент для перехода. Напишите, обсудим конкретику.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.