Установим отдельный экземпляр Open WebUI в готовый кластер Kubernetes через Helm и откроем его в браузере по адресу http://127.0.0.1:13000. Создадим первый аккаунт администратора, штатно заменим под и проверим, что с прежним хранилищем вход в этот аккаунт продолжает работать.
Это новая установка. Существующий экземпляр из урока про установку через Docker Compose или с отдельного сервера сюда не переносится.
Понадобится кластер Kubernetes, с которым вам разрешено работать. На компьютере с браузером должны быть настроены kubectl, Helm 3 и доступ к нужному контексту kubeconfig. Подробные требования приведены в официальном руководстве по Kubernetes для Open WebUI.
До начала работы согласуйте с администратором или оператором кластера:
- новое пространство имён (
namespace)open-webui-courseи одноимённый релиз; - права на установку учебных ресурсов и штатный перезапуск
rollout restart; - класс хранилища
StorageClass, подходящий для SQLite; - стабильный объект
Secretс именемopen-webui-authи ключомWEBUI_SECRET_KEY. Оператор создаст его после появления пространства имён, до установки приложения.
Если готового кластера нет, вернитесь к выбору способа установки и выберите локальный или серверный вариант. Поднимать кластер специально ради урока не нужно.
Продолжайте после подтверждения StorageClass и Secret оператором. Если при проверке найдутся прежний релиз или незнакомые ресурсы в выбранном пространстве имён, остановитесь и согласуйте новые свободные имена. Учебный экземпляр не должен устанавливаться поверх существующих объектов.
Команды рассчитаны на Bash или Zsh: Терминал macOS или Linux либо Ubuntu в WSL2 на Windows. PowerShell использует другой синтаксис. Подготовьте на компьютере с браузером отдельную учебную папку для файла values-course.yaml.
Откройте два локальных окна терминала. В первом зададим переменные, установим приложение и проверим замену пода. Во втором запустим перенаправление портов на 127.0.0.1:13000. В Windows адрес открываем в обычном браузере Windows на том же компьютере. Если настройки WSL2 ограничивают локальный проброс портов, проверьте маршрут до 127.0.0.1.
Мы проверили конфигурацию офлайн командами helm lint и helm template в Helm 3.14.2. Запуск в кластере и проверку сохранения аккаунта вы выполняете в своей среде.
Как устроена установка и где хранятся данные
Чарт Helm (chart) содержит шаблоны ресурсов Kubernetes. Установка этого чарта с нашими настройками из values-course.yaml создаёт релиз (release), то есть конкретный экземпляр приложения в кластере.
Закрепим две независимые версии: чарт 17.0.0 и образ приложения ghcr.io/open-webui/open-webui:v0.12.0. Они указаны в описании Chart.yaml. Так установка не зависит от плавающего тега latest. Параметры ниже проверены для чарта 17.0.0 и отличаются от его настроек по умолчанию.
Контейнер Open WebUI запускается внутри пода (Pod). При обновлении, перезапуске или переносе между узлами Kubernetes может заменить старый под новым. У нового пода будет другой уникальный идентификатор UID. В нашем примере заменой управляет контроллер Deployment.
По умолчанию чарт выбирает StatefulSet и включает дополнительные компоненты. Для учебной установки используем схему из официального руководства по Kubernetes: Deployment, одна реплика (replicaCount: 1), один рабочий процесс (UVICORN_WORKERS=1) и стратегия Recreate.
При штатном обновлении Deployment стратегия Recreate останавливает прежние поды перед запуском новых, как описано в документации Kubernetes. Интерфейс на это время станет недоступен. В выбранной схеме одна реплика и один процесс используют SQLite. Настройка Recreate не даёт той же гарантии при ручном удалении подов и других способах запуска.
Дополнительные компоненты ollama, pipelines, tika, terminals и встроенный redis отключим. Внешние маршруты ingress и route тоже не понадобятся. Поддержка websocket останется включённой и будет работать в памяти одного процесса без Redis.
Чтобы аккаунт пережил замену пода, вынесем данные из временной файловой системы контейнера. Чарт создаст PersistentVolumeClaim (PVC), запрос на постоянное хранилище. Подключённый том будет смонтирован в /app/backend/data. В конфигурации Open WebUI v0.12.0 в этом каталоге находятся файл SQLite webui.db и папки загрузок. При замене пода прежние PVC и связанный с ним том PersistentVolume (PV) подключаются к новому поду.
Параметр provider: local означает файловое хранение приложения в подключённом томе, в отличие от объектного хранилища вроде S3. Он не означает, что диск физически расположен на узле кластера. Способ выделения тома определяет StorageClass.
Для SQLite нужны низкая задержка и надёжные файловые блокировки. Согласно рекомендациям Open WebUI, NFS и SMB для такой базы использовать нельзя. Поэтому подходящий класс хранилища выбираем вместе с оператором.
В примере запросим 10Gi в режиме ReadWriteOnce. Kubernetes определяет этот режим как монтирование тома на чтение и запись одним узлом. Два пода на одном узле он сам по себе не запрещает; для штатного перезапуска мы задаём одну реплику, один процесс и Recreate.
Объём 10Gi, запросы 500m CPU / 1Gi памяти и лимиты 2 CPU / 4Gi памяти выбраны для примера. Они не гарантируют производительность в любой инфраструктуре.
Аннотация helm.sh/resource-policy: keep просит Helm сохранять PVC при операциях с релизом. Она не заменяет резервное копирование и не защищает от ручного удаления тома или всего пространства имён. Команды удаления в уроке не используются.
Для сохранения доступа нужен также постоянный WEBUI_SECRET_KEY. Без явно переданного ключа стартовый скрипт создаёт случайный ключ в файле .webui_secret_key в рабочем каталоге /app/backend. Этот файл находится вне постоянного тома /app/backend/data и пропадёт при замене пода.
Чарт сам не создаёт секрет. Поэтому в extraEnvVars укажем ссылку secretKeyRef на подготовленный оператором Secret open-webui-auth.
Проверки состояния помогут дождаться запуска. startupProbe обращается к /health и проверяет, что веб-процесс отвечает. readinessProbe обращается к /ready: в версии 0.12.0 этот адрес проверяет завершение инициализации и ответ базы данных. После прохождения проверки готовности внутренний Service типа ClusterIP начнёт направлять трафик с порта 80 на порт контейнера 8080.
Перед созданием конфигурации проверим целевой кластер и убедимся, что выбранные имена свободны.
Подготовим конфигурацию и установим Open WebUI
Работаем в первом терминале, в учебной папке для values-course.yaml. Сохраним имя нужного контекста kubeconfig в CTX и будем явно передавать его командам через --context и --kube-context. Переключать глобальный контекст не потребуется.
Пространство имён open-webui-course группирует ресурсы урока. Само по себе оно не обеспечивает полной сетевой или административной изоляции.
Проверим контекст и свободные имена
Посмотрим текущий контекст, зададим переменные первого терминала и проверим доступ к кластеру и хранилищу. Замените REPLACE_WITH_APPROVED_CONTEXT точным именем согласованного существующего контекста:
Команда current-context показывает текущее подключение, ничего не переключая. В выводе helm version --short должна быть версия v3.x. Команды cluster-info и get storageclass должны показать знакомый кластер и согласованный класс хранилища для SQLite.
Затем проверим выбранные имена:
Для новой установки ожидаем NotFound от get namespace и пустой список helm list. Если пространство имён уже существует, найден старый релиз или команда вернула Forbidden, остановитесь. Согласуйте свободные имена или недостающие права с администратором. Отдельное разрешение при необходимости можно уточнить командой вида kubectl --context "$CTX" auth can-i ....
Если имена свободны и доступ разрешён, создадим пространство имён:
После создания пространства имён сделайте паузу: оператор должен подготовить в нём Secret open-webui-auth с ключом WEBUI_SECRET_KEY. Ключ не генерируем в командной строке урока и не записываем в текстовые файлы.
Когда оператор подтвердит, что секрет создан и сохранён в системе управления секретами, проверим наличие объекта:
Команда покажет сводку объекта без секретного значения. Строка open-webui-auth подтверждает только его наличие в выбранном пространстве имён. Наличие точного ключа WEBUI_SECRET_KEY и неизменность значения подтверждает оператор. Флаги -o yaml и -o json здесь не нужны.
Проверим шаблон и выполним установку
Сохраните файл values-course.yaml в учебной папке. В поле storageClass замените REPLACE_WITH_SQLITE_SUITABLE_STORAGE_CLASS точным именем согласованного класса из вывода get storageclass. Остальной файл оставьте без изменений:
В той же папке подключим официальный репозиторий, сверим версию чарта и сохраним итоговые описания ресурсов в rendered-open-webui.yaml. Эти команды ещё не устанавливают приложение:
Команды helm repo add и helm repo update подключают репозиторий и обновляют его локальный индекс. В выводе helm show chart сверьте version: 17.0.0 и appVersion: 0.12.0.
helm template собирает манифест локально. В файл попадает ссылка secretKeyRef, а не значение секрета из кластера. Откройте rendered-open-webui.yaml и проверьте:
- один контроллер
kind: Deploymentсо стратегиейtype: Recreate; - образ
ghcr.io/open-webui/open-webui:v0.12.0; PersistentVolumeClaimс вашимstorageClassNameи подключение тома в/app/backend/data;- ссылку на
open-webui-authс ключомWEBUI_SECRET_KEY; ServiceтипаClusterIPс портом80, ведущим к порту контейнера8080.
После проверки манифеста установим релиз:
С флагом --wait Helm ожидает готовности ресурсов до 15m. Первое скачивание образа и инициализация могут занять несколько минут. При таймауте или ошибке не повторяйте helm install и не удаляйте ресурсы наугад. Проверьте статус ниже и найдите нужную проверку в таблице в конце урока.
Проверим готовность релиза и тома
Проверим релиз, под и том в первом терминале:
Имя релиза open-webui-course содержит строку open-webui, поэтому шаблон чарта даёт основным объектам Deployment, Service и PersistentVolumeClaim то же имя. Подтвердите его в выводе команды с фильтром -l "$SELECTOR".
Статус тома Bound проверяем после создания Deployment. Если класс хранилища использует WaitForFirstConsumer, привязка тома ждёт, пока планировщик выберет узел для пода.
Ожидаем успешное завершение rollout status, один под с готовностью 1/1 в get pods и статус Bound у PVC. В нашей конфигурации готовность 1/1 означает, что прошли проверки /health и /ready: приложение инициализировалось и получает ответ SQLite на подключённом томе. Работу языковой модели эти проверки не тестируют.
Когда эти условия выполнены, можно открыть локальный доступ к Service, не меняя релиз.
Откроем интерфейс и создадим первый аккаунт
У Service open-webui-course внутренний адрес типа ClusterIP. Чтобы открыть приложение в своём браузере, используем kubectl port-forward. Путь соединения будет таким: локальный 127.0.0.1:13000 → порт 80 сервиса → порт 8080 контейнера в выбранном поде.
Это личный доступ для проверки и настройки. Он не создаёт общего адреса для команды и не заменяет настройку сетевой безопасности кластера.
Откройте второй локальный терминал на компьютере с браузером. Переменные первого окна в нём недоступны, поэтому зададим CTX и NS заново:
Подставьте тот же CTX, что и в первом терминале. Переменные RELEASE и SELECTOR здесь не нужны.
port-forward удерживает терминал занятым, пока работает перенаправление. Оставьте окно открытым. Нажатие Ctrl+C завершит пересылку трафика; под и данные в кластере продолжат работать.
Откройте http://127.0.0.1:13000 в браузере этого компьютера. На новой установке создайте первую учётную запись администратора. Подробности ролей и начальных настроек есть в уроке «Первый вход и базовые настройки доступа».
Выйдите из аккаунта и войдите снова с теми же данными. Так проверим исходное состояние: запись пользователя сохранена в SQLite на постоянном томе, а вход работает. Ответ модели для этой проверки не нужен. Проверяем одну запись пользователя, не остальные данные.
Теперь заменим под и сравним идентификаторы ресурсов до и после перезапуска.
Проверим аккаунт после замены Pod
Выполним замену через kubectl rollout restart, чтобы проверить аккаунт с новым подом и прежним томом. Команда обновляет шаблон Deployment, и стратегия Recreate останавливает старый под перед запуском нового. Ручное или принудительное удаление пода для этой проверки не используем.
Вернитесь в первый терминал, где заданы CTX, NS и SELECTOR. Выведем имя и UID пода, а также UID объекта PVC и имя его тома в колонке VOLUME. Затем перезапустим Deployment, дождёмся завершения и запросим те же сведения:
Сравните несекретные метаданные до и после перезапуска:
- у объекта
Podизменились и имя (NAME), и уникальный идентификатор (UID), то есть приложение работает в новом поде; - у объекта
PVCopen-webui-courseзначениеUID, статусBoundи имя привязанного тома в колонкеVOLUME(PV) остались прежними.
Старый процесс port-forward был связан с завершившимся подом, поэтому соединение оборвётся. Во втором терминале остановите его через Ctrl+C, если он ещё не завершился, и запустите перенаправление снова.
Переменные CTX и NS в этом окне уже заданы. Если окно закрыли, повторите полный блок из трёх строк из предыдущего раздела:
Откройте http://127.0.0.1:13000 в новом приватном окне браузера, чтобы исключить влияние старого кеша страницы. Ожидаем обычную форму входа. Войдите в аккаунт, созданный до замены пода.
Если приложение снова предлагает создать первого администратора, остановитесь и не создавайте второй аккаунт. Вместе с оператором проверьте выбранный экземпляр, подключение прежнего тома и ключ.
Новый UID пода, прежние UID объекта PVC и имя VOLUME, а также успешный вход в приватном окне подтверждают выбранный сценарий: аккаунт пережил штатную замену пода при доступном прежнем хранилище.
Эта проверка не заменяет тестирование резервной копии и восстановления после потери диска или узла. Она не проверяет все пользовательские файлы и не подтверждает высокую доступность. Вход также не доказывает неизменность WEBUI_SECRET_KEY: за сохранение ключа в open-webui-auth отвечает оператор.
Если результат отличается от ожидаемого, найдём причину по таблице ниже. Переустанавливать релиз поверх существующего не нужно.
Если запуск или повторный вход не удался
Выберите наблюдаемую ошибку и соответствующую проверку:
| Наблюдение | Что проверить и сделать |
|---|---|
PVC или Pod долго остаётся в статусе Pending | Проверьте события через describe pvc и describe pod: хватает ли квот в пространстве имён, доступен ли провижинер выбранного StorageClass, нет ли ограничений топологии узлов или нехватки CPU/памяти. Помните, что при режиме WaitForFirstConsumer том привязывается только вместе с планированием пода. Не меняйте StorageClass или права доступа наугад, согласуйте причину с администратором. |
Статус ImagePullBackOff или ошибка инициализации в copy-app-data | Для ImagePullBackOff проверьте в событиях пода доступность реестра ghcr.io из кластера и точность тега v0.12.0. Если не завершился init-контейнер copy-app-data, посмотрите его журнал и уточните у оператора политику прав файловой системы на томе CSI (не используйте chmod 777 для обхода проблем с правами). |
Статус CreateContainerConfigError или жалоба на отсутствующий Secret | Попросите оператора сверить наличие объекта Secret open-webui-auth и точное имя ключа WEBUI_SECRET_KEY в пространстве имён open-webui-course. Не выводите секретное значение на экран и не генерируйте новый ключ для уже созданной базы данных. |
CrashLoopBackOff, не проходит readinessProbe или истёк таймаут helm install | Проверьте helm status, события пода и последние строки журнала контейнера open-webui. При первом старте приложение может подгружать вспомогательные ресурсы. Статус контейнера Running сам по себе не заменяет готовность /ready (проверку завершения старта и ответа базы данных). |
Ошибка Address already in use, Service не найден или после rollout restart перестал открываться интерфейс | Проверьте, не остался ли во втором терминале старый процесс port-forward, сверьте переменные CTX, NS и имя сервиса open-webui-course. После каждой замены пода перезапускайте команду port-forward во втором терминале. Если порт 13000 на компьютере занят другой программой, измените только левое число в паре портов (например, 13001:80) и откройте соответствующий локальный адрес. |
| После замены пода снова открылась страница создания первого администратора | Остановитесь и не создавайте новую учётную запись. Проверьте вместе с оператором, что вы подключены к тому же контексту CTX и пространству имён open-webui-course, что к поду смонтирован прежний PVC open-webui-course с тем же томом VOLUME, а объект Secret open-webui-auth не изменялся. |
Диагностические команды выполняем в первом терминале, где заданы CTX, NS и SELECTOR. Выбирайте команды по своей ошибке, весь блок подряд запускать не нужно. Вместо POD_NAME_FROM_GET подставьте имя текущего пода из вывода первой команды:
Урок завершён, если под получил новый UID, у PVC сохранились прежние UID и VOLUME, а после повторного запуска port-forward вы вошли в прежний аккаунт через http://127.0.0.1:13000. При этих условиях проверен повторный доступ к выбранной учётной записи после штатной замены пода с прежним хранилищем.
Подключение модели, общий адрес для команды и регулярное резервное копирование томов требуют отдельных действий.

