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

Установка через Wizard

Wizard — официальный Go-инсталлер AppSec.AIGate, упакованный в Docker-образ. Управляет полным жизненным циклом установки: namespace, pull-secret, инфраструктура, продуктовые сервисы — в правильном порядке. Один и тот же бинарь обслуживает несколько продуктов; для AiGate образ собирается с PRODUCT=aigate.

Docker Compose

Установка пилот/демо на отдельном сервере через Docker Compose описана в разделе Установка и запуск. Этот раздел — про промышленное развёртывание в Kubernetes.


Способ доступа извне (exposure)

Wizard разделяет два независимых решения:

  • exposure — как внешний трафик попадает в сервисы. Единый источник правды: gateway | ingress | none.
  • auth.enabled — включён ли OIDC (Keycloak + Envoy SecurityPolicy). Ортогонален и учитывается только при exposure: gateway.

Трафик идёт через Envoy Gateway (Gateway API). Только этот режим поддерживает OIDC.

  • auth: false — Gateway/HTTPRoute без аутентификации (dev/smoke).
  • auth: true — Keycloak + OIDC SecurityPolicy, JWT во всех сервисах (production). Требует TLS-секрет и DNS на хосты.
preflight:gateway       проверка Envoy Gateway / Gateway API CRD
Phase 1     — postgres, redis, minio, keycloak (если auth), opa
Phase 1.1   — bootstrap: БД, бакет policies, realm llm-firewall
Phase 1.5   — aigate-gateway (GatewayClass + Gateway + HTTPRoute ±OIDC)
Phase 2     — 16 продуктовых сервисов

Классический Ingress (ingress-nginx и т.п.). OIDC недоступен — сервисы открыты без логина.

Phase 1     — postgres, redis, minio, opa
Phase 1.1   — bootstrap: БД, бакет policies, realm (если keycloak.enabled)
Phase 2     — 16 продуктовых сервисов
Phase 2.5   — Ingress для UI

Точка входа не создаётся. После установки вы сами создаёте Gateway/Ingress/HTTPRoute и аутентификацию. Доступ для проверки — через kubectl port-forward.

AiGate-специфика инфраструктуры

AiGate не использует NATS (в отличие от GenAI). PostgreSQL — в режиме databases (отдельная БД на группу сервисов), MinIO — только бакет policies. Realm Keycloak — llm-firewall с ролями admin/operator/viewer.


Быстрый старт: интерактивный Wizard

docker run --rm -it \
  -v ~/.kube/config:/kubeconfig:ro \
  -v $(pwd):/workspace \
  registry.appsec.global/appsecaigate-release/wizard:<VERSION> \
  wizard

OIDC / exec-based kubeconfig

Если ~/.kube/config использует OIDC (auth-provider: oidc) или exec-плагин (exec: command: ...) — wizard не подключится: внешние бинари недоступны в контейнере. Нужен kubeconfig со статическим Bearer-токеном.

Создайте ~/kube-wizard.yaml с полем user.token: <TOKEN> (токен из вашего OIDC-провайдера) и монтируйте его: -v ~/kube-wizard.yaml:/kubeconfig:ro. Токен обычно живёт ~1 час — при истечении пересоздать.

Wizard задаёт минимум вопросов и пишет values.yaml в текущую директорию:

  AppSec AIGate — Setup Wizard
  ────────────────────────────

  Domain: app.example.com
  Namespace [aigate]:
  How should services be exposed? (gateway/ingress/none) [gateway]: gateway
  Enable auth (Keycloak + Envoy OIDC)? [y/N]: y
  TLS secret name (kubectl create secret tls <name> ...) [aigate-tls]: aigate-tls
  Gateway className [aigate-class]:
  Gateway external IP (leave blank for cloud auto-assign):
  Enable persistence (required for production)? [y/N]: y
  StorageClass (leave blank for cluster default):

  ✓ values.yaml written

  Run install now? [Y/n]: y

Куда пишется values.yaml

Внутри контейнера инсталлер обнаруживает /workspace и пишет файл туда — он появляется в текущей директории хоста благодаря -v $(pwd):/workspace.

По окончании wizard печатает endpoints и DNS-записи (при auth: true — также команду для пароля bootstrap-пользователя aigate-admin@appsec.global из секрета keycloak-auth).


Запуск как in-cluster Job

Альтернатива docker run с рабочей машины — запуск инсталлера внутри кластера через Kubernetes Job. Предпочтительно, когда:

  • нет прямого доступа к kube-API с локальной машины (только in-cluster);
  • хочется, чтобы wait-for зависимостей шёл по внутреннему DNS кластера;
  • установка выполняется из CI/CD или bastion-пода.

Образ full-таргета уже несёт вшитые чарты и ENTRYPOINT ["/app/installer", "--local-charts", "/charts"]; команда (check/install/delete) добавляется через args.

1. ConfigMap с values

kubectl -n aigate create configmap wizard-values \
  --from-file=values.yaml=values.yaml \
  --dry-run=client -o yaml | kubectl apply -f -

2. ServiceAccount + RBAC

Wizard создаёт namespace, ставит helm-релизы инфры и сервисов, детектит CRD (Envoy Gateway) — нужны широкие права.

apiVersion: v1
kind: ServiceAccount
metadata: { name: wizard-installer, namespace: aigate }
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata: { name: wizard-installer-admin }
roleRef: { apiGroup: rbac.authorization.k8s.io, kind: ClusterRole, name: cluster-admin }
subjects:
  - { kind: ServiceAccount, name: wizard-installer, namespace: aigate }

3. Job — сначала check (preflight, ничего не меняет)

apiVersion: batch/v1
kind: Job
metadata: { name: wizard-check, namespace: aigate }
spec:
  backoffLimit: 0
  template:
    spec:
      serviceAccountName: wizard-installer
      restartPolicy: Never
      imagePullSecrets: [{ name: harbor-cr }]
      containers:
        - name: wizard
          image: registry.appsec.global/appsecaigate-release/wizard:<VERSION>
          args: ["check", "-f", "/cfg/values.yaml"]   # затем install / delete
          env:
            - { name: KUBECONFIG, value: "" }          # форсит fallback на in-cluster SA
          volumeMounts: [{ name: cfg, mountPath: /cfg }]
      volumes:
        - name: cfg
          configMap: { name: wizard-values }

После зелёного check — пересоздать Job с args: ["install", "-f", "/cfg/values.yaml"].

kubectl -n aigate get pods -l job-name=wizard-check   # Completed = exit 0
kubectl -n aigate logs job/wizard-check               # таблица CHECK ... ✓ all checks passed

Грабли in-cluster Job

  • ImagePullBackOff: no basic auth credentialsharbor-cr авторизует хост registry.appsec.global. В image: использовать именно его, не harbor.prod.swordfishsecurity.com (один Harbor, но imagePullSecret матчится по хосту).
  • loading kubeconfig — образ ставит ENV KUBECONFIG=/kubeconfig, а в Job такого файла нет. Выставить env KUBECONFIG="" → клиент фоллбэкнется на in-cluster SA.
  • app-secret:tokenization-vault ... required на check — создать секрет до install (см. Секреты).

Установка из готового values.yaml

docker run --rm \
  -v ~/.kube/config:/kubeconfig:ro \
  -v ./values.yaml:/values.yaml \
  -e HARBOR_PASS="<пароль>" \
  registry.appsec.global/appsecaigate-release/wizard:<VERSION> \
  install --harbor-user "<логин>" -f /values.yaml

Команды и флаги

Команда Описание
wizard Интерактивный ввод → values.yaml → опциональный install
install Полная установка всех компонентов
update Умный апгрейд — пропускает релизы без изменений (по хешу values+версии)
update --force Принудительный апгрейд всех релизов (hotfix под тот же semver)
delete Удалить Helm-релизы (--wipe-pvc — также PVC, потеря данных)
check Pre-flight проверки без изменений
Флаг По умолчанию Описание
-f, --values <path> values.yaml Путь к конфигурации
--dry-run false Отрендерить манифесты без применения
--only <a,b> Только указанные фазы
--skip <a,b> Пропустить фазы
--set key=value Переопределить значение (повторяемый)
--harbor-user Логин Harbor для pull-secret
--harbor-pass $HARBOR_PASS Пароль Harbor (предпочтительно env)
--harbor-server registry.appsec.global Хост Harbor
--parallel N 4 Параллельность Phase 2
--no-gpu false Пропустить GPU-сервисы (gpu: true в профиле) — кластер без GPU-нод
--skip-services <a,b> Пропустить конкретные phase-2 сервисы
--release-version вшита в образ Переопределить версию чартов

Пароль Harbor через env

Передавайте пароль через -e HARBOR_PASS="...", не через --harbor-pass — чтобы не светить в ps aux.


Фазы установки

Фаза Имя Что делает Пропускается
Pre-flight preflight:secrets Наличие Secret'ов при secrets.create: true
Pre-flight preflight:gateway Envoy Gateway / Gateway API CRD при exposure≠gateway → ok/warn
Pre-flight preflight:gpu Нода с nvidia.com/gpu если нет GPU-сервисов к деплою или --no-gpu
Pre-flight preflight:deps Непустота global.deps.*.existingSecret
Pre-flight preflight:appsecrets App-секреты продукта (для AiGate — tokenization-vault-secrets) если профиль их не требует
Phase 1 phase1:infra postgres, redis, minio, keycloak, opa
Phase 1.1 phase1.1:bootstrap БД, бакет policies, realm llm-firewall если *.bootstrap не задан
Phase 1.5 phase1.5 aigate-gateway (GatewayClass + OIDC) при exposure≠gateway
Phase 2 phase2:product 16 продуктовых сервисов
Phase 2.5 phase2.5 Ingress для UI при exposure≠ingress

Частичный запуск

# Только продуктовые сервисы (после hotfix образа)
docker run --rm ... install --only phase2:product -f /values.yaml

# Пропустить инфраструктуру
docker run --rm ... install --skip phase1:infra,phase1.1:bootstrap -f /values.yaml

# Кластер без GPU — поднять всё, кроме ML-сервисов
docker run --rm ... install --no-gpu -f /values.yaml

preflight:gpu

AiGate несёт три GPU-сервиса (content-safety, threat-detector, translation-service). Если деплоятся они, но в кластере 0 nvidia.com/gpupreflight:gpu завалит установку с подсказкой (добавить GPU-ноду или --no-gpu). Без GPU-сервисов фаза пропускается.


values.yaml — справочник

Обязательные параметры

Параметр Описание
domain Базовый домен инсталляции (не app.customer.com)
namespace Kubernetes namespace (default: aigate)

Схема (AiGate)

# ─── Базовые ──────────────────────────────────────────────────────────────
domain: "app.example.com"          # ОБЯЗАТЕЛЕН
namespace: "aigate"

# ─── Доступ извне ─────────────────────────────────────────────────────────
exposure: "gateway"                # gateway | ingress | none
auth:
  enabled: false                   # OIDC; учитывается только при exposure=gateway

gateway:                           # заполнять при exposure=gateway
  publicScheme: "https"            # http | https
  externalIPs: []                  # bare-metal: ["10.0.0.1"]; cloud: []
  className: "aigate-class"
ingress:
  className: ""                    # при exposure=ingress
ingressTlsSecretName: ""           # при auth=true + https
imagePullSecretName: "harbor-cr"

# ─── Секреты ──────────────────────────────────────────────────────────────
secrets:
  create: true                     # false = создать Secret'ы вручную до запуска

# ─── Инфра-компоненты (AiGate — без NATS) ─────────────────────────────────
postgres:
  enabled: true
  persistence: { enabled: false, size: "50Gi", storageClass: "" }
redis:
  enabled: true
  persistence: { enabled: false, size: "2Gi", storageClass: "" }
minio:
  enabled: true
  persistence: { enabled: false, size: "100Gi", storageClass: "" }
keycloak:
  enabled: true                    # только при auth.enabled: true
  persistence: { enabled: false, size: "1Gi", storageClass: "" }

# ─── Внешняя инфраструктура ───────────────────────────────────────────────
global:
  image:
    registry: "registry.appsec.global"
    repositoryPrefix: "appsecaigate-release"
  deps:
    postgres:
      host: postgres
      port: 5432
      existingSecret: postgres-auth
      # bootstrap: true   # создать БД admin_api_db / profiles_registry / vault_db
    redis:
      host: redis
      port: 6379
      existingSecret: redis-auth
    minio:
      host: minio
      port: 9000
      existingSecret: minio-auth
      # scheme: https     # если внешний MinIO за TLS (default: http)
      # bootstrap: true   # создать бакет policies
    keycloak:
      host: keycloak
      port: 8080
      # scheme: https     # если внешний Keycloak за TLS
      # bootstrap: true   # создать realm llm-firewall

# ─── App-секреты продукта (создаёт клиент сам) ────────────────────────────
# tokenization-vault-secrets/VAULT_MASTER_KEY — см. Секреты

license:
  centerPublicKey: ""              # выдаёт SwordFish Security

bootstrap: идемпотентность

Операции bootstrap безопасны для повторного запуска (IF NOT EXISTS / 409 Conflict = пропуск). Нужны для внешних сервисов (enabled: false) при первом install; для встроенных (enabled: true) инициализацию делают Helm-хуки автоматически.


Pre-flight, обновление, проверка, удаление

# Pre-flight без изменений
docker run --rm -v ~/.kube/config:/kubeconfig:ro -v ./values.yaml:/values.yaml \
  registry.appsec.global/appsecaigate-release/wizard:<VERSION> check -f /values.yaml

# Умный апгрейд (новый тег образа = новая версия чартов)
docker run --rm ... update -f /values.yaml
docker run --rm ... update --force -f /values.yaml   # hotfix под тот же semver

# Проверка
kubectl get pods -n aigate
kubectl -n aigate get secret keycloak-auth \
  -o jsonpath='{.data.KEYCLOAK_BOOTSTRAP_USER_PASSWORD}' | base64 -d   # auth=true

# Удаление (PVC сохраняются)
docker run --rm ... delete -f /values.yaml
kubectl delete pvc -n aigate --all && kubectl delete ns aigate          # полный снос

Версия инсталлера = версия продукта

Тег образа Wizard определяет версию всех Helm-чартов. Для апгрейда достаточно поменять тег — версия в values.yaml не указывается.

Разбор частых проблем — Устранение неполадок.