Commit Graph

1082 Commits

Author SHA1 Message Date
emelinda
237dcb9b28 RabbitMQ: снят loopback-only для администратора
Celery не поднимался: worker падал в CrashLoopBackOff на
amqp.exceptions.AccessRefused (403) при подключении к брокеру.

Диагностика уводила в сторону — 403 читается как несовпадение пароля, но
пароль был верный: хеши значения в Vault, в файле, смонтированном в под
брокера, и в собранном BROKER_URL совпадали, а rabbitmqctl authenticate_user
с ним проходил. Настоящая причина нашлась в логе брокера:

  PLAIN login refused: user 'rabbit' can only connect via localhost

Пользователю разрешён вход только с localhost, поэтому отбивалось любое
подключение из кластера — и по той же причине в management UI нельзя было
войти снаружи.

Лечится так же, как в d8-ugmk-prod: флагом auth.enableLoopbackUser и
дублирующим advancedConfiguration. Дубль не избыточен — флаг лишь пишет в
rabbitmq.conf строку "loopback_users.<user> = false", которую брокер не
применяет: в рантайме loopback_users всё равно оставался [<<"rabbit">>].
Значение задаёт именно advanced.config.
2026-08-08 18:32:38 +03:00
emelinda
c2a9bae0db Celery включён в контуре aero
Worker был отключён патчем удаления, пока не было очередей. RabbitMQ и MinIO
развёрнуты, схема БД накачена — включаем.

Расхождения с base у celery ровно те же, что у backend: нет Kafka, MinIO
живёт внутри кластера. Аннотации инжекции несуществующих секретов убраны —
иначе vault-agent-init не отрендерит шаблон и под навсегда останется в
Init:Error. SERVER_ZITADEL_ENABLED не трогаем: в base у celery он уже False.

Миграции и создание администратора в стартовый скрипт worker'а намеренно НЕ
добавлены: схемой владеет backend, а два процесса, катящих миграции при
одновременном старте, — гонка на ровном месте.

Тег образа выравнен с backend (production_f813140d вместо production_a96dead0).
Разные версии кода у web и worker ломаются не при старте, а на конкретной
задаче, когда worker десериализует аргументы по своей версии модели.
2026-08-08 18:12:32 +03:00
emelinda
bddcc955fe Создание администратора платформы перенесено в под backend
Учётка создавалась задачей ansible через kubectl exec — по явной команде
оператора и в обход GitOps. Теперь это делает сам под при каждом старте:
стартовый скрипт подхватывает креды из Vault и вызывает штатную
createsuperuser --noinput.

Идемпотентность обеспечена ветвлением, а не подавлением ошибки: на уже
существующем логине Django возвращает "That username is already taken" с
ненулевым кодом, что под set -e из command базы уронило бы под на втором
запуске. Ошибка ожидаема и гасится веткой else.

Заодно в стартовый скрипт добавлен migrate. В entrypoint.sh образа он уже
есть, но запущен без set -e — его падение не мешает uwsgi стартовать.
Именно так контур несколько часов отдавал 200 на /admin/ с пустой схемой:
backend не мог аутентифицироваться в СУБД, миграции падали, приложение
работало. Здесь команда идёт под set -e, поэтому отказ виден сразу.

Ansible остаётся владельцем значений: генерирует логин и пароль (теперь
безусловно, а не по флагу — их ждёт vault-agent) и кладёт в
secrets/apps/django/superuser. Задача poe superuser печатает креды.

Убраны временные диагностические задачи с ignore_errors, добавленные при
разборе отказа createsuperuser.
2026-08-08 18:10:19 +03:00
emelinda
ee1881e516 feat(aero): django в k3s — backend, frontend, s3-proxy и выход наружу
Первый прикладной сервис переехал из compose в кластер. Развёрнуты backend,
frontend, redis, srx-admin и s3-proxy; celery выключен до следующего шага.
Платформа доступна по https://sarex.local.lonsdaleites.ru — корень отдаёт
frontend, /api/ и /admin/ уходят в backend, /media/ в s3-proxy.

Kafka и Zitadel в контуре не развёрнуты, и приложению они не нужны:
SERVER_KAFKA_ENABLED в base уже False, а zitadel_enabled в sarex-backend
читается ровно в одном месте — update_ams_user(), которая при выключенном
флаге сразу выходит. Но аннотации инжекции этих секретов пришлось убрать:
vault-agent-init не рендерит шаблон для несуществующего секрета и роняет под
в Init:Error ещё до старта приложения.

nginx-configmap заменён целиком. В base зашиты upstream'ы на namespace pm,
workspaces и processing; nginx резолвит их при старте и падал с
"host not found in upstream". pm убран как ненужный, для остальных двух
адрес вынесен в переменную с resolver — их резолвинг откладывается до
запроса, поэтому появление сервисов позже не потребует правки конфига.
Заменять пришлось именно патчем: объект с тем же kind+name уже приходит из
base, и добавление его в resources валит сборку слоя целиком.

Секреты django в Vault: postgres, rabbitmq, minio и общие RSA-ключи JWT.
RabbitMQ и MinIO подключены под административными кредами — отдельных
пользователей приложения чарты создавать не умеют, это осознанный долг.

Задача создания суперпользователя переписана с docker compose exec на
kubectl exec. ВНИМАНИЕ: она пока НЕ РАБОТАЕТ — команда падает, вывод скрыт
no_log. Механизм проверен отдельно и исправен, значит ошибка на стороне
Django. Чтобы увидеть причину, нужно временно снять no_log.
2026-08-08 16:49:16 +03:00
emelinda
8e14cd1e0b feat(aero): PostgreSQL с четырьмя базами и ускоренный цикл реконсиляции
PostgreSQL разворачивается пустым инстансом, состав баз повторяет то, что
сейчас провижинит postgres-init в compose:
  sarex_db     -> django       (ltree)
  workflow_db  -> processing   (uuid-ossp, ltree, hstore)
  bim_db       -> bim
  workspace_db -> workspace
Пароли администратора и владельцев берутся из Vault через
vault-agent-injector, в репозитории их нет. Расширения создаёт бутстрап
заранее: роли не суперпользователи и CREATE EXTENSION в миграциях им
недоступен. timescaledb включён в shared_preload_libraries сразу, хотя этим
базам не нужен, — параметр читается только при старте, и добавить его позже
означает перезапуск СУБД.

nodeSelector снимается postRenderers'ом. Чарт по умолчанию ставит
dedicated: sts в расчёте на выделенный пул нод; в контуре таких нет, и под
навсегда повисал в Pending, а следом застревал PVC, потому что у local-path
режим WaitForFirstConsumer. Через values это недостижимо: Helm сливает карты
по ключам, поэтому ни {}, ни другая метка dedicated: sts не убирают.

Цикл реконсиляции сокращён с 10 до 2 минут у всех Kustomization и
HelmRelease контура. Корневая Kustomization патчится из clusters/aero:
её файл генерирует flux bootstrap с пометкой DO NOT EDIT, а флаг --interval
задаёт периодичность только GitRepository. Таймаут установки postgresql
снижен с 20 до 10 минут — он определяет цену одной неудачной итерации.

Отключение собственных Gateway/VirtualService/Certificate чарта rabbitmq
переведено с JSON6902 на postRenderers: kustomize нормализует null в {}, а
пустую карту Helm сливает с дефолтами, поэтому настоящий null до Helm не
доходит ни одним путём.
2026-08-08 11:33:43 +03:00
emelinda
565faa0e17 feat(aero): базовый слой контура — Vault↔k3s, GitOps-синхронизация, выход наружу
Топология k3s: 1 мастер + 2 воркера (убран k3s-worker-3 с томом).

Vault ↔ k3s. Vault живёт в compose, вне кластера, поэтому получает
статический IP 172.28.0.13, DNS-мост в namespace vault и token reviewer
(SA vault-auth + system:auth-delegator). Ansible включает auth/kubernetes,
передавая адрес apiserver, CA и JWT ревьюера явно, и заводит политику с
ролями. Секрет token reviewer'а читается целиком в JSON: вариант
-o jsonpath={.data.ca\.crt} НЕ работает — модуль command разбирает строку
через shlex, съедает обратный слэш, kubectl возвращает пустую строку с
кодом 0, и отказ остаётся незамеченным до падения vault write.

Синхронизация репозитория в gitea. Нужное подмножество путей (замыкание
ссылок clusters/aero) едет архивом на хост и коммитится там: gitea не
публикуется дальше самого хоста, контур остаётся замкнутым. flux-bootstrap
вынесен в отдельную волну — до неё Vault получает auth/kubernetes, а
репозиторий наполняется, иначе первая реконсиляция падает на пустом репо.

Инфраструктура: vault-agent-injector (чарт vault-contour в режиме внешнего
Vault), local-path-provisioner взамен встроенного в k3s (--disable=
local-storage; путь данных прежний), rabbitmq и minio с кредами из Vault.

Выход наружу: порты 80/443 k3s-server опубликованы (istio ingressgateway
занимает эти hostPort), общий contour-gateway на wildcard-хост, сертификат
Let's Encrypt через http01. Имена в сертификате перечислены явно —
http01 не выдаёт wildcard, для них нужен dns01.

Разорваны два дедлока Flux: infra-configs больше не зависит от
infra-controllers (издатели не должны зависеть от здоровья чартов, которые
их используют), istio-config получил disableWait.

Модули ядра iptable_nat и смежные грузятся на хосте: ноды k3s —
контейнеры, istio-init правит iptables через ядро хоста, а на RED OS 8
(nf_tables) legacy-модули не загружены, из-за чего любой под с
istio-injection навсегда вставал в Init:Error.

Собственные Gateway/VirtualService/Certificate чартов rabbitmq и dashboard
отключены — маршрутизация описана централизованно. У rabbitmq это сделано
postRenderers, а не values: kustomize нормализует null в {}, а пустую карту
Helm сливает с дефолтами, возвращая их целиком.
2026-08-08 09:36:08 +03:00
emelinda
da8e40c044 feat(istio): add required empty blocks to prevent nil pointer errors in aero environment configuration 2026-08-03 16:20:37 +03:00
emelinda
4ae7a8286b feat(fluxcd): add Istio gateway HelmRelease configuration with kustomize patching in aero environment 2026-08-03 16:08:12 +03:00
emelinda
b28e5dd27a feat(fluxcd): introduce multi-layer infrastructure setup with kustomize and CRD dependency handling in aero environment 2026-08-03 16:02:35 +03:00
emelinda
037d069c85 feat(fluxcd): add HelmRelease for Istio configuration in aero environment 2026-08-03 15:40:24 +03:00
emelinda
457f0dad41 feat(ansible): add private registry configuration for k3s and Flux with secure key handling 2026-08-03 15:40:07 +03:00
emelinda
8a8cd66f59 feat(ansible): add GitOps foundation (k3s, gitea, vault, and FluxCD) with multi-wave deployment support 2026-08-03 14:49:22 +03:00
emelinda
e39404cb4c Merge branch 'master' of gitlab.sarex.io:infra/iac into aero 2026-08-03 12:19:09 +03:00
ivan
4e59c76096 ++ 2026-08-03 13:55:20 +05:00
fb30bab0b8 ++ prefix uralmine service domains with sarex 2026-08-03 11:06:10 +03:00
a4f1424403 ++ move uralmine service domains up one level 2026-08-03 10:56:18 +03:00
ivan
95f567a62b ++ 2026-08-02 02:06:58 +05:00
ivan
c05003f184 ++ 2026-08-02 02:05:07 +05:00
ivan
c5ccafa21f ++ 2026-08-02 01:53:05 +05:00
ivan
5ea61bd508 ++ 2026-08-02 01:52:18 +05:00
ivan
a99d93f41f ++ 2026-08-02 01:44:15 +05:00
ivan
278919eade ++ 2026-08-02 01:40:23 +05:00
ivan
66cd1a599f ++ 2026-08-02 01:39:54 +05:00
ivan
e069f38cb5 ++ 2026-08-02 01:32:18 +05:00
ivan
f5e278fbbf ++ 2026-08-02 01:20:01 +05:00
ivan
9cb672cf34 ++ 2026-08-02 01:10:27 +05:00
ivan
325aad49da ++ 2026-08-02 00:50:33 +05:00
ivan
38219249b3 ++ 2026-08-02 00:44:21 +05:00
ivan
6c81ba0080 ++ 2026-08-02 00:41:18 +05:00
ivan
c14d74050f ++ 2026-08-02 00:36:36 +05:00
ivan
3dd3c12537 ++ 2026-08-01 15:13:48 +05:00
ivan
d86bc2fbc5 ++ 2026-08-01 14:49:07 +05:00
ivan
7ad5c5f4b1 ++ 2026-08-01 14:41:41 +05:00
ivan
38a357ee64 ++ 2026-08-01 14:21:30 +05:00
ivan
5b2c6b9967 ++ 2026-08-01 14:08:35 +05:00
ivan
950c1a5c51 ++ 2026-08-01 14:00:43 +05:00
ivan
f1043df2da ++ 2026-08-01 13:53:41 +05:00
ivan
a148491f95 ++ 2026-08-01 13:07:29 +05:00
ivan
987e9e3a7f ++ 2026-08-01 12:50:10 +05:00
ivan
50cee9c4d3 ++ 2026-07-31 18:40:52 +05:00
ivan
80da663600 ++ 2026-07-31 17:53:50 +05:00
ivan
c470dacee3 ++ 2026-07-31 17:48:17 +05:00
ivan
ab7611fc7e ++ 2026-07-31 17:47:56 +05:00
ivan
fc9e75945a ++ 2026-07-31 17:42:37 +05:00
ivan
84c51343f9 ++ 2026-07-31 17:32:56 +05:00
ivan
396702429f ++ 2026-07-31 17:10:00 +05:00
ivan
800718737d ++ 2026-07-31 17:01:48 +05:00
ivan
e88027ffa6 ++ 2026-07-31 16:56:56 +05:00
ivan
798648e85d ++ 2026-07-31 16:53:33 +05:00
ivan
e09067365f ++ 2026-07-31 16:26:47 +05:00