Перейти к содержанию

Управление кластером

GPUStack поддерживает управление воркерами на основе кластеров и предоставляет несколько типов кластеров. Вы можете подготовить кластер через Cloud Provider, например DigitalOcean, или создать автономный кластер и добавить исполнителей с помощью команд запуска Docker. Альтернативно, вы можете зарегистрировать все узлы в автономном кластере Kubernetes в качестве рабочих GPUStack.

Создать кластер

  1. Перейдите на страницу Clusters.
  2. Нажмите кнопку Add Cluster.
  3. Выберите поставщика кластера. Для провайдера Self-Host есть Docker и Kubernetes, а для Cloud Provider — DigitalOcean и SHUIHUA FUTURE.
  4. В зависимости от поставщика на шагах Base Configuration и Add Worker необходимо установить разные параметры.
  5. Настройки кластера Advanced в базовой конфигурации позволяют предварительно настроить параметры воркера с помощью Worker Configuration YAML.

Создание кластера Docker.

  1. На шаге Basic Configuration поле Name является обязательным, а Description является необязательным.
  2. Нажмите Save.
  3. На шаге Add Worker необходимы некоторые параметры и проверки перед добавлением воркера с помощью команды docker run.
  4. Select the GPU vendor. Протестированные поставщики включают Nvidia, AMD и Ascend. Экспериментальные поставщики включают Hygon, Moore Threads, Iluvatar, Cambricon и Metax. Нажмите Next после выбора поставщика.
  5. Check Environment. Предоставляется команда оболочки, чтобы убедиться, что ваша среда готова добавить воркера. Скопируйте сценарий и запустите его в своей среде. Нажмите Next после того, как скрипт вернет «ОК».
  6. Specify arguments для добавляемого воркера. Укажите следующие аргументы и нажмите Next: - Specify the worker IP, или пусть рабочий Auto-detect the Worker IP. Убедитесь, что рабочий IP-адрес доступен с сервера. - Укажите Additional Volume Mount для рабочего контейнера. Путь монтирования можно использовать для повторного использования существующих файлов модели.

  7. Run command, чтобы создать и запустить рабочий контейнер. Скопируйте сценарий bash и запустите его в своей среде.

Рабочий также может быть добавлен после создания кластера.

  1. Перейдите на страницу Clusters.
  2. Найдите кластер, в который вы хотите добавить воркеров.
  3. Нажмите кнопку с многоточием в столбце операций, затем выберите Add Worker.
  4. Выберите параметры для добавления воркера. Выполнив те же действия, что и выше, от Select the GPU vendor до Run command.

Регистрация кластера Kubernetes

  1. На шаге Basic Configuration поле Name является обязательным, а Description является необязательным.
  2. Нажмите Save.
  3. Select the GPU vendor. Протестированные поставщики включают Nvidia, AMD и Ascend. Экспериментальные поставщики включают Hygon, Moore Threads, Iluvatar, Cambricon и Metax. Для кластеров Kubernetes вы можете выбрать несколько поставщиков графических процессоров или не выбирать ни одного для кластеров только с ЦП — один DaemonSet воркеров отображается для каждого выбранного поставщика, а nodeSelector каждого DaemonSet извлекается из метки присутствия PCI поставщика во время манифеста. Нажмите Next после выбора поставщиков.
  4. Check environment. Предоставляется команда оболочки, позволяющая убедиться, что ваша среда готова к добавлению воркера. Скопируйте сценарий и запустите его в своей среде. Нажмите Next после того, как скрипт вернет «ОК».
  5. Run command, чтобы применить рабочие манифесты. Скопируйте сценарий bash и запустите его в среде, где установлен kubectl и настроен kubeconfig.

Kubernetes можно зарегистрировать после создания кластера.

  1. Перейдите на страницу Clusters.
  2. Найдите кластер, в котором вы хотите зарегистрировать кластер Kubernetes.
  3. Нажмите кнопку с многоточием в столбце операций, затем выберите Register Cluster.
  4. Выберите параметры регистрации кластера. Выполните те же действия, что и выше, от 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:

1
2
3
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged

Зачем это необходимо. Допуск безопасности пода встроен в Kubernetes и применяется при создании пода: под, который не соответствует уровню, сразу отклоняется, а не остается в ожидании. Модель, служба кэширования и тестовые модули законно нуждаются в том, что запрещают уровни baseline и restricted:

Требование Для чего это нужно
Сеть хоста RDMA привязывает свой GID к адресу сетевой карты
хост-порт боковой канал, который дезагрегированная пара передает своему партнеру
Host IPC Совместное использование CUDA-IPC буферов кэша KV
Крепления устройства сами ускорители

Для развертывания предварительного заполнения/декодирования требуются все четыре сразу, поэтому это первый и самый сложный случай без метки.

Почему все три ключа. Если warn и audit оставлены в кластере по умолчанию, каждое создание пода по-прежнему возвращает предупреждение и записывает аннотацию аудита. Это шум в пространстве имен, где ожидается освобождение, и он скрывает важные предупреждения в других местах.

Радиус взрыва. privileged означает, что каждый под в этих пространствах имен освобожден от допуска безопасности пода. По этой причине они представляют собой пространства имен, которые GPUStack создает и владеет ими, а не те, которые используются совместно с вашими собственными рабочими нагрузками: в них больше ничего планировать не следует. Метки также ничего не делают с Kyverno, Gatekeeper или OPA — это отдельные веб-перехватчики доступа, и их политика, запрещающая работу в сети хоста или монтирование устройств, все равно будет отклонять эти поды. Если в вашем кластере он работает, разрешите также использовать пространства имен GPUStack.

Проверка того, от чего отказался бы более строгий уровень. Против собственных текущих рабочих нагрузок, ничего не меняя:

kubectl label --dry-run=server --overwrite ns <namespace> \
  pod-security.kubernetes.io/enforce=baseline

Сервер API сравнивает существующие поды пространства имен с уровнем и предупреждает о каждом из них, который будет отклонен, называя элементы управления, которые он нарушает.

Значения чарта

При регистрации кластера Kubernetes в него устанавливается чартова GPUStack Helm, а приведенные выше параметры преобразуются в значения для этой чарта. helmValues напрямую достигает той же чарта, чего эти параметры не охватывают: ключи являются собственными для чарта, взятыми дословно, поэтому все, что предлагает чартова или ее подчарта, можно настроить, не дожидаясь здесь собственной опции.

В пользовательском интерфейсе пока нет поля, поэтому установите его через API. PUT заменяет весь кластер, поэтому сначала прочитайте кластер и отправьте его обратно с добавлением helmValues под k8sOptions:

# Read the cluster.
curl -sS -H "Authorization: Bearer <api-key>" \
  http://<server>/v2/clusters/<id> > cluster.json

# Add the values. This one keeps the chart from installing the S3 CSI driver,
# for a cluster that already provides its own storage.
jq '.k8sOptions.helmValues = {
      "gpustack-operator": {"csi-driver-s3": {"enabled": false}}
    }' cluster.json > updated.json

# Send it back.
curl -sS -X PUT -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" --data @updated.json \
  http://<server>/v2/clusters/<id>

Значения накладываются поверх значений, выведенных из параметров кластера, рекурсивно по ключам; списки заменяются целиком, а не дополняются — как в самом 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 или нет.

Остатки до того, как существовала эта очистка, удаляются таким же образом: применяется текущий манифест один раз, и задание очищает его, даже если конфигурация с тех пор не менялась. Только кластер, который вообще не может выполнить задание, нуждается в ручной форме:

kubectl delete daemonset/gpustack-worker -n gpustack-system
kubectl delete daemonset/gpustack-worker-<vendor> -n gpustack-system

Сохраняйте параметры 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. По порядку:

  1. Сначала удалите с сервера то, что запускает кластер — удалите (или перенесите) развернутые на нем модели, затем удалите запись кластера — чтобы сервер прекратил планирование воркеров, которые вот-вот исчезнут.
  2. Удалите пользовательские ресурсы , пока их контроллеры ещё работают, и подождите, пока они очистятся. Узнайте, что входит в состав релизов этого кластера, а не гадайте:

    1
    2
    3
    4
    5
    6
    7
    kubectl get crd -o json | jq -r '.items[]
      | select(((.metadata.annotations // {})["meta.helm.sh/release-name"] // "")
        | . == "gpustack" or . == "gpustack-kueue"
          or . == "gpustack-node-feature-discovery"
          or . == "gpustack-csi-driver-nfs" or . == "gpustack-csi-driver-s3"
          or . == "gpustack-operator-device-manager")
      | .metadata.name'
    

    Для каждого CRD, который указан в списке, удалите все его объекты и подождите, пока ни один не останется:

    kubectl delete <crd-name> --all -A          # e.g. clusterqueues.kueue.x-k8s.io
    kubectl get <crd-name> -A                   # empty before you move on
    
  3. Удалите выпуски. Главный из них — gpustack; пять выпусков приложения gpustack-* существуют в кластерах, зарегистрированных до того, как чартова приняла их объекты, а helm uninstall в выпуске, который не существует, является ошибкой, поэтому сначала проверьте:

    1
    2
    3
    4
    5
    6
    7
    for release in gpustack gpustack-kueue gpustack-node-feature-discovery \
                   gpustack-csi-driver-nfs gpustack-csi-driver-s3 \
                   gpustack-operator-device-manager; do
      kubectl get secret -n gpustack-system \
        --selector "owner=helm,name=${release}" >/dev/null 2>&1 || continue
      helm uninstall "${release}" -n gpustack-system --timeout 10m
    done
    

    Не пропускайте --wait здесь. С помощью --wait удаление достигает узла обнаружения функций обработчика обрезки после удаления, создает перехватчик node-feature-discovery-prune ServiceAccount и ClusterRole, а затем блокирует ожидание удаления — ожидание переживает свой --timeout (проверено с помощью helm --debug: оно находится на waiting for resources to be deleted count=1 в течение минут после тайм-аута, а только что созданный им ServiceAccount все еще существует). Убийство Хелма, чтобы сбежать от него, оставляет чернослив RBAC без владельца, поэтому крючок является причиной того, что шаг 4 удаляет эти объекты вручную. Без --wait удаление возвращается быстро, ресурсы перехватчиков очищаются вместе с остальными, а объекты все равно исчезают — шаг 4 удаляет отставшие элементы, которыми Хелм никогда не владел.

  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 для этих групп, пока они не будут удалены, и это никогда не завершится.
    1
    2
    3
    4
    5
    kubectl delete mutatingwebhookconfiguration gpustack-worker-mutation --ignore-not-found
    kubectl delete validatingwebhookconfiguration gpustack-worker-validation --ignore-not-found
    kubectl delete apiservice v1.gpustack.ai v1.worker.gpustack.ai --ignore-not-found
    kubectl delete crd devices.worker.gpustack.ai instances.worker.gpustack.ai \
      instancetypes.worker.gpustack.ai --ignore-not-found
    

    Обрезка RBAC Node Feature Discovery также может пережить helm uninstall — ClusterRole/node-feature-discovery-prune и его привязка представляют собой ресурсы обрезающего хука после удаления (см. примечание --wait выше), остающиеся без владельца, когда Хелм убит в середине хука. Более поздняя регистрация отказывается их устанавливать, а не принимать, поэтому удалите их вместе с остальными:

    kubectl delete clusterrole node-feature-discovery-prune --ignore-not-found
    kubectl delete clusterrolebinding node-feature-discovery-prune --ignore-not-found
    

    Затем загрузочный RBAC на уровне кластера, затем пространства имен. gpustack-system также содержит загрузочный ConfigMap, ServiceAccount и секретный токен регистрации — удаление пространства имен забирает их вместе с собой:

    kubectl delete clusterrolebinding gpustack-bootstrap --ignore-not-found
    kubectl delete namespace gpustack-default gpustack-system
    
  5. (Необязательно) Очистите оставшиеся на узлах данные. Поды воркеров монтируют /var/lib/gpustack с хоста; описанные выше шаги не затрагивают этот каталог с загруженными весами моделей и кэшами. Данные не мешают повторной установке: после повторной регистрации на тех же узлах кластер использует каталог и не скачивает уже имеющиеся файлы заново. Удаляйте его, только если место нужно для других целей:

    rm -rf /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), иначе само исправление будет перехвачено веб-перехватчиком, служба которого больше не существует:

1
2
3
4
kubectl api-resources --verbs=list --namespaced -o name |
  xargs -n1 -I{} sh -c 'kubectl get {} -n gpustack-default -o name 2>/dev/null'
kubectl patch <kind>/<name> -n gpustack-default \
  -p '{"metadata":{"finalizers":null}}' --type=merge

Та же полоса применима к остаткам в области кластера — объект 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

  1. На шаге Basic Configuration поле Name является обязательным, а Description является необязательным. Создайте или выберите облачные учетные данные для связи с API DigitalOcean. Выберите регион, который поддерживает капли графического процессора. Вы также должны настроить GPUStack Server URL, который будет доступен из вновь созданных капель DigitalOcean.
  2. Нажмите Next.
  3. Добавление одного или нескольких Worker Pools. Для каждого пула можно указать Name, Instance Type, OS Image, Replicas, Batch Size, Labels и Volumes.
  4. Нажмите Save после настройки рабочих пулов.

Дополнительные рабочие пулы можно добавить после создания кластера.

  1. Перейдите на страницу Clusters.
  2. Найдите кластер DigitalOcean, в который вы хотите добавить рабочий пул.
  3. Нажмите кнопку с многоточием в столбце операций, затем выберите Add Worker Pool
  4. Добавление нового пула рабочих с опциями из шага 3 выше.

Создание кластера SHUIHUA FUTURE

  1. На шаге Basic Configuration поле Name является обязательным, а поле Description является необязательным. Создайте или выберите облачные учетные данные для связи с API Shuihua. В Шуйхуа нет регионов, поэтому выбирать нечего. Вы также должны настроить GPUStack Server URL, который будет доступен из вновь созданных экземпляров.
  2. Для этого провайдера обязателен Default Container Registry: экземпляры Shuihua не имеют доступа к Docker Hub, поэтому реестр, разрешающийся в Docker Hub, не допускается. Предлагаются quay.io и swr.cn-south-1.myhuaweicloud.com; можно указать любой другой доступный реестр, например собственный Harbor или зеркало.
  3. Нажмите Next.
  4. Добавление одного или нескольких Worker Pools. Для каждого пула можно указать Name, Instance Type, OS Image, Replicas, Batch Size и Labels. Instance Type — это шаблон спецификации Shuihua, в котором указана модель графического процессора, почасовая цена и остаток на складе; распроданный шаблон выбрать невозможно. Тома не предлагаются — у Shuihua нет API блочного хранилища.
  5. Нажмите Save после настройки рабочих пулов.

Дополнительные рабочие пулы можно добавить после создания кластера так же, как и для кластера DigitalOcean.

Экземпляры Shuihua располагаются за NAT, и им сопоставлены только порты 22 и 80, поэтому кластер по умолчанию использует режим прокси-сервера tunnel, а его воркеры выполняют вывод через туннель WebSocket сервера. Их указанный IP-адрес является частным адресом экземпляра; используйте View SSH Access на воркере, чтобы получить конечную точку, которая действительно достижима. Полное пошаговое руководство см. в разделе Добавление кластера графических процессоров с помощью Shuihua.

Пулы действующих рабочих

Вы можете управлять пулами рабочих для кластеров облачных провайдеров на странице Clusters:

  1. Перейдите на страницу Clusters.
  2. Найдите кластер облачного провайдера, которым вы хотите управлять, и разверните его, чтобы просмотреть его рабочие пулы.
  3. Чтобы изменить количество реплик для воркера, измените его непосредственно в столбце воркера.
  4. Чтобы отредактировать пул рабочих, нажмите кнопку Edit и обновите Name, Replica, Batch Size и Labels по мере необходимости.
  5. Чтобы удалить рабочий пул, нажмите кнопку с многоточием в столбце операций для рабочего пула, затем выберите Delete.

Обновление кластера

  1. Перейдите на страницу Clusters.
  2. Найдите кластер, который вы хотите редактировать.
  3. Нажмите кнопку Edit.
  4. Обновите Name, Description и Worker Configuration YAML по мере необходимости.
  5. Нажмите кнопку Save.

Удалить кластер

  1. Перейдите на страницу Clusters.
  2. Найдите кластер, который вы хотите удалить.
  3. Нажмите кнопку с многоточием в столбце операций, затем выберите Delete.
  4. Подтвердите удаление.
  5. Вы не можете удалить кластер, если в нём ещё есть модели или воркеры.

YAML конфигурации воркера

При создании или обновлении кластера вы можете заранее определить рабочую конфигурацию, используя следующий пример YAML:

# ========= log level & tools ===========
debug: false
tools_download_base_url: https://mirror.your_company.com
# ========= directories ===========
pipx_path: "/usr/local/bin/pipx"
cache_dir: "/var/lib/gpustack/cache"
log_dir: "/var/lib/gpustack/log"
bin_dir: "/var/lib/gpustack/bin"
# ========= container & image ===========
image_name_override: "gpustack/gpustack:main"
image_repo: "gpustack/gpustack"
# ========= service & networking ===========
worker_ifname: en0
worker_port: 10150
worker_metrics_port: 10151
disable_worker_metrics: false
service_port_range: "40000-40063"
ray_port_range: "41000-41999"
proxy_mode: worker
# ========= system reserved resources ===========
system_reserved:
  ram: 0
  vram: 0
# ========= huggingface ===========
huggingface_token: xxxxxx
enable_hf_transfer: false
# ========= TLS ===========
insecure_tls: false

В приведенном выше 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 меняет направление: соединение устанавливается в одну сторону, от воркера к серверу.

  1. Воркер открывает постоянное исходящее соединение WebSocket с сервером — к той же конечной точке --server-url, которую он использует для регистрации — аутентифицируется с помощью своего токена и автоматически повторно подключается в случае его разрыва.
  2. Сервер запускает прокси-сервер HTTP/HTTPS на своем порту прокси (по умолчанию 30079, устанавливается через --proxy-port).
  3. Когда шлюзу необходимо достичь экземпляра модели на воркере туннельного режима, он направляет запрос на прокси-порт сервера, который передает его воркеру через существующий туннель.

Поскольку воркер осуществляет только исходящий вызов, на рабочей стороне открывать входящие порты не требуется. Ему необходимо достичь только порта API сервера, а порт прокси-сервера должен быть доступен шлюзу.

Чтобы включить его, установите для рабочего proxy_mode значение tunnel:

proxy_mode: tunnel