SecurityFlow Кабинет лицензий , откроется в новой вкладке

Документация / Руководство по установке / Установка

Установка в Kubernetes

Обновлено 20 октября 2026

Установку выполняет команда SecurityFlow: кладёт образы в реестр площадки, создаёт секреты, разворачивает Core и Radar и проверяет работу. Площадка заранее готовит кластер, виртуальные машины, сеть и доступы. На этой странице - что разворачивается, в каком порядке и как проверить результат.

Перед началом

Площадка готовит:

Что Требование Подробнее
Кластер 3 мастера, пул app без taint, пул scan с taint dedicated=scanners:NoSchedule Системные требования
Пространства имён securityflow-core, securityflow-radar; для securityflow-radar разрешены privileged-поды (Pod Security Admission) воркер сканирования запускает Docker-in-Docker
Хранилище StorageClass для локальных томов брокеров; RWX-том 20 GiB для файлов Core Хранилище
Ingress ingress-nginx с client-max-body-size 100m и proxy-read-timeout 300s
Внешний прокси терминирует TLS для имён Core и Radar и передаёт запросы в ingress Сетевое взаимодействие
Хосты для ВМ под PostgreSQL, реестр образов и служебную ВМ Расчёт ресурсов
Доступы SSH и sudo на хосты, kube-apiserver 6443, исходящий HTTPS до securityflow.ru
Ключ лицензии выдаёт SecurityFlow Активация лицензии

Нужны две базы PostgreSQL 15 или новее, для Core и для Radar, и пользователи, которым разрешено создавать в них объекты: миграции создают и меняют таблицы при установке и каждом обновлении.

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

Имена Deployment и Service задаются при установке. В командах на страницах документации они даны в угловых скобках, например <Radar back>. Теги образов - по составу релиза, см. Релизы.

Core, пространство securityflow-core

Процессы Core работают на одном образе sf-core-back. Какой процесс поднять, решает переменная MODE.

Компонент Образ Порт Реплики Request / limit Данные
Подготовка базы: Job sf-core-init, MODE=init sf-core-back - разовый запуск, до 3 попыток 250m, 512Mi / 1 CPU, 1Gi миграции базы Core, статика, администратор
Интерфейс и API: MODE=web, gunicorn 4 × 4 sf-core-back 8000 2 и больше 500m, 1Gi / 2 CPU, 2Gi база Core, файлы media
Приём отчётов: MODE=importer, gunicorn 2 × 4 sf-core-back 8001 2 и больше 500m, 2Gi / 2 CPU, 4Gi отчёт целиком в памяти, затем в брокер
Worker: MODE=worker, очередь appsecpanel_worker sf-core-back - 2 и больше 500m, 1Gi / 2 CPU, 2Gi база Core
Планировщик: MODE=beat sf-core-back - ровно 1, стратегия Recreate 100m, 256Mi / 500m, 512Mi расписания в базе Core
Разбор отчётов, очередь importer_service sf-core-importer - 2-4, параллельность 3 1 CPU, 1,5Gi / 4Gi -
Помощник БД: запись находок, автовалидатор, дедупликатор, CVSS sf-core-db-helper - ровно 1 1 CPU, 2,5Gi / 5Gi база Core
Jira-помощник, очередь jira_helper_service sf-core-jira-helper - 1-2, параллельность 2 0,1 CPU, 256Mi / 1Gi -
Фронт: nginx и интерфейс sf-core-front 80 2-3 50m, 64Mi / 256Mi статика и файлы media только на чтение
RabbitMQ Core, quorum queues RabbitMQ 5672 3 0,5 CPU, 1Gi / 2Gi локальный том 30 GiB на реплику

Интерфейс и API и приём отчётов - отдельные Deployment, у каждого свой Service: на порт 8000 и на порт 8001.

Тома Core:

Том Куда подключается
RWX-том файлов Core (media) /usr/src/app/media процессов Core, /var/www/media фронта
Статика Django Job подготовки собирает её в /usr/src/app/static, фронт отдаёт её из общего тома в /var/www/static

Пробы readinessProbe и livenessProbe интерфейса и API - GET /healthcheck/ на порт 8000: путь отвечает 200 без входа. Если задан ALLOWED_HOSTS, проба передаёт заголовок Host с именем из этого списка. Пробы остальных компонентов - в разделе Мониторинг и журналы.

Планировщик Core работает строго в одной реплике: две копии поставят каждое периодическое задание дважды. Стратегия Recreate не даёт двум планировщикам пересечься при обновлении.

Radar, пространство securityflow-radar

Компонент Образ Порт Реплики Request / limit Данные
Radar back: API, API_WORKERS=4 sf-radar-back 8090 2 0,55 CPU, 0,8Gi / 2,25Gi база Radar
Фронт Radar sf-radar-front 8080 2 50m, 64Mi / 256Mi -
Воркер сканирования: пайплайн-воркер, Docker-in-Docker, utils-воркер, очистка Docker sf-radar-worker - 2 на узел scan 3,9 CPU, 10,5Gi / 20Gi emptyDir на локальном SSD: тома пайплайнов, кэш образов сканеров
Планировщик Radar: ежедневная очистка sf-radar-worker, entrypoint_utils_beat.sh - ровно 1 0,1 CPU, 256Mi / 512Mi -
RabbitMQ Radar RabbitMQ 5672 3 0,5 CPU, 1Gi / 2Gi локальный том 10 GiB на реплику
Redis Redis 6379 3 0,2 CPU, 512Mi / 1Gi локальный том 5 GiB на реплику

Состав пода воркера сканирования:

Контейнер Что делает
Пайплайн-воркер, entrypoint_pipeline_worker.sh берёт пайплайны из pipeline_queue; слотов на под - MAX_SCALEWORKERS_COUNT=3
Docker-in-Docker, privileged запускает контейнеры сканеров
Utils-воркер, entrypoint_utils_worker.sh, --concurrency=2 задачи utils_queue: остановка джоб, выдача артефактов, удаление образов
Очистка Docker по таймеру удаляет старые тома и контейнеры Docker своего пода. Ежедневная очистка Radar затрагивает Docker одного пода, поэтому у каждого пода своя очистка: без неё на узле scan копится около 8 ГБ томов в сутки

Только контейнер Docker-in-Docker работает в привилегированном режиме. Utils-воркер запускается с --concurrency=2 в команде контейнера: без флага Celery поднимает столько процессов, сколько CPU на узле.

Перезапуск Radar back прерывает сканы

Radar back при каждом старте применяет миграции базы и прерывает все пайплайны "В ожидании" и "Выполняется". Поднимайте и перезапускайте его в окно без сканов - см. Запуск, остановка и масштабирование.

Вне кластера

Компонент Где Назначение
PostgreSQL, Patroni, etcd, PgBouncer, HAProxy и keepalived 3 ВМ базы Core и Radar, общий адрес на порту 5432
Реестр образов ВМ образы платформы и сканеров
Служебная ВМ ВМ NFS-экспорт для файлов Core, репозиторий резервных копий
Сервер лицензий у SecurityFlow, securityflow.ru активация и сверка лицензии

Маршрутизация запросов

Ingress направляет имя Core на фронт Core (порт 80), имя Radar - на фронт Radar (порт 8080). Дальше запросы раскладывают сами фронты:

Путь Куда Порт
Core: /api/v1/scan/import/ приём отчётов 8001
Core: /api/v1/, /admin/, /oauth2/callback интерфейс и API 8000
Core: /static/, /media/ файлы из томов фронта -
Core: остальное интерфейс, index.html -
Radar: /api/v1/, /admin/ Radar back 8090
Radar: остальное интерфейс -

Swagger Core открывается по адресу /api/v1/docs/ и идёт по маршруту /api/v1/.

Фронт Core обращается к интерфейсу и API на порт 8000 и к приёму отчётов на порт 8001, фронт Radar - к Radar back на порт 8090. Имена сервисов бэкендов задаются при установке. nginx фронта не стартует, если не может разрешить имя бэкенда, поэтому сервисы бэкендов создаются раньше фронтов. Воркеры Radar обращаются к Radar back по адресу из AUDITOR_HOST - см. Параметры конфигурации.

Секреты

Секреты хранятся в Kubernetes Secrets и подключаются к подам переменными окружения. Копию секретов команда SecurityFlow передаёт владельцу площадки.

Секрет Пространство Что внутри
sf-core-env securityflow-core доступ к базе и брокеру Core, DJANGO_SECRET_KEY, пара JWT_PRIVATE_KEY и JWT_PUBLIC_KEY, LICENSE_SERVER_PUBLIC_KEY, данные первого администратора
секрет Radar securityflow-radar доступ к базе, брокеру и Redis Radar, DOCKER_ENCRYPTION_TOKEN, ACCESS_TOKEN
пароли RabbitMQ и Redis оба пароли самих брокеров

Полный перечень переменных, их формат и способы генерации - в разделе Параметры конфигурации.

Ключи шифрования задаются один раз

Пара JWT_PRIVATE_KEY и JWT_PUBLIC_KEY шифрует секреты интеграций в базе Core, DOCKER_ENCRYPTION_TOKEN - пароли реестров в базе Radar. После первого запуска их не меняют: сохранённые секреты станут нечитаемыми. Храните эти значения вместе с резервными копиями баз.

Порядок развёртывания

1. Пространства и хранилище

Создаются пространства securityflow-core и securityflow-radar, для Radar включается уровень privileged. Готовятся StorageClass для локальных томов и RWX-том для файлов Core.

kubectl create namespace securityflow-core
kubectl create namespace securityflow-radar
kubectl label namespace securityflow-radar pod-security.kubernetes.io/enforce=privileged

2. Секреты

Создаются секреты Core и Radar. Пример для Core:

kubectl -n securityflow-core create secret generic sf-core-env \
  --from-literal=DJANGO_SECRET_KEY="$(openssl rand -hex 32)" \
  --from-literal=DB_HOST=<адрес PostgreSQL> \
  --from-literal=DB_PORT=5432 \
  --from-literal=DB_NAME=<база Core> \
  --from-literal=DB_USER=<пользователь Core> \
  --from-literal=DB_PASS=<пароль> \
  --from-literal=AMQP_HOST_STRING='amqp://<пользователь>:<пароль>@<RabbitMQ Core>:5672/<vhost>' \
  --from-literal=DOMAIN=https://core.example.ru \
  --from-literal=ALLOWED_HOSTS=core.example.ru,<внутренние имена Core> \
  --from-file=JWT_PRIVATE_KEY=jwt.key \
  --from-file=JWT_PUBLIC_KEY=jwt.pub \
  --from-file=LICENSE_SERVER_PUBLIC_KEY=license.pub \
  --from-literal=ADMIN_USER=admin \
  --from-literal=ADMIN_EMAIL=<почта администратора>

Пароль первого администратора добавляется в секрет ключом ADMIN_PASSWORD. Если ключа нет, пароль генерируется при подготовке базы и выводится в её журнал один раз.

Как получить jwt.key, jwt.pub и license.pub - в разделе Формат PEM-ключей.

3. Брокеры и Redis

Разворачиваются RabbitMQ Core, RabbitMQ Radar и Redis по 3 реплики. До перехода к шагу 4 базы PostgreSQL должны быть доступны по общему адресу.

4. Подготовка базы Core

Job sf-core-init с MODE=init выполняет миграции, собирает статику, создаёт первого администратора и приводит к единому виду имена сканеров. Миграции идут отдельной задачей, а не при старте каждого пода: иначе при масштабировании мигрировал бы каждый новый под. Процессы Core разворачиваются только после завершения Job.

kubectl -n securityflow-core wait --for=condition=complete job/sf-core-init --timeout=900s
kubectl -n securityflow-core logs job/sf-core-init

Ожидаемый результат: Job в состоянии Complete, в журнале строки [admin] создан суперпользователь admin и [admin] назначена роль superuser (полный доступ). Если ADMIN_PASSWORD не задан, пароль сгенерирован и выведен в этот журнал один раз - см. Первичная настройка.

5. Процессы Core

Разворачиваются интерфейс и API, приём отчётов, worker и планировщик с их сервисами, затем разбор отчётов, помощник БД, Jira-помощник и фронт Core.

kubectl -n securityflow-core wait --for=condition=available deployment --all --timeout=600s
kubectl -n securityflow-core get pods

6. Radar

Сначала разворачивается Radar back в одной реплике. При старте он сам применяет миграции базы Radar (alembic upgrade head) и загружает встроенный каталог джоб. Затем число реплик доводится до двух, разворачиваются воркеры сканирования, планировщик Radar и фронт Radar.

kubectl -n securityflow-radar logs deploy/<Radar back> | grep -E "Alembic|Uvicorn"
kubectl -n securityflow-radar get pods -o wide

Поды воркера сканирования должны оказаться на узлах scan.

7. Ingress

Создаются правила ingress для имён Core и Radar. После этого Core открывается на экране активации лицензии.

8. Первичная настройка

Активация лицензии, вход администратора, токен Radar, связь Core и Radar, образы сканеров и первый скан - в разделе Первичная настройка.

Проверка

Что Как Ожидаемый результат
Поды Core и Radar kubectl -n securityflow-core get pods, kubectl -n securityflow-radar get pods все в Running, Job подготовки - Completed
Core web kubectl -n securityflow-core port-forward deploy/<Core web> 8000:8000, затем curl -sS -o /dev/null -w '%{http_code}\n' -H 'Host: core.example.ru' http://127.0.0.1:8000/healthcheck/ 200. Если ALLOWED_HOSTS задан, без заголовка Host из этого списка Core ответит 400
Core через прокси curl -sS -o /dev/null -w '%{http_code}\n' https://core.example.ru/admin/login/ 200
Radar через прокси curl -sS https://radar.example.ru/api/v1/health-check/ {"is_healthy":true}
Токен Radar curl -sS -H "Authorization: Bearer <токен Radar>" https://radar.example.ru/api/v1/auth-health-check/ {"is_healthy":true}
Воркеры Radar curl -sS -H "Authorization: Bearer <токен Radar>" https://radar.example.ru/api/v1/workers/total/ pipeline_workers_total равно числу подов воркера, utils_workers_total - числу utils-воркеров
Связь Core и Radar curl -sS -H "Authorization: Token <API-токен>" https://core.example.ru/api/v1/ci/health-check/ {"is_healthy": true, "is_authenticated": true}
Лицензия Core: "Глобальные настройки" → "Лицензия" видны компания, тариф и срок
Сквозной скан первый аудит продукта пайплайн в Radar "Завершен", в Core появился аудит

Путь /healthcheck/ отвечает на порту 8000 процесса интерфейса и API. Через прокси проверяйте /admin/login/.

Диагностика

Симптом Причина Что сделать
Job подготовки базы в Error нет доступа к PostgreSQL, неверные DB_*, у пользователя нет прав на создание таблиц kubectl -n securityflow-core logs job/sf-core-init; проверьте доступ к 5432 и права пользователя
Под sf-core-back сразу завершается с MODE=... не знаю неверное значение MODE допустимо all, init, web, importer, worker, beat
Фронт Core или Radar в CrashLoopBackOff, в журнале host not found in upstream nginx фронта не разрешает имя сервиса бэкенда проверьте, что сервисы бэкендов созданы и их имена совпадают с адресами бэкендов в конфигурации фронта
Поды интерфейса и API не переходят в Ready и перезапускаются проба указывает не на /healthcheck/, или имя пробы не входит в ALLOWED_HOSTS и Core отвечает 400 переведите пробы на /healthcheck/, передайте в пробе заголовок Host из ALLOWED_HOSTS
Страница /admin/ без стилей, /static/ отвечает 404 фронту не подключён том со статикой Django подключите к /var/www/static фронта том со статикой, которую собрал Job подготовки
Core открывается, но активация не проходит нет исходящего HTTPS до securityflow.ru или адрес кластера не в белом списке проверьте связность - Сетевое взаимодействие, ошибки активации - Активация лицензии
Загрузка отчёта отвечает 413 отчёт больше лимита тела в ingress проверьте размер отчёта; лимит ingress держите ниже max_message_size RabbitMQ
Под воркера не стартует, Docker-in-Docker в ошибке privileged-поды запрещены в пространстве Radar включите уровень privileged для securityflow-radar
В Radar "Нет Доступных Воркеров" воркеры не подключились к брокеру Radar проверьте AMQP_HOST_STRING воркеров и доступ к 5672
Пайплайн висит "В ожидании", в журнале воркера Aborting the pipeline воркер не прошёл проверку токена в Radar back проверьте ACCESS_TOKEN и AUDITOR_HOST воркера - Первичная настройка
Джоба падает на скачивании образа Docker пода не достаёт до реестра или нет учётных данных проверьте доступ узлов scan к реестру и учётные данные реестра в Radar
Джоба-сканер в статусе "Джоба остановлена", отчёт не дошёл до Core "Внутренний URL приложения" недоступен из Radar, или имя сканера в SCAN_TYPE неизвестно Core проверьте адрес в Core: "Глобальные настройки" → "Рабочий процесс"; имя сканера - Свой сканер
Аудит в Core есть, находок нет задание не дошло до Radar: ошибки отправки Core пишет только в журнал worker kubectl -n securityflow-core logs deploy/<Core worker>; проверьте "Статус подключения" в настройках Radar в Core

Общая таблица ошибок - в разделе Типовые ошибки.