Установка через Helm
Начиная с версии 2.2.0, GPUStack можно развертывать в Kubernetes с помощью внутрикластерного API-шлюза Higress с использованием официального чарта Helm.
Примечание
Развертывание GPUStack в Kubernetes с помощью Higress в настоящее время считается экспериментальным. Прежде чем продолжить, ознакомьтесь с ограничениями.
Предварительные условия
| Компонент | Версия |
|---|---|
| Helm | >= v3.18.4 |
| Kubernetes | >= v1.30.0 |
| GPUStack | >= v2.2.0 |
Кроме того:
- В кластере необходимо настроить значение по умолчанию
StorageClassдля тома данных сервера (в k3s значение по умолчанию —local-path). Альтернативно, установитеserver.dataVolume.hostPath, чтобы использовать том пути хоста вместо PVC. - Для работников графического процессора убедитесь, что на узлах установлены соответствующие драйверы графического процессора и наборы инструментов для контейнеров (см. Требования к установке), а также установлено Обнаружение функций узла (NFD), чтобы узлы графического процессора были помечены.
Ограничения
- Сервер GPUStack развернут как
StatefulSetи в настоящее время не поддерживает более одной реплики. - По умолчанию используется встроенная база данных
PostgreSQL. Для производства рекомендуется указать внешнюю базу данных черезserver.externalDatabaseURL. - Плагины Higress обслуживаются специальным развертыванием
gpustack/higress-plugins, установленным вместе с GPUStack. Шлюз Higress загружает плагины из этого сервиса при перезапуске; если сервис недоступен, запуск шлюза блокируется до тех пор, пока плагины не станут доступны. - Входящий в комплект субчарт
higress-coreразвертывает Higress в качестве входного контроллера кластера. Если другой входящий контроллер уже запущен, установитеhigress-core.enabled=falseи укажитеgateway.ingressClassnameна существующий экземпляр Higress.
Установите k3s (необязательно)
В следующих шагах в качестве примера дистрибутива Kubernetes используется k3s. Другие CNCF-совместимые дистрибутивы (RKE2, кластеры на базе kubeadm или управляемые облачные Kubernetes) также работают, если они соответствуют указанным выше требованиям к версии.
Установите k3s с отключенным Traefik, поскольку в качестве входящего контроллера используется Higress. Информацию о кластерах k3s высокой доступности см. в документации k3s.
Проверьте настройку:
Установите GPUStack с помощью Helm.
Чарт публикуется как артефакт OCI в Docker Hub по адресу oci://registry-1.docker.io/gpustack/gpustack-chart. Версия чарта отслеживает выпуск GPUStack (например, чарт 2.2.0 поставляется с GPUStack v2.2.0).
Установите последнюю стабильную версию. Если --version опущено, Helm автоматически обрабатывает новейшую стабильную версию чарта и пропускает сборки для разработчиков и предварительные версии:
Чтобы закрепить конкретную версию, добавьте --version <chart-version> (версия чарта соответствует выпуску GPUStack, например 2.2.0):
По умолчанию субчарт higress-core включён и развертывается вместе с GPUStack. Если в вашем кластере уже установлен Higress, отключите встроенный Higress и укажите GPUStack на существующий экземпляр:
Чтобы настроить параметры, используйте --set key=value или -f your-values.yaml во время установки. См. Параметры чарта ниже.
Установка из клонированного репозитория.
Альтернативно клонируйте репозиторий и установите его из локального каталога чарта (полезно для изолированных сред или при изменении чарта):
Установка Higress отдельно
Если вы установили higress-core.enabled=false, установите совместимый экземпляр Higress перед развертыванием GPUStack:
Убедитесь, что IngressClass доступен и что его имя соответствует gateway.ingressClassname:
Для настройки Higress обратитесь к документации Higress.
Доступ к GPUStack
Подождите, пока серверный модуль будет готов:
Получите первоначальный пароль администратора:
Если вы не установили server.ingress.hostname, получите адрес пользовательского интерфейса GPUStack из входа:
Откройте адрес в браузере и войдите в систему, используя имя пользователя admin и пароль, полученные выше.
Общая конфигурация
Включение рабочих демонсетов
Worker DaemonSet по умолчанию отключены (worker.enabled=false). При включении чарт создаёт DaemonSet для CPU-воркеров (<release>-worker) и по одному DaemonSet для каждого производителя GPU из worker.gpuVendors (с именем <release>-worker-<vendor>).
Поддерживаемые значения worker.gpuVendors: nvidia, mthreads, amd, ascend, hygon, metax, iluvatar, cambricon, thead.
Примечание
Каждый набор демонов графического процессора получает автоматическую метку присутствия PCI nodeSelector (например, feature.node.kubernetes.io/pci-10de.present: "true" для NVIDIA), рекламируемую Node Feature Discovery. NFD должен быть установлен в кластере, иначе ни один узел не будет нести необходимые метки и все рабочие модули останутся Pending.
Всякий раз, когда в списке указан хотя бы один поставщик графического процессора (т. е. worker.gpuVendors не пусто), каждый рабочий модуль дополнительно получает обязательный podAntiAffinity (topologyKey=hostname), поэтому два рабочих не могут совместно использовать узел — это защищает порты hostNetwork: true от коллизий.
Рабочий DaemonSet ЦП охватывает узлы, на которые не претендует ни один поставщик графического процессора, через nodeSelector feature.gpustack.ai/acceleratable: "false". Установите worker.cpuEnabled=false, чтобы оставить эти узлы в покое — обычно, когда плоскость управления разделяет кластер с узлами графического процессора и не должна привлекать рабочих:
worker.gpuVendors должен содержать хотя бы одного поддерживаемого производителя; иначе чарт не создаст ни одного DaemonSet для воркеров и установка будет отклонена. GPU DaemonSet в любом случае сохраняют суффикс -<vendor>, поэтому отключение CPU DaemonSet никогда не переименовывает GPU DaemonSet в <release>-worker.
Альтернативно, добавьте кластеры графических процессоров и рабочие узлы через пользовательский интерфейс на страницах Кластеры и Рабочие после установки.
Использование внешней базы данных
По умолчанию GPUStack использует встроенную базу данных PostgreSQL. Чтобы использовать внешнюю базу данных PostgreSQL или MySQL, установите server.externalDatabaseURL:
Включение HTTPS с помощью специального сертификата.
Предоставьте сертификат и содержимое ключа (PEM) через server.ingress.tls. Когда оба установлены, входная схема становится HTTPS:
Получение образов из частного реестра
Чтобы загружать все образы (сервера/воркера GPUStack, higress-plugins и входящих в комплект компонентов higress-core: gateway/controller/pilot) из зеркального частного реестра, переопределите global.hub. Благодаря распространению глобальных значений Helm одна настройка применяется ко всем образам:
global.hub также передается на сервер как GPUSTACK_SYSTEM_DEFAULT_CONTAINER_REGISTRY, гарантируя, что образы механизма вывода (например, vLLM, llama.cpp) извлекаются из одного и того же реестра.
Чтобы предоставить учетные данные извлечения, чарт может создать секрет docker-registry с именем gpustack-image-pull-secret и подключить его ко всем модулям:
Чтобы вместо этого ссылаться на свои собственные ранее существовавшие секреты, замените global.imagePullSecrets:
Параметры чарта
Ниже перечислены наиболее часто используемые параметры. Полный и авторитетный список см. в values.yaml и README таблицы.
| Параметр | По умолчанию | Описание |
|---|---|---|
debug | false | Включить режим отладки. |
registrationToken | null | Регистрационный жетон работника; случайный генерируется и используется повторно, если null. |
clusterDomain | cluster.local | Kubernetes суффикс домена службы кластера. |
global.hub | docker.io | Хост реестра контейнеров; переопределить для частного реестра. |
global.imagePullSecrets | [gpustack-image-pull-secret] | Секреты извлечения образов, прикрепленные ко всем модулям и распространяемые на субчарты. |
global.nodeSelector | {} | NodeSelector по умолчанию для каждого компонента; заменено значением на уровне компонента. |
image.repository | gpustack/gpustack | Репозиторий образов с пространством имен; итоговая ссылка — {global.hub}/{repository}:{tag}. |
image.tag | null | Тег образа; по умолчанию используется значение appVersion чарта. |
image.pullPolicy | IfNotPresent | Политика получения образов. |
imagePullSecret.credentials.registry | docker.io | Хост реестра, используемый, когда чарт создает секрет извлечения. |
imagePullSecret.credentials.username | null | Имя пользователя реестра; создает секрет при установке пароля. |
imagePullSecret.credentials.password | null | Пароль реестра; создает секрет, если он установлен с именем пользователя. |
server.ingress.hostname | null | Входное имя хоста для сервера. |
server.ingress.tls.cert | null | Входной сертификат TLS (PEM); включает HTTPS при установке с помощью ключа. |
server.ingress.tls.key | null | Входной закрытый ключ TLS (PEM). |
server.externalDatabaseURL | null | Строка подключения к внешней базе данных (PostgreSQL или MySQL). |
server.dataVolume.hostPath | null | Путь к хосту для тома данных сервера; использует HostPath вместо PVC. |
server.dataVolume.size | 100Gi | Размер тома данных сервера (PVC). |
server.apiPort | 30080 | Порт службы API. |
server.metricsPort | 10161 | Порт метрик сервера. |
server.environmentConfig | {} | Дополнительные переменные среды для сервера GPUStack. |
server.nodeSelector | {} | Серверный модуль nodeSelector; заменяет global.nodeSelector, если не пусто. |
gateway.ingressClassname | higress | Higress Имя IngressClass; при обнаружении включает режим шлюза внутри кластера. |
higress-core.enabled | true | Разверните входящий в комплект шлюз Higress; отключить, если он уже установлен. |
worker.enabled | false | Создавать манифесты DaemonSet для воркеров. |
worker.gpuVendors | [nvidia] | поставщики графических процессоров; один набор DaemonSet от каждого поставщика плюс набор демонов ЦП. |
worker.cpuEnabled | true | Создавать манифест DaemonSet для CPU-воркеров; false требуется поставщик графического процессора. |
worker.nodeSelector | {} | Базовый nodeSelector воркеров; заменяет global.nodeSelector, если не пусто. |
worker.port | 10150 | Рабочий порт обслуживания. |
worker.metricsPort | 10151 | Порт рабочих метрик. |
worker.dataDir | /var/lib/gpustack | Путь к хосту установлен в точке /var/lib/gpustack внутри каждого рабочего модуля. |
worker.environmentConfig | {} | Дополнительные переменные среды для работника GPUStack. |
Удаление
В выпуске развертывается больше, чем просто сервер: субчарт gpustack-operator содержит контроллеры Kueue и Node Feature Discovery, а оператор создает пользовательские ресурсы, содержащие финализаторы. helm uninstall удаляет контроллеры вместе со всем остальным, поэтому пользовательские ресурсы должны быть удалены сначала — удалены, пока контроллеры еще работают — иначе объекты останутся в Terminating навсегда, а пространство имен gpustack-system никогда не покинет его. По порядку:
-
Сбросьте рабочие нагрузки, пока каждый контроллер все еще работает. Оператор очищает финализаторы своих объектов
Instance, а Kueue отказывается освобождатьClusterQueue, пока допущенныеWorkloadвсе еще занимают его — поэтому они должны удалиться, прежде чем что-либо будет отключено.Instanceнаходятся в пространстве имен и живут в пространствах имен арендаторов, поэтому перечислите их все с помощью-A. Удалить модели с сервера (или их экземпляры напрямую); модуль каждого экземпляра завершается вместе с ним, и рабочая нагрузка отправляется вместе с экземпляром. Не удаляйте поды пространства имен целиком — это уничтожит оператора, контроллеры Kueue и NFD, и именно они завершат очистку:Если Kueue используется совместно с другими приложениями, не используйте
--allздесь или на шаге 3 — удалите только объекты GPUStack. Все, что оператор создает в Kueue, имеет префиксgpustack(clusterqueue/gpustack--…,admissioncheck/gpustack-node-devices). Виды в области кластера выбираются только по имени; для пространств имен необходимо, чтобы пространство имен сохранялось, потому что-o nameего опускает: -
Остановите собственные контроллеры оператора, но оставьте версию установленной, чтобы контроллеры Kueue продолжали работать — именно они завершают удаление на следующем этапе. Пока
gpustack-operator-workerиgpustack-operator-device-manager-*DaemonSets работают, они воссоздаютLocalQueue,ClusterQueueиgpustack-node-devicesAdmissionCheck, как только вы их удаляете, поэтому счетчики никогда не достигают нуля: -
Удалите ресурсы Kueue в порядке зависимости —
LocalQueues, затемClusterQueues, затемAdmissionChecks, затемResourceFlavors. Kueue удерживает финализаторkueue.x-k8s.io/resource-in-useдля объекта, пользователи которого все еще присутствуют: AdmissionCheckgpustack-node-devicesостается в состоянии удаления до тех пор, пока не исчезнут все ClusterQueue, и каждый ClusterQueue до тех пор, пока не исчезнут его LocalQueues и допущенные рабочие нагрузки. Подождите, пока каждый вид опустеет, прежде чем переходить к следующему. В общем кластере примените к каждой команде префиксgpustackиз шага 1 вместо--all: -
Удалите релиз. Не передавайте
--wait: хук очистки Node Feature Discovery после удаления блокирует ожидание завершения дольше, чем задано в--timeout. Если принудительно завершить Helm, созданные для очистки ресурсы RBAC останутся без владельца (на шаге 5 они удаляются вручную — выполните шаг 5 и в случае, когда--waitне использовался): -
Удалите то, что не удаляет
helm uninstall. Helm никогда не удаляет CRD, а оператор регистрирует admission webhooks и APIServices, не принадлежащие ни одному релизу. После исчезновения Service оператора оба механизма блокируют запросы при ошибке обращения к нему (fail closed), а webhooks не позволяют снять финализаторы приведённой ниже командой, пока сами не будут удалены:Группа
worker.gpustack.aiвсегда принадлежит GPUStack — ни один другой компонент ее не использует — поэтому ее CRD можно безопасно удалить без каких-либо условий. -
Удалите CRD, оставшиеся после выпуска — только те, которые установлены в этом выпуске. При удалении CRD удаляются все объекты такого типа во всем кластере, поэтому, если в кластере уже выполнялись Kueue, Node Feature Discovery или Higress до GPUStack (см.
higress-core.enabledвыше) и что-то еще все еще использует их, оставьте их CRD на месте и пропустите этот шаг для этих групп. Узнайте, что есть в этом выпуске, а не гадайте:В стандартной установке, в которой указаны CRD Kueue, а также NFD и Higress, если они установлены в таблице:
Собственные CRD провайдера кластера никогда не являются объектами GPUStack для удаления — например,
*.k3s.cattle.ioиhelm.cattle.ioв кластере k3s принадлежат кластеру. -
(Необязательно) Удалите пространство имен, которое включает в себя объекты Higress, загрузочную карту ConfigMap, ServiceAccount и регистрационный токен Secret. Знайте, что с этим связано: пространство имен содержит PVC сервера (
gpustack-data-dir-gpustack-server-0,<volumeClaimTemplate>-<statefulset>-<ordinal>), в котором хранятся постоянные данные сервера — встроенная база данных PostgreSQL с ее пользователями, моделями и кластерами. В политике возвратаDelete(по умолчаниюlocal-path) базовый том также удаляется. Сохраните пространство имен, если вам нужны данные для переустановки; в противном случае удалите пространство имен (и сначала PVC, если политика восстановления еще не удалила его):