Django обращается к сервису измерений при MEASUREMENTS_USE_MEASUREMENTS=1 (значение по умолчанию в base), так что без него часть API отвечала ошибкой. Сервис переименован в measurements-service, как в brusnika-*. В base он называется measurements-svc, а django ходит на measurements-service — переименовать сервис дешевле, чем патчить переменную в двух релизах django. Бакеты теперь заводит Job в infrastructure/minio/aero, а не команда руками. Чарт MinIO этого не умеет: форк не принимает ни buckets, ни provisioning. Так бакет django был создан императивно и не пережил бы пересоздание контура — развернув всё с нуля, получили бы работающий MinIO и приложения, падающие на отсутствующем бакете. Measurements сломался бы на этом сразу: имя бакета зашито в его vault-шаблоне. Идемпотентность даёт mc mb --ignore-existing. Сайдкар istio у Job отключён: контейнер задачи выходит, envoy продолжает работать, и под навсегда остаётся Running.
349 lines
19 KiB
YAML
349 lines
19 KiB
YAML
---
|
||
# Каталог развёртывания на хосте (домашка root)
|
||
deploy_dir: /root/sarex
|
||
|
||
# --- Модули ядра для istio-init --------------------------------------------
|
||
# Ноды k3s — это docker-контейнеры, своего ядра у них нет: любые операции с
|
||
# iptables внутри подов идут через ядро ХОСТА. istio-init настраивает перехват
|
||
# трафика и создаёт legacy-таблицу nat, поэтому на хосте должен быть загружен
|
||
# iptable_nat.
|
||
#
|
||
# На RED OS 8 (ядро 6.6, iptables в режиме nf_tables) он по умолчанию НЕ
|
||
# загружен: присутствуют только nft-варианты (nft_chain_nat, xt_nat). Без этих
|
||
# модулей istio-init падает с
|
||
# xtables parameter problem: iptables-restore: unable to initialize table 'nat'
|
||
# и КАЖДЫЙ под в namespace с istio-injection=enabled навсегда остаётся в
|
||
# Init:Error — именно так встал kubernetes-dashboard.
|
||
aero_kernel_modules:
|
||
- iptable_nat
|
||
- iptable_mangle
|
||
- iptable_raw
|
||
- xt_REDIRECT
|
||
- xt_owner
|
||
|
||
# Источник файлов — корень репозитория iac (playbook лежит в aero/)
|
||
deploy_src_root: "{{ playbook_dir }}/.."
|
||
|
||
# Домены верхнего nginx (попадают в .env и в SAN сертификата)
|
||
platform_domain: sarex.local.lonsdaleites.ru
|
||
admin_domain: admin.sarex.local.lonsdaleites.ru
|
||
minio_domain: minio.sarex.local.lonsdaleites.ru
|
||
|
||
# Самоподписанный TLS-сертификат
|
||
cert_days: 365
|
||
cert_dir: "{{ deploy_dir }}/nginx/certs"
|
||
|
||
# Переменные-пароли: им генерируются стойкие значения взамен слабых дефолтов.
|
||
sarex_secret_vars:
|
||
- K3S_TOKEN
|
||
- GITEA_ADMIN_PASSWORD
|
||
- SAREX_POSTGRES_PASSWORD
|
||
- SAREX_DJANGO_DB_PASSWORD
|
||
- SAREX_PROCESSING_DB_PASSWORD
|
||
- SAREX_BIM_DB_PASSWORD
|
||
- SAREX_WORKSPACE_DB_PASSWORD
|
||
- SAREX_RABBITMQ_PASSWORD
|
||
- SAREX_MINIO_ROOT_PASSWORD
|
||
- SAREX_MINIO_APP_PASSWORD
|
||
|
||
secret_length: 24
|
||
|
||
# Хранилище секретов на control-node (persist + переиспользование). Gitignored.
|
||
secrets_store: "{{ playbook_dir }}/.secrets"
|
||
|
||
# RSA-ключи JWT backend (RS512). Генерируются на control-node, persist в secrets_store.
|
||
jwt_private_key_path: "{{ secrets_store }}/{{ inventory_hostname }}/jwt_private.pem"
|
||
jwt_public_key_path: "{{ secrets_store }}/{{ inventory_hostname }}/jwt_public.pem"
|
||
|
||
# --- Приватный реестр образов и чартов (cr.yandex, аутентификация json_key) ---
|
||
registry_host: cr.yandex
|
||
registry_username: json_key
|
||
|
||
# Путь к ключу сервисного аккаунта НА CONTROL-NODE (ansible запускается из WSL,
|
||
# поэтому диск C: виден как /mnt/c). Это машинно-зависимое значение —
|
||
# переопределяйте, не редактируя роль:
|
||
# uv run poe platform -- -e registry_key_src=/path/to/authorized_key.json
|
||
registry_key_src: "/mnt/c/Users/user/Downloads/Telegram Desktop/authorized_key.json"
|
||
|
||
# Куда ключ кладётся на целевом хосте на время провижининга (удаляется после).
|
||
registry_key_dest: "{{ deploy_dir }}/registry-key.json"
|
||
|
||
# Секреты в кластере. Namespace создаётся вместе с секретом — он нужен раньше,
|
||
# чем чарт создаст его сам. Список пополняется по мере переезда компонентов.
|
||
# * yc-cr-auth (flux-system) — Flux тянет им OCI-ЧАРТЫ. Обязателен.
|
||
# * regcred — imagePullSecrets подов в namespace потребителя.
|
||
registry_secrets:
|
||
- {name: yc-cr-auth, namespace: flux-system}
|
||
- {name: regcred, namespace: cert-manager}
|
||
- {name: regcred, namespace: istio-system}
|
||
- {name: regcred, namespace: kubernetes-dashboard}
|
||
# Образы vault-k8s и vault-agent для injector'а тоже лежат в cr.yandex.
|
||
- {name: regcred, namespace: vault}
|
||
- {name: regcred, namespace: local-path-provisioner}
|
||
- {name: regcred, namespace: postgresql}
|
||
- {name: regcred, namespace: rabbitmq}
|
||
- {name: regcred, namespace: minio}
|
||
# Образы backend и frontend лежат в приватном cr.yandex.
|
||
- {name: regcred, namespace: django}
|
||
- {name: regcred, namespace: measurements}
|
||
|
||
# Поднимать стек (docker compose up -d). Требует запущенной службы docker и
|
||
# docker login в cr.yandex — по умолчанию выключено.
|
||
sarex_compose_up: false
|
||
compose_cmd: "docker compose"
|
||
|
||
# --- GitOps-подложка контура (k3s + gitea + vault + flux) -------------------
|
||
# Параметры gitea и Flux. Попадают в .env (их читает docker-compose) — менять
|
||
# нужно здесь, а не в .env.example, иначе перезапишется при следующем деплое.
|
||
gitea_admin_user: sarex
|
||
gitea_admin_email: "{{ gitea_admin_user }}@{{ platform_domain }}"
|
||
gitea_org: infra
|
||
gitea_repo: iac
|
||
# Ветка и путь, за которыми следит Flux внутри репозитория в gitea.
|
||
aero_git_branch: master
|
||
aero_flux_path: clusters/aero
|
||
|
||
# --- Синхронизация репозитория в gitea --------------------------------------
|
||
# Содержимое едет с control-node на хост архивом и коммитится в gitea оттуда:
|
||
# наружу gitea не публикуется дальше самого хоста, а git на control-node может
|
||
# быть не настроен на работу с контуром.
|
||
#
|
||
# Список — это ЗАМЫКАНИЕ ссылок clusters/aero, а не весь репозиторий:
|
||
# clusters/aero/controllers ссылается на ../../../infrastructure/<компонент>/aero,
|
||
# каждый такой overlay тянет только ../base. Каталоги ansible-роли, snapshots и
|
||
# docs кластеру не нужны и не синхронизируются.
|
||
#
|
||
# ВАЖНО: добавил компонент в clusters/aero/controllers — добавь его сюда, иначе
|
||
# kustomize в кластере упадёт на отсутствующем каталоге.
|
||
gitea_sync_paths:
|
||
- clusters/aero
|
||
- infrastructure/cert-manager
|
||
- infrastructure/dashboard
|
||
- infrastructure/istio-base
|
||
- infrastructure/istio-config
|
||
- infrastructure/istio-gateway
|
||
- infrastructure/istio-pilot
|
||
- infrastructure/vault-injector
|
||
- infrastructure/local-path-provisioner
|
||
- infrastructure/postgresql
|
||
- infrastructure/rabbitmq
|
||
- infrastructure/minio
|
||
# Прикладной слой.
|
||
- apps/django
|
||
- apps/measurements
|
||
|
||
# Рабочая копия репозитория gitea на хосте (клон, живёт между прогонами).
|
||
gitea_sync_workdir: "{{ deploy_dir }}/gitea-sync"
|
||
gitea_sync_archive_remote: "{{ deploy_dir }}/gitea-sync.tar.gz"
|
||
|
||
# Адрес gitea с точки зрения ХОСТА: контейнер публикует 3000 наружу.
|
||
gitea_http_addr: "http://127.0.0.1:3000"
|
||
|
||
# URL с кредами для push'а. sarex_secrets заполняется в tasks/main.yml, поэтому
|
||
# выражение раскрывается лениво — к моменту использования пароль уже есть.
|
||
gitea_sync_url: >-
|
||
http://{{ gitea_admin_user }}:{{ sarex_secrets.GITEA_ADMIN_PASSWORD | urlencode }}@127.0.0.1:3000/{{ gitea_org }}/{{ gitea_repo }}.git
|
||
|
||
# Временный архив на control-node (удаляется после синхронизации).
|
||
gitea_sync_archive_local: /tmp/aero-gitea-sync.tar.gz
|
||
|
||
# Автор коммитов синхронизации.
|
||
gitea_commit_name: aero-sync
|
||
gitea_commit_email: "aero-sync@{{ platform_domain }}"
|
||
|
||
# Поднимается отдельно от прикладного стека: образы публичные, docker login в
|
||
# cr.yandex не нужен. По умолчанию выключено, включает `uv run poe platform`.
|
||
aero_platform_up: false
|
||
|
||
# Волна 1: долгоживущие сервисы, которым нужно успеть стать healthy.
|
||
# k3s-server при первом старте создаёт ./k3s/kubeconfig.yaml — его ждёт волна 2.
|
||
aero_platform_services_wave1:
|
||
- k3s-server
|
||
- k3s-worker-1
|
||
- k3s-worker-2
|
||
- gitea
|
||
|
||
# Волна 2: провижининг. gitea-init и flux-k8s-init одноразовые (restart: "no"),
|
||
# vault-init живёт постоянно и распечатывает Vault после ребута хоста.
|
||
#
|
||
# flux-bootstrap ВЫНЕСЕН в волну 3 намеренно: между волнами Vault получает
|
||
# auth/kubernetes, а репозиторий контура синхронизируется в gitea. Запусти
|
||
# bootstrap раньше — Flux привязался бы к репозиторию, в котором ещё нет ни
|
||
# clusters/aero, ни infrastructure, и первая же реконсиляция упала бы.
|
||
aero_platform_services_wave2:
|
||
- gitea-init
|
||
- flux-k8s-init
|
||
- vault
|
||
- vault-init
|
||
|
||
# Волна 3: bootstrap FluxCD. Запускается после наполнения gitea.
|
||
aero_platform_services_wave3:
|
||
- flux-bootstrap
|
||
|
||
# Ноды k3s. Каждой нужен свой каталог PVC-хранилища на хосте: провижинер
|
||
# local-path node-local, и PV навсегда привязывается к ноде через nodeAffinity.
|
||
aero_k3s_nodes:
|
||
- server
|
||
- worker-1
|
||
- worker-2
|
||
|
||
# Сколько ждать появления kubeconfig от k3s-server, секунд.
|
||
aero_kubeconfig_timeout: 180
|
||
|
||
# --- Интеграция Vault ↔ k3s (метод auth/kubernetes) -------------------------
|
||
# Статический IP контейнера vault в compose-сети. ДОЛЖЕН совпадать с
|
||
# ipv4_address сервиса vault в docker-compose.yaml: отсюда значение
|
||
# подставляется в Endpoints DNS-моста (k3s/manifests/vault/bridge-vault.yaml).
|
||
vault_bridge_ip: 172.28.0.13
|
||
|
||
# Адрес apiserver, по которому Vault валидирует токены подов. Vault живёт в
|
||
# compose, поэтому имя резолвится compose-DNS, а не CoreDNS кластера.
|
||
vault_k8s_host: "https://k3s-server:6443"
|
||
|
||
# Политика чтения kv-v2 на пути secrets/ — том же, что включает vault-init.
|
||
vault_apps_policy: apps-read
|
||
|
||
# TTL выдаваемого агенту токена по умолчанию.
|
||
vault_role_ttl: 24h
|
||
|
||
# Роли auth/kubernetes. Имя роли — то, что приложение указывает в аннотации
|
||
# vault.hashicorp.com/role, namespace — где живут его поды. Пополняется по мере
|
||
# переезда приложений из compose в k3s.
|
||
vault_k8s_roles:
|
||
- {name: postgresql, namespaces: [postgresql]}
|
||
- {name: rabbitmq, namespaces: [rabbitmq]}
|
||
- {name: minio, namespaces: [minio]}
|
||
- {name: django, namespaces: [django]}
|
||
- {name: processing, namespaces: [processing]}
|
||
- {name: measurements, namespaces: [measurements]}
|
||
|
||
# Боевые креды инфраструктурных сервисов. Пути и имена ключей заданы чартами
|
||
# (см. vaultRoot у minio и auth.vault у rabbitmq в infrastructure/*/aero) —
|
||
# менять их в отрыве от values нельзя.
|
||
#
|
||
# Пароли не хранятся в репозитории: берутся из sarex_secrets, который
|
||
# генерирует и персистит в aero/.secrets задача "Сгенерировать/загрузить пароли".
|
||
vault_app_secrets:
|
||
# Пароль администратора PostgreSQL. Имя ключа задано чартом
|
||
# (contour.vault.secretKey) — менять в отрыве от values нельзя.
|
||
- path: secrets/postgresql/admin
|
||
data:
|
||
postgres-password: "{{ sarex_secrets.SAREX_POSTGRES_PASSWORD }}"
|
||
# Пароли владельцев баз. Ключи сопоставляются с passwordKey каждой базы в
|
||
# contour.databases (см. infrastructure/postgresql/aero). Добавляешь базу —
|
||
# добавь сюда ключ, иначе бутстрап не сможет задать роли пароль.
|
||
- path: secrets/postgresql/users
|
||
data:
|
||
django: "{{ sarex_secrets.SAREX_DJANGO_DB_PASSWORD }}"
|
||
processing: "{{ sarex_secrets.SAREX_PROCESSING_DB_PASSWORD }}"
|
||
bim: "{{ sarex_secrets.SAREX_BIM_DB_PASSWORD }}"
|
||
workspace: "{{ sarex_secrets.SAREX_WORKSPACE_DB_PASSWORD }}"
|
||
# --- Секреты приложения django ---------------------------------------------
|
||
# Пути и имена ключей заданы vault-шаблонами в apps/django/base/backend.yaml —
|
||
# менять их в отрыве от манифестов нельзя. Отсутствие любого из них означает
|
||
# не «пустая переменная», а падение vault-agent-init и под в Init:Error.
|
||
- path: secrets/apps/django/postgres
|
||
data:
|
||
host: postgresql.postgresql.svc.cluster.local
|
||
port: "5432"
|
||
database: "{{ sarex_postgres_django_db }}"
|
||
username: "{{ sarex_postgres_django_user }}"
|
||
password: "{{ sarex_secrets.SAREX_DJANGO_DB_PASSWORD }}"
|
||
# В k3s-инстансе RabbitMQ отдельного пользователя под django нет, поэтому
|
||
# используются админские креды и vhost по умолчанию. Это осознанный
|
||
# временный компромисс: завести отдельного пользователя нечем — чарт такой
|
||
# возможности не даёт, а руками это выпадет из GitOps.
|
||
- path: secrets/rabbitmq/apps/django
|
||
data:
|
||
username: "{{ sarex_rabbitmq_k8s_user }}"
|
||
password: "{{ sarex_secrets.SAREX_RABBITMQ_PASSWORD }}"
|
||
vhost: "/"
|
||
# Аналогично MinIO: пользователь приложения не заводится, берём root.
|
||
# buckets — список объектов: шаблон читает index (index $buckets 0) "name".
|
||
- path: secrets/minio/apps/django
|
||
data:
|
||
access_key: "{{ sarex_minio_k8s_user }}"
|
||
secret_key: "{{ sarex_secrets.SAREX_MINIO_ROOT_PASSWORD }}"
|
||
buckets:
|
||
- name: "{{ sarex_django_s3_bucket }}"
|
||
# --- Секреты приложения measurements ---------------------------------------
|
||
# Структура задана vault-шаблоном в apps/measurements/base/backend.yaml: он
|
||
# собирает из этих ключей одну переменную S3_JSON_SETTINGS и читает endpoint
|
||
# ВЛОЖЕННЫМ ключом .Data.data.client.endpoint — отсюда лишний уровень client.
|
||
#
|
||
# Бакет measurements зашит в том же шаблоне и заводится Job'ом
|
||
# infrastructure/minio/aero/buckets-job.yaml.
|
||
#
|
||
# Отдельного пользователя MinIO нет — тот же временный компромисс, что и у
|
||
# django: берём root-креды.
|
||
- path: secrets/minio/apps/measurements
|
||
data:
|
||
client:
|
||
endpoint: http://minio.minio.svc.cluster.local:9000
|
||
access_key: "{{ sarex_minio_k8s_user }}"
|
||
secret_key: "{{ sarex_secrets.SAREX_MINIO_ROOT_PASSWORD }}"
|
||
# Учётка администратора платформы. Её разбирает не приложение, а стартовый
|
||
# скрипт пода backend: он экспортирует ключи как DJANGO_SUPERUSER_* — ровно
|
||
# те имена, которые ждёт штатная manage.py createsuperuser --noinput.
|
||
# См. apps/django/aero/kustomization.yaml.
|
||
- path: secrets/apps/django/superuser
|
||
data:
|
||
username: "{{ superuser_name }}"
|
||
password: "{{ superuser_password }}"
|
||
email: "{{ superuser_name }}@{{ platform_domain }}"
|
||
# JWT-ключи RS512. Те же самые, что роль генерирует для compose-стека, —
|
||
# контур переезжает, и токены должны остаться совместимыми.
|
||
- path: secrets/vault/common/rsa_keys
|
||
data:
|
||
private_key: "{{ lookup('file', jwt_private_key_path) }}"
|
||
public_key: "{{ lookup('file', jwt_public_key_path) }}"
|
||
- path: secrets/rabbitmq/auth
|
||
data:
|
||
username: "{{ sarex_rabbitmq_k8s_user }}"
|
||
password: "{{ sarex_secrets.SAREX_RABBITMQ_PASSWORD }}"
|
||
- path: secrets/minio/admin
|
||
data:
|
||
rootUser: "{{ sarex_minio_k8s_user }}"
|
||
rootPassword: "{{ sarex_secrets.SAREX_MINIO_ROOT_PASSWORD }}"
|
||
|
||
# Логины сервисов в k3s. Совпадают со значениями в .env.example для
|
||
# одноимённых сервисов compose; пароли к ним — в sarex_secrets (те же
|
||
# переменные: контур переезжает в k3s, плодить вторую пару кредов незачем).
|
||
sarex_rabbitmq_k8s_user: rabbit
|
||
sarex_minio_k8s_user: minioadmin
|
||
|
||
# Параметры подключения django к общей СУБД контура. Должны совпадать с
|
||
# соответствующей записью в contour.databases (infrastructure/postgresql/aero).
|
||
sarex_postgres_django_db: sarex_db
|
||
sarex_postgres_django_user: django
|
||
|
||
# Бакет медиафайлов django. ВНИМАНИЕ: чарт MinIO бакеты не создаёт — его нужно
|
||
# завести отдельно, иначе загрузка файлов будет падать.
|
||
sarex_django_s3_bucket: sarex-media-storage
|
||
|
||
# Сервисы приложения, поднимаемые при sarex_compose_up (depends_on тянет
|
||
# зависимости и порядок). k3s/gitea намеренно не поднимаем.
|
||
sarex_services:
|
||
# k3s + провижининг DNS-моста (нужны engine'у до старта)
|
||
- k3s-server
|
||
- processing-k8s-init
|
||
- postgres
|
||
- postgres-init
|
||
- redis
|
||
- rabbitmq
|
||
- minio
|
||
- minio-init
|
||
- measurements
|
||
- s3-proxy
|
||
- backend
|
||
- celery
|
||
- frontend
|
||
- processing-api
|
||
- processing-frontend
|
||
- engine
|
||
- nginx
|
||
|
||
# Namespace прикладного слоя django в k3s. Используется задачей создания
|
||
# суперпользователя (tasks/main.yml) — backend переехал из compose в кластер.
|
||
django_namespace: django
|