GPU Operator и NVIDIA-драйверы

Раздел по ML-сценариям уточняется. Отдельные шаги и примеры могут быть дополнены. При возникновении вопросов обратитесь к команде платформы «Штурвал».

Инструкция описывает установку GPU Operator, драйверов NVIDIA, среды выполнения nvidia и Fabric Manager на узлах с NVSwitch. Здесь также описано, как проверить применение конфигурации, добавить GPU-узел и подготовить его к обслуживанию.

Подробнее про устройство NCI: Конфигурация узлов.


Перед началом

Клиентский кластер уже установлен. Проверьте:

  • в кластере есть GPU-узлы с картой NVIDIA;
  • лицензия поддерживает Enterprise ML: Виды лицензии — лицензия потребуется для доступа к RPM-репозиторию shturval_rpm_nvidia;
  • на всех GPU-узлах установлена одна версия ядра — иначе указанная в NCI версия пакета kernel-lt-devel подойдёт не всем узлам.

Для CLI-пути нужны kubectl, curl, gzip, grep, sort.

  1. Откройте клиентский кластер.
  2. Администрирование → Управление узлами → страница просмотра узла → блок Описание: версия ядра. Сохраните её — это значение для пакетов kernel-lt-devel / kernel-lt-headers.
  3. На всех GPU-узлах версия должна совпадать. Если версии разные, сначала выровняйте ядро.
export KUBECONFIG_CLIENT=<путь-к-kubeconfig-клиентского-кластера>

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get nodes \
  -o custom-columns='NAME:.metadata.name,KERNEL:.status.nodeInfo.kernelVersion'

Сопоставьте имена узлов с GPU-группой и убедитесь, что в столбце KERNEL у всех GPU-узлов указана одна версия.

Как перенести версию ядра в NCI:

Откуда Пример Что указать в NCI Где применяется
Блок Описание на странице узла или status.nodeInfo.kernelVersion 5.15.178-1.el8.x86_64 5.15.178-1.el8 — пакетная версия без суффикса архитектуры. Не 5.15 и не latest Шаг 2. Установите NVIDIA-компоненты на узлы, поле version у пакетов kernel-lt-devel и kernel-lt-headers в NCI nvidia-drivers

Загрузите патчи NVIDIA в зеркало

Этот шаг выполняется на хосте зеркала. Без него кластер не скачает чарт gpu-operator и RPM драйверов.

sudo -i
cd /opt/mirror

Примените архивы из комплекта поставки в этом порядке:

Компонент Что добавляет в зеркало
NVIDIA drivers RPM драйверов NVIDIA и nvidia-container-toolkit
gpu-operator Helm-чарт GPU Operator

Для каждого архива:

rm -rf shturval-patch && mkdir shturval-patch
wget <URL_архива_из_поставки> -O shturval-patch/<имя-файла>.tgz
./stm patch apply
rm -rf shturval-patch
Обратите внимание! URL архивов берите только из комплекта поставки.

Подготовьте параметры

Параметр Обязателен Назначение Откуда взять Где используется
SHTURVAL_LICENSE Да токен лицензии для RPM-репозитория shturval_rpm_nvidia токен лицензии Штурвала Шаг 2, NCI nvidia-drivers, URL репозитория
<версия-ядра> Да версия пакетов kernel-lt-devel и kernel-lt-headers страница узла, блок Описание, или status.nodeInfo.kernelVersion Шаг 2, NCI nvidia-drivers
NVIDIA_DRIVER_VERSION Да версия пакетов драйвера, которая есть в shturval_rpm_nvidia. Доступные версии: 575.57.08 и 580.82.07 список версий в зеркале — команда ниже Шаг 2, NCI nvidia-drivers

Список версий драйвера в зеркале:

NVIDIA_REPO_URL="$(kubectl --kubeconfig "${KUBECONFIG_CLIENT}" \
  get shturvalrepoconfigs shturval \
  -o jsonpath='{.spec.url}' | sed 's#shturval_helm#shturval_rpm_nvidia#' | sed 's#/$##')"

curl -fsSLk -u "user:${SHTURVAL_LICENSE}" "${NVIDIA_REPO_URL}/$(curl -fsSLk \
  -u "user:${SHTURVAL_LICENSE}" "${NVIDIA_REPO_URL}/repodata/repomd.xml" \
  | grep -oP '(?<=href=")[^"]*primary\.xml\.gz' | head -n 1)" \
| gzip -dc \
| grep -oP 'nvidia-driver-\K[0-9]+\.[0-9]+\.[0-9]+(?=-1\.red80\.x86_64\.rpm)' \
| sort -Vu

Шаг 1. Установите GPU Operator

В кластере должны быть GPU-узлы: GPU Operator обнаружит карту NVIDIA в PCI и проставит лейбл nvidia.com/gpu.present=true. NCI драйверов и runtime привязаны к этому лейблу: если его нет, у nvidia-drivers будет APPLIED 0/0.

Ставьте GPU Operator до NCI драйверов.

  1. Сервисы и репозитории → Доступные чарты, репозиторий shturval.
  2. Найдите чарт gpu-operator и нажмите Установить.
  3. Название экземпляра: gpu-operator. Неймспейс: gpu-operator (создайте, если его нет). Режим: Авто и нажмите Сохранить.
  4. Дождитесь установки gpu-operator.
  5. Проверьте: Сервисы и репозитории → Установленные сервисы → gpu-operator → Управлять: режим Авто, состояние Healthy.
  6. Администрирование → Управление узлами: у узлов с картой NVIDIA есть лейбл nvidia.com/gpu.present=true. Если лейбла нет, см. устранение неполадок.
kubectl --kubeconfig "${KUBECONFIG_CLIENT}" apply -f - <<'EOF'
apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServiceConfig
metadata:
  annotations:
    shturval.tech/description: NVIDIA GPU Operator creates/configures/manages GPUs atop Kubernetes
    shturval.tech/name: gpu-operator
  name: gpu-operator
spec:
  chart: gpu-operator
  mode: auto
  namespace: gpu-operator
  reponame: shturval
  version: 2.15.0
EOF

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get ssc gpu-operator
kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get pods -n gpu-operator
kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get nodes -L nvidia.com/gpu.present

Шаг 2. Установите NVIDIA-компоненты на узлы

Установите NVIDIA-компоненты на GPU-узлы с помощью NCI.

Создайте три NCI и одно правило NFD. CRD NodeFeatureRule (группа nfd.k8s-sigs.io) создаётся вместе с GPU Operator — без него правило применить нельзя.

Объект Тип Приоритет Разделы в GUI Селектор Что делает
nvidia-drivers NCI 90 Репозитории пакетов, Параметры загрузчика ядра (grub), Модули ядра, Пакеты для установки nvidia.com/gpu.present=true RPM-репозиторий NVIDIA, blacklist nouveau, пакеты ядра и драйвера, toolkit
nvidia-nvswitch NodeFeatureRule — — PCI NVSwitch (vendor 10de, device 1ac2 / 1af1 / 22a3) NFD из GPU Operator ставит лейбл nvidia.com/nvswitch.present=true
nvidia-fabricmanager NCI 95 Systemd-юниты nvidia.com/nvswitch.present=true включает systemd-юнит nvidia-fabricmanager. На GPU без NVSwitch NCI не применяется
nvidia-runtime-minimal NCI 100 Container Runtime, блок Плагины nvidia.com/gpu.present=true runtime nvidia в containerd

В URL репозитория драйверов токен лицензии входит в authority: https://user:<токен>@<зеркало>/repository/shturval_rpm_nvidia. Версии kernel-lt-devel / kernel-lt-headers должны совпасть с ядром узлов. В манифесте ниже пример 5.15.178-1.el8 — подставьте версию со своих узлов. Версия nvidia-container-toolkit — 1.18.0~rc.4.

  1. Откройте клиентский кластер.
  2. В манифесте ниже подставьте свои значения <токен-лицензии>, <зеркало>, версию ядра и <NVIDIA_DRIVER_VERSION>.
  3. Загрузите все объекты одним файлом: импорт манифестов → вставьте YAML → Проверить → Сохранить.
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: nvidia-drivers
spec:
  priority: 90
  repositories:
  - name: nvidia-repo
    description: "Shturval nvidia drivers repository"
    address: "https://user:<токен-лицензии>@<зеркало>/repository/shturval_rpm_nvidia"
    state: present
  kernelarguments:
  - param: "modprobe.blacklist"
    value: "nouveau"
    exist: true
  kernelmodules:
  - autoload: false
    blacklist: true
    name: nouveau
  packages:
  - name: gcc
    setlock: false
    state: present
  - name: make
    setlock: false
    state: present
  - name: kernel-lt-devel
    setlock: false
    state: present
    version: "5.15.178-1.el8"
  - name: kernel-lt-headers
    setlock: false
    state: present
    version: "5.15.178-1.el8"
  - name: dkms-nvidia
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-driver
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-driver-cuda
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-modprobe
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-fabric-manager
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-container-toolkit
    setlock: false
    state: present
    version: 1.18.0~rc.4
  nodeconfigselector:
    nvidia.com/gpu.present: "true"
---
apiVersion: nfd.k8s-sigs.io/v1alpha1
kind: NodeFeatureRule
metadata:
  name: nvidia-nvswitch
spec:
  rules:
    - name: nvswitch-present
      labels:
        nvidia.com/nvswitch.present: "true"
      matchFeatures:
        - feature: pci.device
          matchExpressions:
            vendor:
              op: In
              value: ["10de"]
            device:
              op: In
              value:
                - "1ac2"  # V100 NVSwitch
                - "1af1"  # A100 NVSwitch
                - "22a3"  # H100/H200 NVSwitch
---
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: nvidia-fabricmanager
spec:
  priority: 95
  systemdunits:
    - active: true
      enabled: true
      name: nvidia-fabricmanager
  nodeconfigselector:
    nvidia.com/nvswitch.present: "true"
---
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: nvidia-runtime-minimal
spec:
  priority: 100
  runtimecfg:
    configSections:
      - path: 'plugins."io.containerd.grpc.v1.cri".containerd'
        params:
          - key: default_runtime_name
            value: "nvidia"
      - path: 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia'
        params:
          - key: privileged_without_host_devices
            value: false
          - key: runtime_type
            value: "io.containerd.runc.v2"
      - path: 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options'
        params:
          - key: BinaryName
            value: "/usr/bin/nvidia-container-runtime"
          - key: SystemdCgroup
            value: true
  nodeconfigselector:
    nvidia.com/gpu.present: "true"

Если NCI не применяются, см. устранение неполадок.

Подставьте <токен-лицензии>, <зеркало>, версию ядра (в примере 5.15.178-1.el8) и <NVIDIA_DRIVER_VERSION> и выполните:

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" apply -f - <<'EOF'
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: nvidia-drivers
spec:
  priority: 90
  repositories:
  - name: nvidia-repo
    description: "Shturval nvidia drivers repository"
    address: "https://user:<токен-лицензии>@<зеркало>/repository/shturval_rpm_nvidia"
    state: present
  kernelarguments:
  - param: "modprobe.blacklist"
    value: "nouveau"
    exist: true
  kernelmodules:
  - autoload: false
    blacklist: true
    name: nouveau
  packages:
  - name: gcc
    setlock: false
    state: present
  - name: make
    setlock: false
    state: present
  - name: kernel-lt-devel
    setlock: false
    state: present
    version: "5.15.178-1.el8"
  - name: kernel-lt-headers
    setlock: false
    state: present
    version: "5.15.178-1.el8"
  - name: dkms-nvidia
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-driver
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-driver-cuda
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-modprobe
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-fabric-manager
    setlock: false
    state: present
    version: "<NVIDIA_DRIVER_VERSION>"
  - name: nvidia-container-toolkit
    setlock: false
    state: present
    version: 1.18.0~rc.4
  nodeconfigselector:
    nvidia.com/gpu.present: "true"
---
apiVersion: nfd.k8s-sigs.io/v1alpha1
kind: NodeFeatureRule
metadata:
  name: nvidia-nvswitch
spec:
  rules:
    - name: nvswitch-present
      labels:
        nvidia.com/nvswitch.present: "true"
      matchFeatures:
        - feature: pci.device
          matchExpressions:
            vendor:
              op: In
              value: ["10de"]
            device:
              op: In
              value:
                - "1ac2"  # V100 NVSwitch
                - "1af1"  # A100 NVSwitch
                - "22a3"  # H100/H200 NVSwitch
---
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: nvidia-fabricmanager
spec:
  priority: 95
  systemdunits:
    - active: true
      enabled: true
      name: nvidia-fabricmanager
  nodeconfigselector:
    nvidia.com/nvswitch.present: "true"
---
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: nvidia-runtime-minimal
spec:
  priority: 100
  runtimecfg:
    configSections:
      - path: 'plugins."io.containerd.grpc.v1.cri".containerd'
        params:
          - key: default_runtime_name
            value: "nvidia"
      - path: 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia'
        params:
          - key: privileged_without_host_devices
            value: false
          - key: runtime_type
            value: "io.containerd.runc.v2"
      - path: 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options'
        params:
          - key: BinaryName
            value: "/usr/bin/nvidia-container-runtime"
          - key: SystemdCgroup
            value: true
  nodeconfigselector:
    nvidia.com/gpu.present: "true"
EOF

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get nci
kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get nodes -L nvidia.com/gpu.present

Как узлы получают драйверы и среду выполнения

После установки GPU Operator на узлах работает NFD: он смотрит PCI и, если находит карту NVIDIA (vendor 10de), на узел добавляется лейбл nvidia.com/gpu.present=true.

NCI применяются оператором shturval-node-config только к узлам, которые совпали с селектором:

Ресурс Селектор Что делает
NCI nvidia-drivers nvidia.com/gpu.present: "true" RPM-репозиторий NVIDIA, blacklist nouveau, пакеты ядра и драйвера, toolkit
NodeFeatureRule nvidia-nvswitch PCI NVSwitch (10de / 1ac2, 1af1, 22a3) лейбл nvidia.com/nvswitch.present=true
NCI nvidia-fabricmanager nvidia.com/nvswitch.present: "true" включает systemd-юнит nvidia-fabricmanager
NCI nvidia-runtime-minimal nvidia.com/gpu.present: "true" среда выполнения nvidia в containerd

Версии kernel-lt-devel и kernel-lt-headers в NCI драйверов должны совпадать с ядром всех узлов, на которые применяется NCI. Разные версии ядра на GPU-узлах — частая причина сбоя пакетов.


Обычный GPU и NVSwitch

Большинству GPU-узлов достаточно драйверов и среды выполнения. Fabric Manager нужен только там, где есть NVSwitch (несколько GPU на узле связаны через коммутатор NVIDIA).

  • Нет NVSwitch — NFD не ставит nvidia.com/nvswitch.present. NCI nvidia-fabricmanager на такой узел не применяется и не уходит в failed.
  • Есть NVSwitch — появляется лейбл, NCI включает nvidia-fabricmanager.

Не включайте Fabric Manager на все GPU-узлы: на машине без NVSwitch не стартует systemd-юнит.


Проверка после установки GPU Operator

Если лейбла GPU нет, сначала проверьте состояние подов и события в неймспейсе gpu-operator.

Дополнительно: Устранение неполадок.

Если NCI применился, но GPU-нагрузка не запускается, проверьте события пода:

kubectl describe pod -n <неймспейс> <имя-pod>
kubectl get events -n <неймспейс> --sort-by=.lastTimestamp

Notebook с GPU: Устранение неполадок.


Добавить GPU-узел в уже установленный кластер

В платформу узлы с GPU можно добавить только через провайдер Shturval v2: физические хосты, не ВМ основного провайдера виртуализации или облака. NCI и GPU Operator пересоздавать не нужно. Новый узел должен попасть под те же селекторы.

  1. Добавьте хост с GPU в Worker-группу Shturval v2: добавление хостов. Если клиентский кластер развёрнут на другом провайдере (vSphere, oVirt, OpenStack и т.д.), сначала создайте отдельную Worker-группу Shturval v2 — Гибридные кластеры.
  2. Ядро ОС на новом узле должно совпадать с версией остальных GPU-узлов.
  3. Дождитесь, пока GPU Operator / NFD увидит PCI NVIDIA и появится лейбл nvidia.com/gpu.present=true.
  4. Проверьте, что NCI драйверов и среды выполнения применились к этому узлу.
  5. Если на узле есть NVSwitch, отдельно дождитесь лейбла nvidia.com/nvswitch.present=true и применения nvidia-fabricmanager.

Если лейбл не появился, проверьте состояние NFD и доступность устройства NVIDIA на узле.


Подготовка узла к очистке NVIDIA

Если узел нужно полностью перенастроить, сначала запретите планирование новых подов с помощью Cordon, затем вытесните рабочие нагрузки с помощью Drain. Удалите пакеты NVIDIA и восстановите конфигурацию containerd по процедуре вашей поставки.

Обратите внимание! Не очищайте рабочий узел: удаление containerd или повреждение его конфигурации может перевести узел в состояние NotReady до завершения восстановления.