Управление кластером
GPUStack поддерживает управление воркерами на основе кластеров и предоставляет несколько типов кластеров. Вы можете подготовить кластер через Cloud Provider, например DigitalOcean, или создать автономный кластер и добавить исполнителей с помощью команд запуска Docker. Альтернативно, вы можете зарегистрировать все узлы в автономном кластере Kubernetes в качестве рабочих GPUStack.
Создать кластер
- Перейдите на страницу
Clusters. - Нажмите кнопку
Add Cluster. - Выберите поставщика кластера. Для провайдера
Self-HostестьDockerиKubernetes, а дляCloud Provider—DigitalOceanиSHUIHUA FUTURE. - В зависимости от поставщика на шагах
Base ConfigurationиAdd Workerнеобходимо установить разные параметры. - Настройки кластера
Advancedв базовой конфигурации позволяют предварительно настроить параметры воркера с помощьюWorker Configuration YAML.
Создание кластера Docker.
- На шаге
Basic ConfigurationполеNameявляется обязательным, аDescriptionявляется необязательным. - Нажмите
Save. - На шаге
Add Workerнеобходимы некоторые параметры и проверки перед добавлением воркера с помощью командыdocker run. Select the GPU vendor. Протестированные поставщики включаютNvidia,AMDиAscend. Экспериментальные поставщики включаютHygon,Moore Threads,Iluvatar,CambriconиMetax. НажмитеNextпосле выбора поставщика.Check Environment. Предоставляется команда оболочки, чтобы убедиться, что ваша среда готова добавить воркера. Скопируйте сценарий и запустите его в своей среде. НажмитеNextпосле того, как скрипт вернет «ОК».-
Specify argumentsдля добавляемого воркера. Укажите следующие аргументы и нажмитеNext: -Specify the worker IP, или пусть рабочийAuto-detect the Worker IP. Убедитесь, что рабочий IP-адрес доступен с сервера. - УкажитеAdditional Volume Mountдля рабочего контейнера. Путь монтирования можно использовать для повторного использования существующих файлов модели. -
Run command, чтобы создать и запустить рабочий контейнер. Скопируйте сценарий bash и запустите его в своей среде.
Рабочий также может быть добавлен после создания кластера.
- Перейдите на страницу
Clusters. - Найдите кластер, в который вы хотите добавить воркеров.
- Нажмите кнопку с многоточием в столбце операций, затем выберите
Add Worker. - Выберите параметры для добавления воркера. Выполнив те же действия, что и выше, от
Select the GPU vendorдоRun command.
Регистрация кластера Kubernetes
- На шаге
Basic ConfigurationполеNameявляется обязательным, аDescriptionявляется необязательным. - Нажмите
Save. Select the GPU vendor. Протестированные поставщики включаютNvidia,AMDиAscend. Экспериментальные поставщики включаютHygon,Moore Threads,Iluvatar,CambriconиMetax. Для кластеровKubernetesвы можете выбрать несколько поставщиков графических процессоров или не выбирать ни одного для кластеров только с ЦП — один DaemonSet воркеров отображается для каждого выбранного поставщика, аnodeSelectorкаждого DaemonSet извлекается из метки присутствия PCI поставщика во время манифеста. НажмитеNextпосле выбора поставщиков.Check environment. Предоставляется команда оболочки, позволяющая убедиться, что ваша среда готова к добавлению воркера. Скопируйте сценарий и запустите его в своей среде. НажмитеNextпосле того, как скрипт вернет «ОК».Run command, чтобы применить рабочие манифесты. Скопируйте сценарий bash и запустите его в среде, где установленkubectlи настроенkubeconfig.
Kubernetes можно зарегистрировать после создания кластера.
- Перейдите на страницу
Clusters. - Найдите кластер, в котором вы хотите зарегистрировать кластер Kubernetes.
- Нажмите кнопку с многоточием в столбце операций, затем выберите
Register Cluster. - Выберите параметры регистрации кластера. Выполните те же действия, что и выше, от
Select the GPU vendorдоRun command.
Параметры кластера Kubernetes
При создании или редактировании кластера Kubernetes на шаге Basic Configuration в дополнение к Name и Description доступны следующие параметры:
Cluster Type(обязательно) — выберите способ использования кластера:Model Service— для вывода LLM и обслуживания API, например. предоставление доступа к API-интерфейсам модели и сервисам на основе токенов.GPU Service— для вычислений на графическом процессоре по требованию, например. интерактивная разработка, учебные задания или пользовательские среды.
Настройки Advanced предоставляют следующие варианты развертывания Kubernetes:
Namespace— пространство имен Kubernetes, в котором отображаются манифесты кластера. Оставьте пустым, чтобы использоватьgpustack-system.Volume Mounts— дополнительные тома, подключенные к каждому рабочему поду. Для каждого монтирования укажите флагVolume Name,Container PathиRead Only, затем выберитеSource Type:Host Path— путь в узле сPath Type(например,Directory,Directory (create if not exists),File,Socket,Character Device,Block Device).Persistent Volume Claim (PVC)— существующийPVC Name, опционально доступный только для чтения.ConfigMap—ConfigMap Name, необязательно помечено как необязательное.
Image Credentials— секреты получения изображений, используемые для извлечения изображений GPUStack из частного реестра. Для каждой записи укажитеRegistry,UsernameиPassword.Node Selector— ограничивает рабочие нагрузки GPUStack этого кластера узлами, метки которых совпадают. Он передается какglobal.nodeSelectorчарта, к которому возвращается каждый компонент, поэтому он достигает DaemonSet воркеров и оператора, а также компонентов, которые развертывает оператор (Kueue, плоскость управления Node Feature Discovery, контроллеры CSI) из версии оператора, которая его учитывает. Два типа рабочей нагрузки намеренно опущены: те, которые должны охватывать узлы, которые они обслуживают (маркировщик Node Feature Discovery, плагины узлов CSI), поскольку их ограничение оставит все остальные узлы без меток — в том числе с метками, которые сами воркеры выбирают, — и перехватчики установки чарта, которые запускаются до того, как существует релиз, и поэтому не могут ждать метки, к которой применяется сам релиз. DaemonSet воркеров сохраняет метку поставщика графического процессора, а также эти; узел должен соответствовать обоим.Default Container Registry— реестр по умолчанию, используемый для разрешения образов GPUStack для этого кластера. Возвращается к настройкам сервера по умолчанию, если они не установлены (заполнительdocker.io).Operator Image— переопределение образа контейнера оператора GPUStack. Оставьте пустым, чтобы использовать сервер по умолчанию.GPU Service Static Access Address— отображается только тогда, когдаCluster TypeравноGPU Service. Статический адрес, который оператор использует для доступа к экземплярам графического процессора в этом кластере (например, VIP-адрес LoadBalancer). Необязательный.Worker Configuration YAML— см. YAML конфигурации рабочей силы ниже.
Пространства имен и безопасность доступа к модулям
GPUStack создает принадлежащие ему пространства имен — gpustack-system (или любое другое значение, установленное в Namespace) и одно gpustack-<org> на каждую организацию, использующую кластер — и помечает каждое из них для Pod Security Admission на уровне privileged:
Зачем это необходимо. Допуск безопасности пода встроен в Kubernetes и применяется при создании пода: под, который не соответствует уровню, сразу отклоняется, а не остается в ожидании. Модель, служба кэширования и тестовые модули законно нуждаются в том, что запрещают уровни baseline и restricted:
| Требование | Для чего это нужно |
|---|---|
| Сеть хоста | RDMA привязывает свой GID к адресу сетевой карты |
| хост-порт | боковой канал, который дезагрегированная пара передает своему партнеру |
| Host IPC | Совместное использование CUDA-IPC буферов кэша KV |
| Крепления устройства | сами ускорители |
Для развертывания предварительного заполнения/декодирования требуются все четыре сразу, поэтому это первый и самый сложный случай без метки.
Почему все три ключа. Если warn и audit оставлены в кластере по умолчанию, каждое создание пода по-прежнему возвращает предупреждение и записывает аннотацию аудита. Это шум в пространстве имен, где ожидается освобождение, и он скрывает важные предупреждения в других местах.
Радиус взрыва. privileged означает, что каждый под в этих пространствах имен освобожден от допуска безопасности пода. По этой причине они представляют собой пространства имен, которые GPUStack создает и владеет ими, а не те, которые используются совместно с вашими собственными рабочими нагрузками: в них больше ничего планировать не следует. Метки также ничего не делают с Kyverno, Gatekeeper или OPA — это отдельные веб-перехватчики доступа, и их политика, запрещающая работу в сети хоста или монтирование устройств, все равно будет отклонять эти поды. Если в вашем кластере он работает, разрешите также использовать пространства имен GPUStack.
Проверка того, от чего отказался бы более строгий уровень. Против собственных текущих рабочих нагрузок, ничего не меняя:
Сервер API сравнивает существующие поды пространства имен с уровнем и предупреждает о каждом из них, который будет отклонен, называя элементы управления, которые он нарушает.
Значения чарта
При регистрации кластера Kubernetes в него устанавливается чартова GPUStack Helm, а приведенные выше параметры преобразуются в значения для этой чарта. helmValues напрямую достигает той же чарта, чего эти параметры не охватывают: ключи являются собственными для чарта, взятыми дословно, поэтому все, что предлагает чартова или ее подчарта, можно настроить, не дожидаясь здесь собственной опции.
В пользовательском интерфейсе пока нет поля, поэтому установите его через API. PUT заменяет весь кластер, поэтому сначала прочитайте кластер и отправьте его обратно с добавлением helmValues под k8sOptions:
Значения накладываются поверх значений, выведенных из параметров кластера, рекурсивно по ключам; списки заменяются целиком, а не дополняются — как в самом Helm. Ключи описаны в документации чартов: в values.yaml чарта GPUStack, а для раздела gpustack-operator — в чарте GPUStack Operator.
Некоторые пути отклоняются, а не объединяются: те, которые сервер извлекает из регистрации этого кластера, которые решают, что выпуск соответствует кластеру, для которого он был выпущен — где его рабочие сообщают, какой образ они запускают, из какого реестра взят этот образ, какой секрет содержит токен. API называет путь, который он отверг, а описание поля helmValues содержит текущий список; эта страница не повторяет ее, поэтому они не могут дрейфовать.
Примечание
Само по себе сохранение кластера ничего не меняет в Kubernetes. Перезапустите Register Cluster и примените полученный манифест: задание внутри кластера сравнивает то, что запрашивает манифест, с тем, из чего был установлен выпуск, и обновляется только в том случае, если они отличаются.
Примечание
Обновление, которое меняет то, что развертывается в выпуске — отключение рабочего DaemonSet ЦП (worker.cpuEnabled=false в helmValues, для кластера, узлы которого содержат только ЦП и несут плоскость управления) или удаление поставщика графического процессора, который кластер больше не выбирает — удаляет DaemonSet воркеров, которые он прекращает рендеринг самостоятельно: kubectl apply не будет (он никогда не удаляет объект, который не указан в манифесте), поэтому задание обновления удаляет каждый <release>-worker[-<vendor>] DaemonSet, который больше не отображается в выпуске, независимо от того, принадлежал ли он когда-либо ревизии Helm или нет.
Остатки до того, как существовала эта очистка, удаляются таким же образом: применяется текущий манифест один раз, и задание очищает его, даже если конфигурация с тех пор не менялась. Только кластер, который вообще не может выполнить задание, нуждается в ручной форме:
Сохраняйте параметры Register Cluster (поставщики графического процессора, параметры) идентичными последнему примененному манифесту, когда вы хотите обновить только версию — все остальное является изменением конфигурации, а не обновлением.
Предупреждение
Kueue и Node Feature Discovery обязательны. Оператор строит на них цепочку планирования и при запуске ожидает их CRD. Если отключить компонент, который кластер ещё не предоставляет самостоятельно, оператор не сможет запуститься. Если компонент был установлен этим релизом, его отключение удалит его: CRD Kueue поставляются его чартом и удаляются вместе со всеми Workload и ClusterQueue.
Удаление кластера Kubernetes
Удаление производится из helm uninstall выпусков, для которых установлена регистрация, а также объектов, которыми Helm никогда не владел. Один подготовительный шаг решает, завершится ли все чисто: дерево операторов (Kueue, Node Feature Discovery, драйверы CSI, диспетчеры устройств) развертывает контроллеры, чьи пользовательские ресурсы содержат финализаторы, а удаление удаляет эти контроллеры — поэтому ресурсы должны быть удалены первыми, иначе пространства имен, в которых они живут (gpustack-system, gpustack-default), никогда не покинут Terminating. По порядку:
- Сначала удалите с сервера то, что запускает кластер — удалите (или перенесите) развернутые на нем модели, затем удалите запись кластера — чтобы сервер прекратил планирование воркеров, которые вот-вот исчезнут.
-
Удалите пользовательские ресурсы , пока их контроллеры ещё работают, и подождите, пока они очистятся. Узнайте, что входит в состав релизов этого кластера, а не гадайте:
Для каждого CRD, который указан в списке, удалите все его объекты и подождите, пока ни один не останется:
-
Удалите выпуски. Главный из них —
gpustack; пять выпусков приложенияgpustack-*существуют в кластерах, зарегистрированных до того, как чартова приняла их объекты, аhelm uninstallв выпуске, который не существует, является ошибкой, поэтому сначала проверьте:Не пропускайте
--waitздесь. С помощью--waitудаление достигает узла обнаружения функций обработчика обрезки после удаления, создает перехватчикnode-feature-discovery-pruneServiceAccount и ClusterRole, а затем блокирует ожидание удаления — ожидание переживает свой--timeout(проверено с помощьюhelm --debug: оно находится наwaiting for resources to be deleted count=1в течение минут после тайм-аута, а только что созданный им ServiceAccount все еще существует). Убийство Хелма, чтобы сбежать от него, оставляет чернослив RBAC без владельца, поэтому крючок является причиной того, что шаг 4 удаляет эти объекты вручную. Без--waitудаление возвращается быстро, ресурсы перехватчиков очищаются вместе с остальными, а объекты все равно исчезают — шаг 4 удаляет отставшие элементы, которыми Хелм никогда не владел. -
Удалите то, что
helm uninstallне удаляет. Helm никогда не удаляет CRD, и оператор регистрирует еще три типа объектов в области кластера, которыми не владеет ни одна версия:- Собственные CRD оператора —
devices,instancesиinstancetypesподworker.gpustack.ai. Оператор создает их при запуске, а не чартову, поэтому они не содержат аннотацийmeta.helm.sh/release-nameи в запросе на обнаружение на шаге 2 они не перечисляются. Объектinstancetypeсохраняется с помощью финализатораgpustack.ai/controlled; удалите его (см. ниже) до или во время удаления CRD, иначе CRD останется в удалении, а API группы никогда не исчезнет. - Вебхуки допуска оператора —
gpustack-worker-mutation(Мутация) иgpustack-worker-validation(Проверка). Они пересылаются в службу оператора и закрываются при сбое, поэтому до тех пор, пока они не будут удалены, каждая запись в объектworker.gpustack.ai, включая полосу финализатора ниже, отклоняется с помощьюservice "gpustack-operator-worker" not found. - APIServices оператора —
v1.gpustack.aiиv1.worker.gpustack.ai, также поддерживаемые Службой оператора. Пространство имен зависло при удалении отчетовstale GroupVersion discoveryдля этих групп, пока они не будут удалены, и это никогда не завершится.
Обрезка RBAC Node Feature Discovery также может пережить
helm uninstall—ClusterRole/node-feature-discovery-pruneи его привязка представляют собой ресурсы обрезающего хука после удаления (см. примечание--waitвыше), остающиеся без владельца, когда Хелм убит в середине хука. Более поздняя регистрация отказывается их устанавливать, а не принимать, поэтому удалите их вместе с остальными:Затем загрузочный RBAC на уровне кластера, затем пространства имен.
gpustack-systemтакже содержит загрузочный ConfigMap, ServiceAccount и секретный токен регистрации — удаление пространства имен забирает их вместе с собой: - Собственные CRD оператора —
-
(Необязательно) Очистите оставшиеся на узлах данные. Поды воркеров монтируют
/var/lib/gpustackс хоста; описанные выше шаги не затрагивают этот каталог с загруженными весами моделей и кэшами. Данные не мешают повторной установке: после повторной регистрации на тех же узлах кластер использует каталог и не скачивает уже имеющиеся файлы заново. Удаляйте его, только если место нужно для других целей:
Проверьте с помощью kubectl get all -n gpustack-system (должно быть NotFound), kubectl get clusterrolebinding | grep gpustack, kubectl get ds -A | grep -E 'gpustack|csi' и — для объектов, которые удаляются только на шаге 4 — kubectl get apiservice,mutatingwebhookconfiguration,validatingwebhookconfiguration 2>/dev/null | grep gpustack и kubectl get crd | grep -E 'gpustack|worker\.gpustack' (оба не должны ничего печатать).
Если пространство имен уже застряло в Terminating, его объекты по-прежнему содержат финализаторы, контроллеры которых исчезли. Найдите их, затем удалите финализаторы вручную — безопасно только на удаляемом кластере. Сначала удалите веб-перехватчики доступа (шаг 4), иначе само исправление будет перехвачено веб-перехватчиком, служба которого больше не существует:
Та же полоса применима к остаткам в области кластера — объект instancetype.worker.gpustack.ai, содержащий финализатор gpustack.ai/controlled, сохраняет свой CRD (а вместе с ним и всю группу worker.gpustack.ai) в состоянии удаления: kubectl patch instancetypes.worker.gpustack.ai <name> -p '{"metadata":{"finalizers":null}}' --type=merge.
Создание кластера DigitalOcean
- На шаге
Basic ConfigurationполеNameявляется обязательным, аDescriptionявляется необязательным. Создайте или выберите облачные учетные данные для связи с API DigitalOcean. Выберите регион, который поддерживает капли графического процессора. Вы также должны настроитьGPUStack Server URL, который будет доступен из вновь созданных капель DigitalOcean. - Нажмите
Next. - Добавление одного или нескольких
Worker Pools. Для каждого пула можно указатьName,Instance Type,OS Image,Replicas,Batch Size,LabelsиVolumes. - Нажмите
Saveпосле настройки рабочих пулов.
Дополнительные рабочие пулы можно добавить после создания кластера.
- Перейдите на страницу
Clusters. - Найдите кластер
DigitalOcean, в который вы хотите добавить рабочий пул. - Нажмите кнопку с многоточием в столбце операций, затем выберите
Add Worker Pool - Добавление нового пула рабочих с опциями из шага 3 выше.
Создание кластера SHUIHUA FUTURE
- На шаге
Basic ConfigurationполеNameявляется обязательным, а полеDescriptionявляется необязательным. Создайте или выберите облачные учетные данные для связи с API Shuihua. В Шуйхуа нет регионов, поэтому выбирать нечего. Вы также должны настроитьGPUStack Server URL, который будет доступен из вновь созданных экземпляров. - Для этого провайдера обязателен
Default Container Registry: экземпляры Shuihua не имеют доступа к Docker Hub, поэтому реестр, разрешающийся в Docker Hub, не допускается. Предлагаютсяquay.ioиswr.cn-south-1.myhuaweicloud.com; можно указать любой другой доступный реестр, например собственный Harbor или зеркало. - Нажмите
Next. - Добавление одного или нескольких
Worker Pools. Для каждого пула можно указатьName,Instance Type,OS Image,Replicas,Batch SizeиLabels.Instance Type— это шаблон спецификации Shuihua, в котором указана модель графического процессора, почасовая цена и остаток на складе; распроданный шаблон выбрать невозможно. Тома не предлагаются — у Shuihua нет API блочного хранилища. - Нажмите
Saveпосле настройки рабочих пулов.
Дополнительные рабочие пулы можно добавить после создания кластера так же, как и для кластера DigitalOcean.
Экземпляры Shuihua располагаются за NAT, и им сопоставлены только порты 22 и 80, поэтому кластер по умолчанию использует режим прокси-сервера tunnel, а его воркеры выполняют вывод через туннель WebSocket сервера. Их указанный IP-адрес является частным адресом экземпляра; используйте View SSH Access на воркере, чтобы получить конечную точку, которая действительно достижима. Полное пошаговое руководство см. в разделе Добавление кластера графических процессоров с помощью Shuihua.
Пулы действующих рабочих
Вы можете управлять пулами рабочих для кластеров облачных провайдеров на странице Clusters:
- Перейдите на страницу
Clusters. - Найдите кластер облачного провайдера, которым вы хотите управлять, и разверните его, чтобы просмотреть его рабочие пулы.
- Чтобы изменить количество реплик для воркера, измените его непосредственно в столбце воркера.
- Чтобы отредактировать пул рабочих, нажмите кнопку
Editи обновитеName,Replica,Batch SizeиLabelsпо мере необходимости. - Чтобы удалить рабочий пул, нажмите кнопку с многоточием в столбце операций для рабочего пула, затем выберите
Delete.
Обновление кластера
- Перейдите на страницу
Clusters. - Найдите кластер, который вы хотите редактировать.
- Нажмите кнопку
Edit. - Обновите
Name,DescriptionиWorker Configuration YAMLпо мере необходимости. - Нажмите кнопку
Save.
Удалить кластер
- Перейдите на страницу
Clusters. - Найдите кластер, который вы хотите удалить.
- Нажмите кнопку с многоточием в столбце операций, затем выберите
Delete. - Подтвердите удаление.
- Вы не можете удалить кластер, если в нём ещё есть модели или воркеры.
YAML конфигурации воркера
При создании или обновлении кластера вы можете заранее определить рабочую конфигурацию, используя следующий пример YAML:
В приведенном выше YAML-файле перечислены все поддерживаемые в настоящее время параметры для Worker Configuration YAML. Значение каждой опции см. в полной документации по файлу конфигурации GPUStack . Опция proxy_mode управляет тем, как сервер достигает воркера — см. Режимы подключения воркера.
Реестр контейнеров по умолчанию больше не задается здесь ни для кластеров Docker, ни для Kubernetes; Вместо этого настройте его с помощью опции Default Container Registry уровня кластера в настройках Advanced. Для кластеров Kubernetes пространство имен также настраивается с помощью параметра Namespace (см. Параметры кластера Kubernetes).
Режимы подключения рабочих
Чтобы пересылать запросы на вывод экземплярам модели на рабочем сервере, серверу и шлюзу API необходим сетевой путь обратно к этому воркеру. Опция рабочего proxy_mode, установленная с помощью YAML Worker Configuration YAML или флага --proxy-mode, выбирает этот путь:
direct— Сервер и шлюз подключаются напрямую к объявленному адресу и порту воркера. Самые низкие накладные расходы, но воркер должен быть доступен напрямую с сервера.worker— запросы проходят через встроенный HTTP reverse proxy воркера, который передаёт их локальному процессу инференса. Воркер по-прежнему должен быть доступен серверу, но открыть достаточно только порта воркера.tunnel— воркер поддерживает одно исходящее WebSocket-соединение с сервером, и сервер обращается к нему только через туннель. Используйте этот режим, когда воркер не может принимать входящие соединения от сервера.
Значение по умолчанию — direct для встроенного воркера внутри сервера и worker для автономного воркера.
Туннельный режим (воркер за брандмауэром или NAT)
В режимах direct и worker сервер инициирует соединение, поэтому воркер должен быть доступен с сервера. Это не всегда возможно — например, когда воркер находится за брандмауэром или NAT, в другой сети или в частной подсети, которая разрешает только исходящий трафик.
tunnel меняет направление: соединение устанавливается в одну сторону, от воркера к серверу.
- Воркер открывает постоянное исходящее соединение WebSocket с сервером — к той же конечной точке
--server-url, которую он использует для регистрации — аутентифицируется с помощью своего токена и автоматически повторно подключается в случае его разрыва. - Сервер запускает прокси-сервер HTTP/HTTPS на своем порту прокси (по умолчанию
30079, устанавливается через--proxy-port). - Когда шлюзу необходимо достичь экземпляра модели на воркере туннельного режима, он направляет запрос на прокси-порт сервера, который передает его воркеру через существующий туннель.
Поскольку воркер осуществляет только исходящий вызов, на рабочей стороне открывать входящие порты не требуется. Ему необходимо достичь только порта API сервера, а порт прокси-сервера должен быть доступен шлюзу.
Чтобы включить его, установите для рабочего proxy_mode значение tunnel: