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 - сейчас нормальный момент для перехода. Напишите, обсудим конкретику.