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

Развёртывание

Выбор способа развёртывания

Provisa поддерживает шесть способов развёртывания. Выбирайте, исходя из аудитории и эксплуатационного контекста:

Способ Артефакт или скрипт Лучше всего подходит для
Разработка start-ui.sh Разработка из исходников, оценка с полным набором демонстрационных данных
Установщик для macOS Provisa-<version>-macOS.dmg Рабочие станции разработчиков, оценка
Установщик для Windows Provisa-<version>-windows-x64.exe Рабочие станции разработчиков, оценка
Linux AppImage Provisa.AppImage Локальные серверы, облачные виртуальные машины, изолированные окружения
Облачные ВМ (AWS) terraform/deploy.sh Многоузловое облачное развёртывание с балансировщиками нагрузки
Kubernetes helm/provisa/ Команды, уже эксплуатирующие K8s

Виртуальные машины или Kubernetes

Оба варианта подходят для продакшена. Путь с ВМ и AppImage проще: не нужно готовить кластер, не нужно настраивать политики CNI или RBAC, а AppImage полностью самодостаточен. Он естественно вписывается в существующие средства управления серверами (Ansible, Puppet, агенты Datadog, форвардеры Splunk и т. д.).

Выбирайте Kubernetes, только если ваша команда уже эксплуатирует кластер K8s и хочет, чтобы Provisa вписался в этот порядок работы (постепенные развёртывания, HPA, единая наблюдаемость). Возможности одинаковы; Kubernetes добавляет операционную нагрузку.

Получение образов и сканирование безопасности

Любому производственному пути нужны артефакты Provisa до того, как сможет выполниться развёртывание. «Air-gapped» описывает то, что происходит при установке на целевой машине, поэтому артефакты получают заранее.

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

Путь AppImage: Скачайте его со страницы релизов на GitHub и скопируйте на целевую машину. AppImage упаковывает каждый образ компонента как tarball внутри файловой системы squashfs, которую большинство сканеров реестров не могут проверить на месте. Запросите у вашей команды Provisa дайджесты образов компонентов, чтобы сверить их со своим сканером самостоятельно.

Путь Terraform: Загрузите AppImage в S3 до запуска terraform/deploy.sh. Узлы EC2 скачивают его при загрузке через свою роль IAM, поэтому им нужен исходящий доступ к S3, напрямую или через шлюзовой endpoint VPC. Применяйте ту же политику сканирования, что и для пути AppImage.

Путь Helm / Kubernetes: Загрузите отдельные образы в реестр, доступный кластеру. Этот путь лучше всего сочетается со сканированием на уровне реестра (Prisma Cloud, Aqua, Trivy, AWS Inspector), потому что образы — объекты, которые сканеры уже понимают. Для изолированного кластера зеркалируйте образы во внутренний реестр и переопределите ссылки в values.yaml.


Разработка (из исходников)

Это самый простой способ запустить Provisa из исходников. Одна команда поднимает всю инфраструктуру, серверный API и сервер разработки для интерфейса. Ctrl+C корректно всё останавливает.

Предварительные требования: Docker Desktop, Node.js, виртуальное окружение Python в .venv/

./start-ui.sh

Что он делает:

  • Запускает docker-compose.core.yml + docker-compose.dev.yml (все основные и демонстрационные службы) и ждёт, пока они станут работоспособными
  • Наполняет Kafka демонстрационными данными
  • Синхронизирует зависимости Python из .venv/
  • Запускает серверный API на порту 8001 (журналы в .logs/server.log)
  • Запускает сервер разработки Vite для интерфейса на порту 3000
  • Печатает адреса и ждёт; Ctrl+C останавливает всё и разбирает compose
Backend: http://localhost:8001
UI:      http://localhost:3000

Параметры:

--reset-volumes — выполняет docker compose down -v перед запуском, уничтожая все тома Docker (данные PostgreSQL, объекты MinIO, состояние Redis и т. д.). Используйте, когда нужно начать полностью с нуля: после изменения схемы во время разработки или когда Docker упал и оставил тома повреждёнными. Все данные будут потеряны.

--observability — добавляет полную инструментацию трассировки и метрик. Скачивает Java-агент OpenTelemetry и правит jvm.config Trino, чтобы тот его загрузил, инструментирует серверную часть Provisa экспортом OTLP и запускает коллектор OTel, Prometheus, Tempo и Grafana (http://localhost:3100). Правка jvm.config автоматически откатывается по Ctrl+C.

Ручные шаги (только серверная часть, без интерфейса)

Если вам нужен только API:

  1. Установите Docker Desktop
  2. Запустите основные службы:
docker compose -f docker-compose.core.yml up -d
  1. Запустите API:
uvicorn main:app --reload --port 8001
  1. Проверьте: curl http://localhost:8001/health

Полный стек (Provisa в контейнере)

Чтобы запустить API как контейнер, а не на хосте:

docker compose -f docker-compose.core.yml -f docker-compose.app.yml up -d

Службы

Основные (docker-compose.core.yml) — требуются всегда:

Служба Порт Назначение
PostgreSQL 5432 Метаданные конфигурации и каталог Iceberg
PgBouncer 6432 Пул соединений
Федеративный движок 8080 Федерация запросов
Redis 6379 Кеш результатов запросов
MinIO 9000/9001 S3-совместимое объектное хранилище

Демонстрационные (docker-compose.dev.yml) — необязательные, включаются start-ui.sh:

Служба Порт Назначение
MongoDB 27017 Демонстрационный источник NoSQL
Kafka 9092 Демонстрационный потоковый источник
Schema Registry 8081 Демонстрационное управление схемами Avro и Protobuf
Debezium — Демонстрационный коннектор CDC
Elasticsearch 9200 Демонстрационный поисковый источник
Neo4j 7474/7687 Демонстрационный графовый источник
Fuseki 3030 Демонстрационное хранилище триплетов SPARQL
OpenTelemetry Collector — Сбор трассировок (с --observability)
Prometheus 9090 Метрики (с --observability)
Tempo — Хранение трассировок (с --observability)
Grafana 3100 Дашборды (с --observability)

Хранилища, федеративный движок и эти службы телеметрии публикуются на PROVISA_STORE_BIND_IP (127.0.0.1, если не задано), с паролями, сгенерированными для развёртывания. См. Укрепление развёртывания.

Бэкенд телеметрии (otlp2sql)

Стек --observability, описанный выше (Collector → Tempo/Prometheus/Grafana), — это один путь телеметрии. Другой — otlp2sql (provisa.observability.otlp2sql): приёмник OTLP/HTTP, который пишет трассировки, метрики и журналы в базу данных SQL, выбранную URL-адресом SQLAlchemy, извлекая атрибуты спанов provisa.* при приёме, так что отдельное задание уплотнения не требуется. Записи выполняются пакетами (OTLP2SQL_BATCH_MAX_ROWS, по умолчанию 1000; OTLP2SQL_BATCH_MAX_SECS, по умолчанию 2 с).

Телеметрия получает собственное хранилище, отдельное от базы данных плоскости управления. Выберите бэкенд через PROVISA_OPS_DB_URL:

PROVISA_OPS_DB_URL Бэкенд Примечания
(не задано) выделенная DuckDB в ~/.provisa/telemetry/ по умолчанию; ни сервера, ни Docker
clickhouse+native://user@host/otel ClickHouse приём с высокой частотой и автоматическими фоновыми слияниями
postgresql+psycopg2://user@host/otel PostgreSQL умеренный объём
trino://user@host:8080/otel Trino / Iceberg технически работает, не рекомендуется — см. ниже

С trino://: диалект Trino для SQLAlchemy выдаёт корректный DDL Trino и INSERT, поэтому может служить бэкендом otlp2sql, но мы рекомендуем его только для низкой скорости приёма. Каждый сброс пакета превращается в распределённый INSERT Trino плюс снимок Iceberg, поэтому высокочастотная телеметрия порождает множество мелких файлов и снимков и всё равно требует периодического ALTER TABLE ... EXECUTE optimize / expire_snapshots, которые otlp2sql не выполняет. К тому же это ставит движок запросов на горячий путь приёма.

Для больших объёмов телеметрии в Trino и Iceberg используйте вместо этого otlp2parquet: он пишет parquet в объектное хранилище, минуя Trino, а запланированное уплотнение в Trino сворачивает сырые файлы в живые таблицы Iceberg. Если нужен один движок, справляющийся и с высокой частотой приёма, и с уплотнением, предпочтите ClickHouse.

Направьте экспортёры OTLP приложения и Trino (OTEL_EXPORTER_OTLP_ENDPOINT) на конечную точку otlp2sql и зарегистрируйте домен ops для того же PROVISA_OPS_DB_URL, чтобы он читал то, что записал приёмник.


Установщик для macOS

Для рабочих станций разработчиков и оценки. Полностью автономен; после скачивания интернет не нужен.

Базовый установщик представляет собой нативная установка: движок федерации DuckDB, встроенная плоскость управления PostgreSQL (pgserver) и кэш в памяти (fakeredis), без Docker, ВМ, Trino, Redis и MinIO. Движок федерации выбирается в мастере: DuckDB (нативный, по умолчанию), Trino в Docker или внешний движок. Наблюдаемость — это постоянно включённая самотелеметрия, видимая в Admin; Docker-стек из collector, Prometheus и Grafana — отдельная необязательная демонстрация, которая её не включает и не выключает. Пакет демо-данных необязателен и по умолчанию выключен. Trino, Docker-стек наблюдаемости и демо — тяжёлые дополнения. Сначала они ищутся локально (каталог рядом с установщиком, подключённые тома, ~/Downloads), и только потом скачиваются из релиза на GitHub, чтобы компании могли заранее подготовить tarball-архивы для изолированных установок.

Шаги

  1. Скачайте Provisa-<version>-macOS.dmg со страницы релизов GitHub
  2. Откройте DMG и перетащите Provisa.app в /Applications
  3. Дважды щёлкните Provisa.app. Настройка при первом запуске выполняется один раз, и мастер предлагает описанный выше выбор движка, наблюдаемости и демонстрации
  4. Откройте терминал:
provisa start    # start all services
provisa status   # confirm all services are running
provisa open     # open the UI in the browser

Сохранность данных

Все данные хранятся в ~/.provisa/. Чтобы удалить всё: provisa uninstall.


Установщик для Windows

Для рабочих станций разработчиков и оценки. Полностью автономен; после скачивания интернет не нужен.

Как и в macOS, базовый установщик для Windows — это нативный уровень: автономная среда выполнения Python + wheel provisa + DuckDB/pg_duckdb + встроенная плоскость управления PostgreSQL (pgserver), без Docker, без виртуальных машин и без образов контейнеров. Федеративный движок (Trino), стек наблюдаемости и набор демонстрационных данных добавляются позже отдельными послойными установщиками, по порядку: установщик Container (Provisa-Container-<version>.exe, добавляющий WSL2 + containerd + Trino), затем установщик Obs (требует уровня контейнеров) и затем установщик Demo (требует Core + Obs). Подсказки при первом запуске объясняют, как инициализировать федеративный движок, запустив установщик Container.

Шаги

  1. Скачайте Provisa-<version>-windows-x64.exe со страницы релизов GitHub
  2. Запустите установщик. Права администратора ему не нужны, а установка выполняется в %LOCALAPPDATA%\Programs\Provisa\
  3. Откройте Provisa First Launch из меню «Пуск». Нативная настройка выполняется один раз и печатает подсказки по дальнейшим шагам для послойных дополнений
  4. Откройте новый терминал:
provisa status
provisa open

Сохранность данных

Все данные хранятся в %USERPROFILE%\.provisa\.


Linux AppImage — одноузловая или многоузловая ВМ

Что это

Provisa.AppImage — один самодостаточный исполняемый файл, включающий:

  • Демон Docker без root-прав (dockerd-rootless.sh + rootlesskit), поэтому системный Docker и root не нужны
  • Все tar-архивы образов контейнеров (PostgreSQL, PgBouncer, MinIO, Redis, федеративный движок, API Provisa)
  • Обёртку CLI Provisa и скрипт настройки при первом запуске

Образ Provisa собирается при упаковке, и исходный код Python в него никогда не входит.

Когда использовать

  • Локальное «железо» или ВМ (один или несколько узлов)
  • Облачные ВМ без кластера K8s
  • Изолированные окружения
  • Когда нужна эксплуатация проще, чем в Kubernetes

Шаги — один узел

  1. Скачайте Provisa.AppImage со страницы релизов GitHub и перенесите на целевую машину
  2. Сделайте файл исполняемым:
chmod +x Provisa.AppImage
  1. Запустите настройку первого запуска:
./Provisa.AppImage
  1. Мастер настройки спрашивает:
  2. Роль → выберите primary
  3. Бюджет ОЗУ → сколько оперативной памяти выделить (0 = вся доступная); определяет число рабочих узлов Trino
  4. Имя узла → объявляемый адрес этого узла
  5. Порт API → по умолчанию 8000
  6. Настройка загружает все образы контейнеров (~2–5 минут), записывает конфигурацию и запускает службы
  7. Проверьте:
provisa status
curl -k https://localhost:8000/health   # -k: the node generates a self-signed certificate unless PROVISA_TLS_CERT/KEY supply one

Шаги — несколько узлов (главный)

Сначала выполните эти шаги на главном узле. Вторичные узлы настраиваются после того, как главный уже работает.

  1. Скачайте Provisa.AppImage и перенесите на главную машину
  2. Откройте нужные порты в межсетевом экране только для вторичных узлов (они будут подключаться к ним входящими соединениями):
Порт Служба
5432 PostgreSQL
6379 Redis
9000 MinIO
8080 Координатор федеративного движка
8000 API Provisa
  1. Сделайте файл исполняемым и запустите с хранилищами, опубликованными на частном адресе узла, по которому к ним обращаются вторичные узлы. Узел без вторичных узлов публикует их только на 127.0.0.1:
chmod +x Provisa.AppImage
PROVISA_STORE_BIND_IP=<this node's private IP> ./Provisa.AppImage
  1. Мастер настройки спрашивает:
  2. Роль → выберите primary
  3. Бюджет ОЗУ, имя узла, порт API → отвечайте так же, как для одного узла
  4. После завершения настройки запишите частный IP-адрес этой машины. Он нужен вторичным узлам, как и учётные данные хранилищ, сгенерированные главным узлом: ~/.provisa/store-credentials.env (PROVISA_PG_PASSWORD, PROVISA_REDIS_PASSWORD, PROVISA_MINIO_ROOT_PASSWORD, PROVISA_GRAFANA_ADMIN_PASSWORD, PROVISA_TRINO_SHARED_SECRET). Скопируйте этот файл на каждый вторичный узел по защищённому каналу
  5. Мастер печатает блок upstream для nginx; сохраните его для конфигурации балансировщика нагрузки
  6. Проверьте:
provisa status
curl -k https://localhost:8000/health   # -k: the node generates a self-signed certificate unless PROVISA_TLS_CERT/KEY supply one

Шаги — несколько узлов (каждый вторичный)

Повторите эти шаги на каждом дополнительном узле после того, как главный узел работает и доступен.

  1. Скачайте Provisa.AppImage и перенесите на вторичную машину
  2. Убедитесь, что вторичный узел достаёт до главного:
curl -k https://<primary-ip>:8000/health
  1. Сделайте файл исполняемым и запустите с учётными данными хранилищ главного узла в окружении (файл, скопированный с главного узла). Вторичный узел без них не запускается:
chmod +x Provisa.AppImage
set -a; . ./store-credentials.env; set +a
./Provisa.AppImage
  1. Мастер настройки спрашивает:
  2. Роль → выберите secondary
  3. IP главного узла → введите IP-адрес главного узла (связность проверяется вживую)
  4. Бюджет ОЗУ, имя узла, порт API → отвечайте как выше
  5. Настройка загружает сокращённый набор образов (без PostgreSQL, PgBouncer, MinIO и Redis, которые работают только на главном узле), запускает API Provisa и рабочий узел федеративного движка
  6. Проверьте:
provisa status
curl -k https://localhost:8000/health
  1. Добавьте этот узел в upstream балансировщика нагрузки

Топология «главный — вторичные»

Главный узел выполняет все службы в единственном экземпляре:

Служба Почему в единственном экземпляре
PostgreSQL Общая схема, конфигурация приложения, семантическая модель
Redis Общий кеш результатов запросов и состояние подписок
MinIO Общее объектное хранилище для перенаправленных результатов и снимков материализованных представлений
Координатор федеративного движка Здесь регистрируются все рабочие узлы (главный и вторичные)

Вторичные узлы выполняют только:

  • API Provisa — без состояния; при запуске читает всю конфигурацию из PostgreSQL на главном узле
  • Рабочий узел федеративного движка — сам регистрируется у координатора на главном узле

Всё состояние приложения проходит через PostgreSQL главного узла. Ручная синхронизация не требуется.


Неинтерактивный (автоматизированный) первый запуск

Для Terraform, cloud-init или Ansible передайте флаги вместо ответов на вопросы:

# Primary
./Provisa.AppImage --non-interactive --role primary --ram-gb 32

# Secondary
./Provisa.AppImage --non-interactive --role secondary --primary-ip 10.0.0.10 --ram-gb 32

Неинтерактивный режим устанавливает юнит systemd (/etc/systemd/system/provisa.service) для запуска при загрузке.

Флаг Описание
--non-interactive Пропустить все вопросы; установить юнит systemd
--role primary\|secondary Роль узла
--primary-ip <ip> IP-адрес главного узла (обязателен для вторичного)
--ram-gb <n> Сколько ОЗУ выделить (0 = вся доступная)

Развёртывание на облачных ВМ — Terraform (AWS)

Одна интерактивная команда разворачивает полный многоузловой кластер Provisa в AWS: VPC, группы безопасности, экземпляры EC2, ALB и NLB.

Файлы

Файл Назначение
terraform/deploy.sh Интерактивная обёртка — собирает параметры, проверяет учётные данные, пишет terraform.tfvars, выполняет apply
terraform/aws/variables.tf Все определения переменных со значениями по умолчанию
terraform/aws/main.tf VPC, подсети, группы безопасности, IAM, EC2, ALB, NLB
terraform/aws/outputs.tf Адреса конечных точек и IP-адреса узлов

Шаги

  1. Скачайте Provisa.AppImage со страницы релизов GitHub

  2. Загрузите его в бакет S3 в своей учётной записи AWS:

aws s3 cp Provisa.AppImage s3://<your-bucket>/releases/Provisa.AppImage
  1. Убедитесь, что учётные данные AWS доступны в вашей оболочке (любым способом):
  2. Переменные окружения: AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY
  3. Именованный профиль: export AWS_PROFILE=my-profile
  4. Активная сессия SSO: aws sso login

  5. (Необязательно) Если нужен доступ к узлам по SSH, создайте пару ключей EC2 в целевом регионе и запишите её имя

  6. Запустите обёртку развёртывания:

bash terraform/deploy.sh
  1. Ответьте на вопросы мастера (см. справочную таблицу ниже). Скрипт проверяет наличие AppImage в S3, прежде чем продолжить, и прерывается, если файла нет

  2. Просмотрите сводку развёртывания и подтвердите

  3. Terraform разворачивает всю инфраструктуру (~5–10 минут). После apply скрипт печатает:

api_endpoint      = "https://<alb-dns>:8000"
protocol_endpoints = { flight = "<alb-dns>:8815", ... }
primary_ip        = "10.0.x.x"
secondary_ips     = ["10.0.x.x", ...]
  1. (Необязательно) Направьте записи DNS на DNS-имена ALB и NLB

  2. Проверьте:

    curl http://<api_endpoint>/health
    

Вопросы мастера

Вопрос По умолчанию Примечания
Облачный провайдер — Только AWS
Учётные данные AWS — Сначала проверяет активную сессию
Регион us-east-1
Количество узлов 2 1 = только главный, без балансировщика; 2 и более = главный + вторичные + ALB/NLB
Тип экземпляра m7i.2xlarge См. руководство по подбору размера ниже
Размер корневого тома 100 GB На узел
Бюджет ОЗУ 0 (вся ОЗУ) Определяет число рабочих узлов Trino на узел
Бакет S3 — Проверяется вживую перед продолжением
Ключ S3 releases/Provisa.AppImage
Доступ по SSH Нет Требует имени существующей пары ключей и административного CIDR
CIDR для VPC 10.0.0.0/16

Руководство по подбору размера экземпляра

Тип vCPU ОЗУ Рабочих узлов Trino на узел Сценарий использования
m7i.xlarge 4 16 ГБ 0 Разработка и небольшие наборы данных
m7i.2xlarge 8 32 ГБ 1 Небольшой продуктив
m7i.4xlarge 16 64 ГБ 2 Средний продуктив
m7i.8xlarge 32 128 ГБ 4 Крупный продуктив

Все узлы отдают рабочие процессы одному координатору на главном узле. Кластер из трёх узлов m7i.4xlarge даёт в сумме 6 рабочих узлов Trino.

Что разворачивается

  • VPC с двумя публичными подсетями в двух зонах доступности
  • Группы безопасности: группа балансировщиков (публичный входящий трафик на 8000/8815), группа узлов (балансировщик → узлы, внутрикластерный трафик, необязательный SSH)
  • Роль IAM и профиль экземпляра с правом S3 GetObject на бакет с AppImage
  • Главный экземпляр EC2 — выполняет первый запуск в режиме --non-interactive --role primary
  • Вторичные экземпляры EC2 (node_count − 1) — выполняют первый запуск в режиме --non-interactive --role secondary --primary-ip <primary private IP>; зависят от того, что главный узел завершил настройку первым
  • ALB на порту 8000 — HTTP API, проверка работоспособности по /health
  • NLB на порту 8815 — Arrow Flight и gRPC
  • Оба балансировщика подключаются ко всем узлам

Контрольный список предварительных требований

  • [ ] Права IAM: полный доступ к EC2, ELB и VPC, создание ролей IAM, S3 GetObject на бакет с AppImage
  • [ ] Provisa.AppImage загружен в S3
  • [ ] У узлов EC2 есть исходящий доступ к S3 (прямой интернет или шлюзовая конечная точка S3 в VPC)
  • [ ] Пара ключей EC2 существует в целевом регионе (если нужен SSH)
  • [ ] Terraform ≥ 1.5 установлен локально
  • [ ] Записи DNS для ALB и NLB спланированы (необязательно, но рекомендуется)
  • [ ] Сертификат ACM готов, если требуется HTTPS (в базовый Terraform не входит)

Секреты

Пароли встроенных хранилищ (PostgreSQL, Redis, MinIO, администратор Grafana) и общий секрет кластера Trino генерирует Terraform (random_password) и передаёт каждому узлу, который хранит их в своём файле окружения systemd с режимом 600. Они хранятся в состоянии Terraform, поэтому защищайте состояние так же, как сами пароли. Без Terraform запуск на каждом узле генерирует их в ~/.provisa/store-credentials.env. Остальные учётные данные AppImage генерирует при первом запуске и записывает в ~/.provisa/config.yaml на каждом узле. Для продуктива получите административный токен с главного узла после развёртывания:

ssh ubuntu@<primary-public-ip> cat ~/.provisa/config.yaml | grep admin_token

Kubernetes и Helm

Когда использовать

Ваша команда уже эксплуатирует кластер Kubernetes и хочет, чтобы Provisa участвовала в этой эксплуатационной модели. Если вы оцениваете Provisa или разворачиваете её локально без готового кластера, путь AppImage проще.

Примечание: AppImage Provisa не может работать внутри пода Kubernetes. Ему нужны FUSE и rootless-демон Docker, а стандартные профили безопасности подов не допускают ни того, ни другого.

Шаги

  1. Проверьте доступ к кластеру:
kubectl cluster-info
  1. Скачайте и зеркалируйте образы в свой внутренний реестр (требуется для изолированных или сканируемых окружений; пропустите, если тянете напрямую из публичных реестров):
Образ Для чего используется
provisa/provisa:<version> API Provisa
trinodb/trino:480 Координатор и рабочие узлы федеративного движка
postgres:16 PostgreSQL внутри кластера (если postgresql.enabled)
edoburu/pgbouncer:latest PgBouncer внутри кластера (если pgbouncer.enabled)
redis:7.2 Redis внутри кластера (если redis.enabled и не задан redis.host)
minio/minio:latest MinIO внутри кластера (если minio.enabled)

Для окружений со сканированием реестра: - Отправьте каждый образ в промежуточный реестр - Запустите свой сканер (Prisma Cloud, Aqua, Trivy, AWS Inspector) и получите утверждение - Продвиньте образы в производственный внутренний реестр

  1. Решите до установки:
  2. PostgreSQL — внутри кластера (postgresql.enabled: true) или внешняя управляемая (postgresql.host)? Для продуктива рекомендуется внешняя
  3. Redis — внутри кластера или внешний (redis.host)?
  4. Учётные данные хранилищ — создайте Secret, имя которого задано в credentials.existingSecret, с ключами pg-password, redis-password, minio-access-key, minio-secret-key, grafana-admin-password и trino-shared-secret. Чарт не задаёт собственного пароля и без него не рендерится
  5. TLS — включён по умолчанию (tls.enabled: true): создайте Secret типа kubernetes.io/tls, имя которого задано в tls.secretName, или задайте tls.enabled: false
  6. MinIO или S3 — MinIO внутри кластера или нативный S3? Для AWS используйте S3 с ролью IAM
  7. Секреты — для оценки передавайте через --set; для продуктива используйте External Secrets или Vault Agent
  8. Кеш координатора Trino — том 1Gi, запрашиваемый по умолчанию и смонтированный в /data/trino/cache (trino.coordinator.cache.persistence: enabled, size, storageClass). Там хранятся результаты describe источника Salesforce, чтобы перезапущенный координатор не тратил снова квоту API организации на его описание. Отключайте его, только если ни одному источнику он не нужен

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

kubectl create namespace provisa
kubectl create secret generic provisa-master-key --namespace provisa \
  --from-literal=master-key="$(openssl rand -base64 32)"

Храните копию ключа вне кластера. Хранилище, записанное ключом, который потом утерян, открыть нельзя. Альтернатива Secret — постоянный том данных (encryption.dataVolume.enabled=true), где продукт хранит созданный им ключ; см. encryption в values.yaml.

  1. Установите чарт:
helm install provisa helm/provisa/ \
  --set encryption.existingSecret=provisa-master-key \
  --set auth.provider=oidc \
  --set auth.oidc.issuerUrl=https://login.example.com/realms/main \
  --set auth.oidc.clientId=provisa \
  --set config.pgPassword=<password> \
  --set config.adminToken=<token> \
  --set s3.endpoint=https://s3.amazonaws.com \
  --set s3.bucket=my-provisa-results \
  --namespace provisa --create-namespace

Чарт не рендерится, пока не выбран auth.provider: oidc (корпоративный издатель OpenID Connect), saml (auth.saml.idpMetadataUrl и auth.saml.publicUrl), ldap (auth.ldap.*), local (только аварийная учётная запись, auth.breakGlass.*) или none (без аутентификации, только для разработки). Все учётные данные берутся из Secret Kubernetes; ldap, saml и local также требуют auth.sessionSecret.existingSecret — ключ, которым подписываются сеансы браузера. См. auth в values.yaml.

Координатор Trino выполняет инструкции каждой организации в её собственной группе ресурсов, global.tenant-<org>, из файла групп ресурсов, поставляемого с чартом. Инструкции, проходящие через прокси Arrow Flight, используют одну группу, global.flight: прокси открывает собственное подключение к Trino и не может передать организацию.

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

--set image.repository=harbor.internal.example.com/provisa/provisa \
--set image.tag=1.2.3 \
--set trino.image.repository=harbor.internal.example.com/trinodb/trino \
--set trino.image.tag=480
  1. Убедитесь, что поды запущены:
kubectl get pods -n provisa
  1. Проверьте API:
kubectl port-forward svc/provisa 8000:8000 -n provisa
curl http://localhost:8000/health
  1. (Необязательно) Включите ingress для внешнего доступа: задайте ingress.enabled: true и настройте свой контроллер ingress

Контрольный список предварительных требований

  • [ ] Kubernetes 1.26+, Helm 3.12+
  • [ ] Класс хранилища, поддерживающий PVC с ReadWriteOnce (для служб с состоянием внутри кластера)
  • [ ] Образы доступны кластеру (публичный или внутренний реестр)
  • [ ] Конечная точка PostgreSQL и учётные данные (если внешняя)
  • [ ] Конечная точка Redis и учётные данные (если внешний)
  • [ ] Бакет S3 и учётные данные или роль IAM
  • [ ] Выбран административный токен
  • [ ] Настроен контроллер ingress (если нужен внешний доступ)

Основные значения

Значение По умолчанию Описание
replicaCount 2 Реплики API Provisa (без состояния)
config.pgHost postgres Хост PostgreSQL
config.pgPassword Пароль PostgreSQL
config.adminToken Bearer-токен административного API
redis.enabled true Развернуть StatefulSet Redis внутри кластера
redis.host "" Задайте, чтобы использовать внешний Redis
redis.port 6379
credentials.existingSecret Secret с паролями хранилищ (обязателен)
tls.enabled true Обслуживать каждую конечную точку по TLS из tls.secretName
redis.tls false
trino.enabled true Развернуть федеративный движок
trino.workers 2 Реплики рабочих узлов федеративного движка
trino.internalTls false Шифрует трафик координатор–рабочие узлы сертификатом, сгенерированным chart; замедляет запросы с интенсивным обменом данными от 10% до более чем 100%
postgresql.enabled true Развернуть PostgreSQL внутри кластера
postgresql.host "" Задайте, чтобы использовать внешнюю PostgreSQL
minio.enabled true Развернуть MinIO внутри кластера
s3.endpoint URL S3-совместимой конечной точки
s3.bucket provisa-results Бакет для перенаправления больших результатов
ingress.enabled false Включить ingress

Масштабирование

kubectl scale deployment/provisa --replicas=5 --namespace provisa

Воркеры движка федерации масштабируются независимо, и больше воркеров означают больше пропускной способности и больше одновременных запросов.

Обновление конфигурации

kubectl create configmap provisa-config \
  --from-file=config.yaml=./config.yaml \
  --namespace provisa --dry-run=client -o yaml | kubectl apply -f -
kubectl rollout restart deployment/provisa --namespace provisa

Высокая доступность и восстановление

Provisa применяет двухуровневую модель восстановления во всех режимах развёртывания:

  • Уровень 1 — временные ошибки. Операции чтения повторяются до 30 секунд при временных ошибках, с экспоненциальной задержкой и полным разбросом. Бюджет настраивается через PROVISA_RETRY_BUDGET_SECS. Операции записи никогда не повторяются внутренне, а ошибки памяти никогда не считаются повторяемыми.
  • Уровень 2 — отказ компонента. Внутренний наблюдатель за движком обнаруживает и перезапускает отказавшие программные компоненты в течение 2–3 минут.

Отказы машин и кластеров остаются на ответственности оператора. Чтобы выдерживать потерю узла, разверните избыточные узлы и балансировщик нагрузки (пути Terraform и Helm выше).

Таблица телеметрии без метаданных

На движке Trino таблицы телеметрии (otel.signals.traces, metrics, logs) — это таблицы Iceberg. Регистрация каждой — это строка в базе данных плоскости управления, а её метаданные и данные — файлы в бакете телеметрии. Если бакет отдаётся без этих файлов, а база данных по-прежнему хранит регистрации, любой запрос к таблице завершается ошибкой ICEBERG_MISSING_METADATA. Так бывает, если диск бакета ещё не был смонтирован при запуске хранилища объектов, или если бакет очистили или заменили.

В этом случае Provisa ничего не меняет. Каждый запуск уплотнения пишет в журнал ERROR с названием таблицы и расположением метаданных, которые Trino не смог прочитать (otel.signals.traces is registered but its metadata cannot be read …), пропускает этот сигнал и оставляет его исходные файлы в бакете для следующего запуска. Остальные сигналы уплотняются как обычно. При запуске таблица так же исключается из проверок схемы.

Восстановите её вручную в таком порядке:

  1. Выясните, существуют ли ещё метаданные. ERROR называет расположение. На координаторе Terraform (GCP) проверьте, что диск хранилища объектов смонтирован (findmnt /var/lib/provisa-object-store) и что контейнер MinIO запустился после монтирования. MinIO, запущенный раньше, отдаёт пустой каталог под точкой монтирования; перезапустите его после монтирования диска, и таблица снова читается с сохранённой историей.
  2. Если файл метаданных существует, но регистрация указывает в другое место, зарегистрируйте таблицу заново по её расположению:
CALL otel.system.register_table(schema_name => 'signals', table_name => 'traces', table_location => 's3://<bucket>/warehouse/signals/<table directory>')

Сначала отмените устаревшую регистрацию, если имя занято (CALL otel.system.unregister_table(schema_name => 'signals', table_name => 'traces')). 3. Если файлы бакета действительно утрачены, отмените регистрацию таблицы. Следующий запуск уплотнения создаст её заново, пустой. Сигналы, которые она хранила, прочитать снова нельзя.

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

Зависимости федеративных движков

Федеративным движкам хранилищ нужны пакеты Python и системные компоненты. Пакеты Python объявлены в pyproject.toml и ставятся обычным pip install provisa или pip install -e ., поэтому ни одному движку хранилища не нужен дополнительный extra.

Системные компоненты (драйвер ODBC, облачные CLI, ключи сервисных аккаунтов) устанавливаются отдельно.

Пакеты Python (уже в основных зависимостях)

Пакет Движок Назначение
databricks-sql-connector Databricks Подключение к SQL-хранилищу; Arrow Cloud Fetch
snowflake-connector-python[pandas] Snowflake Подключение и нативный для Arrow fetch_arrow_table
google-cloud-bigquery BigQuery Выполнение запросов
google-cloud-bigquery-storage BigQuery Storage Read API для нативных для Arrow чтений
google-cloud-storage BigQuery Промежуточное хранение в GCS для ссылок на внешние таблицы
pyodbc Fabric, Synapse Подключение по ODBC к конечным точкам T-SQL
azure-identity Fabric, Synapse Токен Azure AD через DefaultAzureCredential
clickhouse-connect ClickHouse Колоночные чтения по HTTP
protobuf>=6.33.5,<7 BigQuery, gRPC Закрепление совместимости — google-cloud-* и OTel используют общую среду выполнения protobuf; <7 удерживает их согласованными
grpcio-status<1.82 gRPC Согласовано с закреплением protobuf<7

Системные требования

Это не пакеты Python. Установите их на хост или в контейнер, где работает Provisa.

Microsoft Fabric и Azure Synapse (ODBC)

pyodbc подключается через Microsoft ODBC Driver for SQL Server (msodbcsql18). Установите драйвер на сам хост; pip его установить не может.

macOS:

brew install microsoft/mssql-release/msodbcsql18

Linux (Ubuntu/Debian):

curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
apt-get update && ACCEPT_EULA=Y apt-get install -y msodbcsql18

Provisa подхватывает драйвер автоматически. Чтобы переопределить имя драйвера (для нестандартных установок), задайте:

export PROVISA_MSSQL_ODBC_DRIVER="ODBC Driver 17 for SQL Server"

Аутентификация Azure AD (Fabric и Synapse)

Оба движка аутентифицируются через azure.identity.DefaultAzureCredential. DefaultAzureCredential проверяет источники учётных данных по порядку: переменные окружения, workload identity, managed identity, VS Code, az login и другие.

Для локальной разработки проще всего az login:

az login

В продакшене используйте управляемое удостоверение (на ВМ Azure или в AKS), которому не нужно управление учётными данными. Для аутентификации через service principal задайте:

export AZURE_TENANT_ID=<tenant>
export AZURE_CLIENT_ID=<app-id>
export AZURE_CLIENT_SECRET=<secret>

BigQuery (сервисная учётная запись)

google-cloud-bigquery использует Application Default Credentials. Для локальной разработки укажите файл ключа сервисной учётной записи:

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa-key.json

В продакшене на GCP (Cloud Run, GKE с Workload Identity, Compute Engine) библиотека сама подхватывает привязанный сервисный аккаунт, без переменной окружения.

Сервисной учётной записи требуются:

  • roles/bigquery.dataViewer — чтение данных
  • roles/bigquery.jobUser — выполнение запросов
  • roles/bigquery.dataEditor — создание внешних таблиц (для ATTACH)
  • roles/storage.objectViewer — чтение объектов GCS для внешних таблиц

Databricks (сертификат CA в окружениях с прокси для разработки)

Если Provisa работает за прокси, перехватывающим TLS (Charles, mitmproxy, корпоративные прокси), коннектор Databricks SQL может отклонить сертификат прокси. Передайте собственный набор CA:

export REQUESTS_CA_BUNDLE=/path/to/your/proxy-ca.pem

Коннектор Databricks наследует это от requests, поэтому отдельная переменная окружения для Databricks не нужна.

Контрольный список по каждому движку

Databricks

  • [ ] databricks-sql-connector установлен (по умолчанию)
  • [ ] URL движка с http_path: databricks://token:TOKEN@workspace.azuredatabricks.net?http_path=/sql/1.0/warehouses/xxx
  • [ ] Персональный токен доступа или токен субъекта-службы
  • [ ] REQUESTS_CA_BUNDLE задан, если используется прокси с перехватом TLS

Snowflake

  • [ ] snowflake-connector-python[pandas] установлен (по умолчанию)
  • [ ] URL движка: snowflake://user:pass@account.snowflakecomputing.com/database
  • [ ] account в PROVISA_ENGINE_URL или в federation_hints

BigQuery

  • [ ] google-cloud-bigquery, google-cloud-bigquery-storage, google-cloud-storage установлены (по умолчанию)
  • [ ] GOOGLE_APPLICATION_CREDENTIALS задан (разработка) или настроен workload identity (продуктив)
  • [ ] GOOGLE_CLOUD_PROJECT задан, если проект нельзя вывести из сервисной учётной записи
  • [ ] У сервисной учётной записи есть роли BigQuery Data Viewer и Job User

Microsoft Fabric

  • [ ] pyodbc и azure-identity установлены (по умолчанию)
  • [ ] Системный драйвер msodbcsql18 установлен
  • [ ] FABRIC_SQL_SERVER и FABRIC_DATABASE заданы
  • [ ] Аутентификация Azure AD: az login (разработка) или managed identity либо субъект-служба (продуктив)
  • [ ] FABRIC_WORKSPACE_ID задан, если используются ссылки на внешнее объектное хранилище

Azure Synapse

  • [ ] Те же требования к Python и системе, что и для Fabric
  • [ ] SYNAPSE_SQL_SERVER и SYNAPSE_DATABASE заданы
  • [ ] Та же настройка аутентификации Azure AD, что и для Fabric

ClickHouse

  • [ ] clickhouse-connect установлен (по умолчанию)
  • [ ] URL движка: clickhouse+http://user:pass@host:8123/database
  • [ ] secure: "true" в federation_hints для TLS (порт 8443)

Переменные окружения

Переменная По умолчанию Назначение
PG_PASSWORD Пароль PostgreSQL
PROVISA_CONFIG config/provisa.yaml Путь к файлу конфигурации
PROVISA_REDIRECT_ENABLED false Включить перенаправление больших результатов в S3
PROVISA_REDIRECT_THRESHOLD 1000 Порог по числу строк для перенаправления
PROVISA_REDIRECT_BUCKET provisa-results Бакет S3
PROVISA_REDIRECT_ENDPOINT URL S3-совместимой конечной точки
PROVISA_REDIRECT_TTL 3600 TTL предподписанного URL (в секундах)
REDIS_HOST localhost Хост Redis
REDIS_PORT 6379 Порт Redis
REDIS_PASSWORD Пароль Redis
REDIS_TLS false Включить TLS для Redis
TRINO_HOST localhost Хост координатора федеративного движка Trino
TRINO_PORT 8080 HTTP-порт координатора федеративного движка Trino
PROVISA_ENGINE duckdb Ключ активного федеративного движка; переопределяет сохранённую конфигурацию
PROVISA_ENGINE_URL URL подключения для движков, управляемых через URL (Databricks, Snowflake, ClickHouse, BigQuery, Fabric, Synapse, SQLAlchemy)
PROVISA_MATERIALIZE_URL Переопределение URL хранилища материализации; по умолчанию используется собственное хранилище движка
PROVISA_MSSQL_ODBC_DRIVER ODBC Driver 18 for SQL Server Имя драйвера ODBC для Fabric и Synapse
GOOGLE_APPLICATION_CREDENTIALS Путь к JSON-ключу сервисной учётной записи GCP (BigQuery)
GOOGLE_CLOUD_PROJECT Идентификатор проекта GCP (BigQuery; выводится из сервисной учётной записи, если не задан)
FABRIC_SQL_SERVER Имя узла конечной точки SQL-аналитики Microsoft Fabric
FABRIC_DATABASE Имя базы данных Fabric
FABRIC_WORKSPACE_ID GUID рабочей области Fabric (обязателен для ярлыков на внешнее объектное хранилище)
SYNAPSE_SQL_SERVER Имя узла выделенного пула SQL или бессерверного пула Azure Synapse
SYNAPSE_DATABASE Имя базы данных Synapse
AZURE_TENANT_ID Арендатор Azure AD (аутентификация субъектом-службой для Fabric и Synapse)
AZURE_CLIENT_ID Идентификатор клиента приложения Azure AD
AZURE_CLIENT_SECRET Секрет клиента приложения Azure AD
REQUESTS_CA_BUNDLE Путь к собственному набору CA (коннектор Databricks, TLS-прокси для разработки)

Команды CLI

provisa start              # Start all services
provisa stop               # Stop all services
provisa restart            # Restart
provisa status             # Show service health
provisa open               # Open the UI in the browser
provisa logs               # Tail service logs
provisa export             # Print current config as YAML to stdout
provisa export FILE        # Write current config as YAML to FILE
provisa import FILE        # Replace running config with YAML from FILE

Процесс продвижения конфигурации (dev → test → prod)

Все настройки, зависящие от окружения (строки подключения, секреты, порты), задаются в переменных окружения или в менеджере секретов, вне экспортируемой конфигурации. Экспортируемый YAML фиксирует вашу семантическую модель: источники, домены, роли и представления.

# On dev — export after making changes in the UI
provisa export > config.yaml
git add config.yaml && git commit -m "chore: update semantic model"
git push

# On test/prod — pull and import
git pull
provisa import config.yaml

См. также: Окружения — о том, как управлять именованными копиями вашей управляемой модели, изолированными по схемам.