iac/apps/bim/CONFIGURATION.md

17 KiB
Raw Permalink Blame History

Конфигурация проекта bim-backend-v2

Документ описывает все переменные окружения и способы конфигурирования сервиса.

Способы конфигурирования

Сервис настраивается только через переменные окружения. Разбор выполняется в config/config.go (функция NewConfig) через библиотеку kelseyhightower/envconfig (структура Config).

Особенности разбора:

  • Префикса нетenvconfig.Process("", &cfg) вызывается с пустым префиксом, поэтому имена переменных задаются как есть (напр. POSTGRES_ADDRESS, API_ADDRESS). Имя переменной определяется тегом envconfig:"..." у каждого поля.
  • Типы приводятся автоматически по типу поля Go (string, int, bool, uint64). Для bool подходят 1/0/true/false.
  • Ошибка разбора приводит к panic при старте (в NewConfig envconfig.Process завёрнут в sync.Once, ошибка не возвращается, а паникует).
  • Отсутствующая переменная не является ошибкой — поле получает нулевое значение соответствующего типа (пустая строка, 0, false). Обязательность полей не проверяется.

В отличие от python-сервисов, приложение загружает .env автоматически: в cmd/httpserver/main.go вызывается godotenv.Load(".env") (если файла нет — печатается предупреждение и используются переменные окружения процесса).

Отдельного конфиг-файла (yaml/toml) у приложения нет.

Источники переменных по способам запуска:

Способ запуска Откуда берутся переменные
Локально (бинарник) Файл .env в рабочем каталоге (godotenv.Load) либо переменные окружения процесса
Локально (контейнеры) .docker/docker-compose.yml: env_file.docker/.env + .docker/.docker.env
Kubernetes (Helm, репозиторий приложения) .helm/values-<env>.yaml: блоки envs (обычные значения) и secrets (из k8s-секретов); шаблон .helm/templates/api.yaml
Kubernetes (IaC, этот репозиторий) iac/apps/bim/base/backend-deployment.yaml: блок env и секреты из Vault (аннотации vault.hashicorp.com/*, шаблон bim-postgresql)
CI/CD (GitLab) .gitlab-ci.yml: подключение общих пайплайнов generic/common-ci и переменные workflow.rules по ветке/тегу

Способы запуска процессов:

Команда Точка входа Назначение
httpserver (make apigo install ./cmd/httpserver) cmd/httpserver/main.go HTTP API. При старте применяет миграции (appmigrations.RunOnStartup), поднимает net/http/pprof на :8081, затем запускает API на API_ADDRESS
migrations (go install ./cmd/migrations) cmd/migrations/main.go Отдельный запуск миграций БД

Порядок запуска в контейнере (.docker/entrypoint.sh): запускается /go/bin/httpserver (строка запуска миграций закомментирована — миграции выполняются самим приложением на старте). Финальный образ (.docker/api.dockerfile) — scratch со статически слинкованным бинарником httpserver и вшитым CA-сертификатом Postgres (/root/yandex_pg.pem).

Переменные приложения

Ниже перечислены все переменные, читаемые кодом (config/config.go). Префикса нет. Дефолт — это нулевое значение типа Go, если переменная не задана.

App

Переменная Тип Значение по умолчанию Назначение
APP_NAME string "" Имя приложения (в коде помечено TODO — в deploy-envs не задаётся)
APP_VERSION string "" Версия приложения (TODO — в deploy-envs не задаётся)
LOG_LEVEL string "" Уровень логирования, передаётся в logging.NewLogger (TODO — в deploy-envs не задаётся)
API_ADDRESS string "" Адрес прослушивания HTTP API в формате host:port (напр. 0.0.0.0:8080)
TEST_ENV string "" Служебное поле для тестов

PostgreSQL

Сервис работает с тремя кластерами PostgreSQL (master, slave-1, slave-2). Выбор кластера для конкретного BIM выполняется по его id в internal/app/http/httpserver.go (сравнение с LAST_MASTER_BIM*/LAST_SLAVE_1_BIM*). Строка подключения собирается в Config.GetPostgresConnectionURL (postgres://user:password@addr:port/db, при ENABLE_SSL=false добавляется ?sslmode=disable).

Master-кластер:

Переменная Тип Назначение
POSTGRES_ADDRESS string Хост PostgreSQL (master)
POSTGRES_PORT string Порт PostgreSQL (master)
POSTGRES_USER string Пользователь БД
POSTGRES_PASSWORD string Пароль пользователя БД
POSTGRES_DB string Имя базы данных
POSTGRES_POOL_SIZE int Размер пула соединений
DB_CERT_PATH string Путь к CA-сертификату PostgreSQL (используется при ENABLE_SSL=1)

Slave-1 кластер — те же поля с суффиксом _2:

Переменная Тип Назначение
POSTGRES_ADDRESS_2 string Хост PostgreSQL (slave-1)
POSTGRES_PORT_2 string Порт
POSTGRES_USER_2 string Пользователь
POSTGRES_PASSWORD_2 string Пароль
POSTGRES_DB_2 string База данных
POSTGRES_POOL_SIZE_2 int Размер пула
DB_CERT_PATH_2 string Путь к CA-сертификату

Slave-2 кластер — те же поля с суффиксом _3:

Переменная Тип Назначение
POSTGRES_ADDRESS_3 string Хост PostgreSQL (slave-2)
POSTGRES_PORT_3 string Порт
POSTGRES_USER_3 string Пользователь
POSTGRES_PASSWORD_3 string Пароль
POSTGRES_DB_3 string База данных
POSTGRES_POOL_SIZE_3 int Размер пула
DB_CERT_PATH_3 string Путь к CA-сертификату

Шардирование BIM по кластерам

Переменная Тип Назначение
LAST_MASTER_BIM uint64 Верхняя граница id BIM для master-кластера (API v1)
LAST_MASTER_BIM_V3 uint64 Верхняя граница id BIM для master-кластера (API v2 / BIM v3)
LAST_SLAVE_1_BIM uint64 Верхняя граница id BIM для slave-1 (API v1)
LAST_SLAVE_1_BIM_V3 uint64 Верхняя граница id BIM для slave-1 (API v2 / BIM v3)

Прочее

Переменная Тип Значение по умолчанию Назначение
ENABLE_SSL bool false Подключение к PostgreSQL по TLS. При false в DSN добавляется sslmode=disable
ENABLE_SQL_QUERY bool false Логировать SQL-запросы
DJANGO_HOST string "" Базовый URL Django-бэкенда для проверки прав администратора (см. ENDPOINTS.md)
INTEGRATION_TESTS bool false Режим интеграционных тестов. При true CheckUserIsAdmin всегда возвращает true

Переменные, не читаемые приложением (инфраструктура/сборка/тесты)

Присутствуют в .docker/.env, .docker/.docker.env, docker-compose.yml или Helm, но config/config.go их не разбирает.

Переменная Где используется Назначение
API_PORT .docker/.env Порт API для локального compose
POSTGRES_EXTERNAL_PORT, POSTGRES_EXTERNAL_PORT_2 docker-compose.yml Проброс портов контейнеров Postgres
POSTGRES_ADDRESS2 .docker/.docker.env Опечатка/легаси (нет суффикса _), кодом не читается
GRPC_ADDRESS, GRPC_PORT .docker/.env Объявлены, но кодом не используются
TEST_BIM, JWT_TEST .docker/.env, .docker/.docker.env Данные для интеграционных тестов
POSTGRES_*_4, DB_CERT_PATH_4 .helm/values-*.yaml, IaC backend-deployment.yaml Четвёртый кластер задаётся в деплое, но config.go доходит только до суффикса _3
LAST_SLAVE_2_BIM(_V3), LAST_SLAVE_3_BIM(_V3), LAST_SLAVE_4_BIM(_V3) .helm/values-*.yaml Заданы в values, но кодом не читаются (актуальны только LAST_MASTER_* и LAST_SLAVE_1_*)
CI_COMMIT_SHORT_SHA .gitlab-ci.yml (build-arg) Тег/версия сборки образа

Переменные из Helm-чарта приложения (.helm/values-<env>.yaml)

Обычные значения задаются в блоке envs для каждого окружения (stage/preprod/production) и содержат те же переменные POSTGRES_*, API_ADDRESS, DJANGO_HOST, ENABLE_SSL, ENABLE_SQL_QUERY, LAST_*, что описаны выше (различаются адресами БД, размерами пула, границами шардирования и доменом Django).

Значения из секретов (блок secrets, монтируются как env через secretKeyRef):

Переменная Секрет (secret_name) Ключ (secret_key)
POSTGRES_USER bim-v2-database-secret username
POSTGRES_PASSWORD bim-v2-database-secret password
POSTGRES_USER_2 bim-v2-database-secret-2 username
POSTGRES_PASSWORD_2 bim-v2-database-secret-2 password
POSTGRES_USER_3 bim-v2-database-secret-3 username
POSTGRES_PASSWORD_3 bim-v2-database-secret-3 password
POSTGRES_USER_4 bim-v2-database-secret-3 username
POSTGRES_PASSWORD_4 bim-v2-database-secret-3 password

Ключевые не-env значения чарта: api.name, api.image, api.version, api.port (8080), api.replicas, api.service_name/api.service_port (80), api.service_account, api.requests.memory/cpu, api.api_host, api.api_host_prefix (/bimv2/api/), api.api_path (/api/), api.internal_path (/internal/), api.permitted_ns (namespace'ы, которым разрешён доступ к /internal/*), imagePullSecrets.

Сетевой слой (.helm/templates/mesh-config.yaml, Istio):

  • VirtualService (при api.virtual_service.enabled) маршрутизирует api_host_prefixapi_path, задаёт CORS (allowOrigins*.sarex.io и localhost, allowHeaders включают Authorization, Content-Type, Identity).
  • AuthorizationPolicy routes-v2: доступ к /api/* разрешён только от istio-ingressgateway при наличии claim token_type=access; доступ к /internal/* — только из namespace'ов api.permitted_ns.

Переменные из IaC-репозитория (iac/apps/bim/)

Деплой в этом репозитории (kustomize) устроен иначе, чем чарт приложения:

  • base/backend-deployment.yaml — Deployment backend в namespace bim, образ bim-api, containerPort: 8000, API_ADDRESS=0.0.0.0:8000, health-проба GET /ping.
  • Секреты PostgreSQL инъектируются из Vault (аннотации vault.hashicorp.com/*, роль bim, путь secrets/data/postgresql/apps/bim) в файл /vault/secrets/bim-postgresql, который экспортируется в окружение перед запуском (set -a; . /vault/secrets/bim-postgresql; set +a; exec ./httpserver). Шаблон Vault задаёт POSTGRES_ADDRESS[_2../_4], POSTGRES_PORT*, POSTGRES_DB* (все указывают на postgresql.bim.svc.cluster.local:5432, БД bim_db) и POSTGRES_USER*/POSTGRES_PASSWORD* из Vault.
  • Прочие env заданы прямо в манифесте: LAST_MASTER_BIM, LAST_MASTER_BIM_V3, LAST_SLAVE_1_BIM, POSTGRES_POOL_SIZE, DB_CERT_PATH_2/3/4, DJANGO_HOST (http://backend.django.svc.cluster.local:8000), ENABLE_SQL_QUERY=0, ENABLE_SSL=0.
  • Оверлеи brusnika-prod, brusnika-stage, yc-k8s-test патчат base (реплики, образ, postgresql).

Переменные в CI (.gitlab-ci.yml)

Пайплайн подключает общие шаблоны generic/common-ci (universal-pipeline-<env>.yaml, common-security-scan.yaml, common-build.yaml) и переключает окружение по ветке/тегу через workflow.rules:

Условие STAND Namespace
ветка master preprod bim-api-preprod
ветка stage stage bim-api-stage
тег (CI_COMMIT_TAG) prod bim-api-prod

Общие переменные job'ов: RELEASE_NAME=bim-backend-v2, CHART_NAME=bim-backend-v2, CHART_VERSION=0.0.1-<stand>, IMAGE_PATH=api.image, DOCKERFILE_PATH=.docker/api.dockerfile, HELM_SET_ARGS=--set api.image=${IMAGE_NAME}, BUILD_ARGS=--build-arg CI_COMMIT_SHORT_SHA=..., флаги ENABLE_BUILD_CHART/ENABLE_BUILD_IMAGE/ENABLE_STATE_UPDATE/ENABLE_DEPLOY=true, ENABLE_LINTER=false. Стадии: linter → test → unittest → prebuild-secscan → build → state-update → deploy.

Замечания и потенциальные проблемы

  • Переменные разбираются без префикса (envconfig.Process("", ...)) — имена совпадают с тегами envconfig полей структуры Config.
  • Обязательность полей не валидируется: отсутствующая переменная молча получает нулевое значение. Например пустой API_ADDRESS приведёт к попытке слушать на ":0".
  • В коде объявлены только три кластера (POSTGRES_*, _2, _3), тогда как в деплое присутствует и четвёртый (_4). Переменные _4 и дополнительные LAST_SLAVE_2/3/4_* в окружении задаются, но приложением не используются.
  • Приложение загружает .env автоматически (godotenv.Load(".env")); при отсутствии файла ошибки нет — берутся переменные процесса.
  • В NewConfig ошибка envconfig.Process не возвращается, а вызывает panic (обёрнута в sync.Once).

Минимальный набор для локального запуска

Postgres поднимается через docker-compose (.docker/docker-compose.yml), приложение — через make api и запуск httpserver. Минимально необходимо задать (готовые примеры — в .env.example):

  • API_ADDRESS
  • Master-кластер: POSTGRES_ADDRESS, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, POSTGRES_POOL_SIZE
  • Slave-кластеры _2 и _3 (те же поля) — сервис создаёт соединения ко всем трём при старте
  • ENABLE_SSL=0, DB_CERT_PATH* (при ENABLE_SSL=1)
  • DJANGO_HOST
  • LAST_MASTER_BIM, LAST_MASTER_BIM_V3, LAST_SLAVE_1_BIM, LAST_SLAVE_1_BIM_V3
  • INTEGRATION_TESTS=0, ENABLE_SQL_QUERY по необходимости