Processing в контуре aero: api и engine-low

Развёрнут частично, и это осознанно:
  * engine удалён — в base у него replicaCount 0, то есть он выключен и там,
    а образ прибит к тегу с опечаткой в имени (workflows-endigne_prod);
  * frontend удалён — адреса бэкендов зашиты в образ на этапе сборки через
    __BUILD_ENV__, и ни один готовый профиль не смотрит на домен контура.
    Подключать его имеет смысл только вместе с пересборкой образа.

Отключены смежные сервисы, которых в контуре нет: documentations (PDM,
filestream), resources, bim-api, workspace, issues, comparisons, mailgun,
SMTP. Оставлен только S3. Вместе с флагом ENABLE_SMTP убрана аннотация
инжекции secrets/vault/common/smtp_auth — секрета нет, и vault-agent-init
оставил бы под в Init:Error, не дойдя до флага.

S3 приезжает из Vault отдельным файлом: приложение читает по пути из
S3_SERVICE_ACCOUNT целый JSON, а не пару переменных. Набор ключей повторяет
engine/yc-s3-service-account.json из compose-стека, который так же смотрел
в MinIO.

Планирование подов задач: engine работает kubernetes-исполнителем и сам
создаёт Job'ы, подставляя им nodeSelector dedicated=processing. Выделенных
нод в контуре нет, поды висли бы в Pending — как это уже было у postgresql.
ENABLE_TOLERATION и DEFAULT_NODE_SELECTOR_* сняты.

Заодно у celery поправлены четыре адреса на wb.sarex.io — чужой контур,
недостижимый из aero. У backend те же переменные уже вели внутрь кластера;
при WORKFLOWS_USE=1 расхождение давало бы зависания вместо явной ошибки.

Патчи адресуются по индексу env, поэтому перед каждым replace стоит op: test
на имя переменной: смена порядка в base уронит сборку явно, а не перезапишет
соседнее значение.
This commit is contained in:
emelinda 2026-08-08 20:51:02 +03:00
parent 51b9120797
commit c7c194feaa
4 changed files with 277 additions and 0 deletions

View File

@ -86,6 +86,7 @@ registry_secrets:
# Образы backend и frontend лежат в приватном cr.yandex. # Образы backend и frontend лежат в приватном cr.yandex.
- {name: regcred, namespace: django} - {name: regcred, namespace: django}
- {name: regcred, namespace: measurements} - {name: regcred, namespace: measurements}
- {name: regcred, namespace: processing}
# Поднимать стек (docker compose up -d). Требует запущенной службы docker и # Поднимать стек (docker compose up -d). Требует запущенной службы docker и
# docker login в cr.yandex — по умолчанию выключено. # docker login в cr.yandex — по умолчанию выключено.
@ -131,6 +132,7 @@ gitea_sync_paths:
# Прикладной слой. # Прикладной слой.
- apps/django - apps/django
- apps/measurements - apps/measurements
- apps/processing
# Рабочая копия репозитория gitea на хосте (клон, живёт между прогонами). # Рабочая копия репозитория gitea на хосте (клон, живёт между прогонами).
gitea_sync_workdir: "{{ deploy_dir }}/gitea-sync" gitea_sync_workdir: "{{ deploy_dir }}/gitea-sync"
@ -266,6 +268,39 @@ vault_app_secrets:
secret_key: "{{ sarex_secrets.SAREX_MINIO_ROOT_PASSWORD }}" secret_key: "{{ sarex_secrets.SAREX_MINIO_ROOT_PASSWORD }}"
buckets: buckets:
- name: "{{ sarex_django_s3_bucket }}" - name: "{{ sarex_django_s3_bucket }}"
# --- Секреты приложения processing ------------------------------------------
# Пути и имена ключей заданы vault-шаблонами в apps/processing/base —
# менять их в отрыве от манифестов нельзя.
#
# Владелец workflow_db в контуре — роль processing (см. contour.databases в
# infrastructure/postgresql/aero). В yc-k8s-test та же база принадлежит роли
# workflow; здесь имя другое, и пароль берётся из соответствующего ключа
# secrets/postgresql/users.
- path: secrets/apps/processing/postgres
data:
host: postgresql.postgresql.svc.cluster.local
port: "5432"
database: "{{ sarex_postgres_processing_db }}"
username: "{{ sarex_postgres_processing_user }}"
password: "{{ sarex_secrets.SAREX_PROCESSING_DB_PASSWORD }}"
# Как и у django — админские креды вместо отдельного пользователя.
# Хост и порт брокера чарт не читает отсюда: они захардкожены внутри
# vault-шаблона в apps/processing/base/engine-low.yaml.
- path: secrets/rabbitmq/apps/processing
data:
username: "{{ sarex_rabbitmq_k8s_user }}"
password: "{{ sarex_secrets.SAREX_RABBITMQ_PASSWORD }}"
# S3 для engine и api. Формат — не пары ключ-значение, а ЦЕЛЫЙ JSON-файл:
# переменная S3_SERVICE_ACCOUNT содержит путь к нему, а не сами креды.
# Набор ключей повторяет engine/yc-s3-service-account.json из compose-стека,
# который точно так же смотрел в MinIO.
- path: secrets/minio/apps/processing
data:
host: http://minio.minio.svc.cluster.local:9000
bucket: "{{ sarex_django_s3_bucket }}"
access_key_id: "{{ sarex_minio_k8s_user }}"
secret_access_key: "{{ sarex_secrets.SAREX_MINIO_ROOT_PASSWORD }}"
region: us-east-1
# --- Секреты приложения measurements --------------------------------------- # --- Секреты приложения measurements ---------------------------------------
# Структура задана vault-шаблоном в apps/measurements/base/backend.yaml: он # Структура задана vault-шаблоном в apps/measurements/base/backend.yaml: он
# собирает из этих ключей одну переменную S3_JSON_SETTINGS и читает endpoint # собирает из этих ключей одну переменную S3_JSON_SETTINGS и читает endpoint
@ -317,6 +352,11 @@ sarex_minio_k8s_user: minioadmin
sarex_postgres_django_db: sarex_db sarex_postgres_django_db: sarex_db
sarex_postgres_django_user: django sarex_postgres_django_user: django
# То же для processing. Должно совпадать с записью workflow_db в
# contour.databases (infrastructure/postgresql/aero).
sarex_postgres_processing_db: workflow_db
sarex_postgres_processing_user: processing
# Бакет медиафайлов django. ВНИМАНИЕ: чарт MinIO бакеты не создаёт — его нужно # Бакет медиафайлов django. ВНИМАНИЕ: чарт MinIO бакеты не создаёт — его нужно
# завести отдельно, иначе загрузка файлов будет падать. # завести отдельно, иначе загрузка файлов будет падать.
sarex_django_s3_bucket: sarex-media-storage sarex_django_s3_bucket: sarex-media-storage

View File

@ -64,6 +64,35 @@ patches:
set +a set +a
exec celery -A config worker -B -l info -E -Q default -n default_worker.%h --concurrency=2 exec celery -A config worker -B -l info -E -Q default -n default_worker.%h --concurrency=2
# Адреса на wb.sarex.io — чужой контур, из aero недостижим. В base их
# четыре, и все четыре у celery: у backend те же переменные уже указывают
# внутрь кластера. WORKFLOWS_USE=1, так что оставить как есть — значит
# получить зависания на недоступном домене вместо явной ошибки.
- op: test
path: /spec/values/services/celery/envs/15/name
value: SERVER_API_HOST
- op: replace
path: /spec/values/services/celery/envs/15/value/_default
value: https://sarex.local.lonsdaleites.ru
- op: test
path: /spec/values/services/celery/envs/16/name
value: SERVER_HOST
- op: replace
path: /spec/values/services/celery/envs/16/value/_default
value: https://sarex.local.lonsdaleites.ru
- op: test
path: /spec/values/services/celery/envs/17/name
value: WORKFLOWS_HOST
- op: replace
path: /spec/values/services/celery/envs/17/value/_default
value: http://backend-svc.processing.svc.cluster.local:80
- op: test
path: /spec/values/services/celery/envs/18/name
value: WORKFLOWS_BASE_HOST
- op: replace
path: /spec/values/services/celery/envs/18/value/_default
value: http://backend-svc.django.svc.cluster.local:80
# Тег образа выравнен с backend. В base у celery production_a96dead0, а у # Тег образа выравнен с backend. В base у celery production_a96dead0, а у
# backend production_f813140d — worker и web крутили бы разный код, и # backend production_f813140d — worker и web крутили бы разный код, и
# рассинхрон вылезал бы не при старте, а на конкретной задаче: worker # рассинхрон вылезал бы не при старте, а на конкретной задаче: worker

View File

@ -0,0 +1,205 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: processing
resources:
- ../base
patches:
# --- Состав: только api и engine-low ---------------------------------------
# engine удалён: в base у него replicaCount 0, то есть он и там выключен, а
# образ прибит к тегу с опечаткой в имени (workflows-endigne_prod). Рабочий
# обработчик — engine-low, он же на более свежем образе contour_*.
- target: {kind: HelmRelease, name: engine}
patch: |
$patch: delete
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: engine
namespace: processing
# frontend удалён: адреса бэкендов зашиты в образ на этапе сборки через
# __BUILD_ENV__, и ни один из готовых профилей не смотрит на домен контура.
# Подключать его имеет смысл только вместе с пересборкой образа под aero.
- target: {kind: HelmRelease, name: frontend}
patch: |
$patch: delete
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: frontend
namespace: processing
# --- workflows-api ----------------------------------------------------------
- target: {kind: HelmRelease, name: workflows-api}
patch: |
# S3 приезжает из Vault отдельным ФАЙЛОМ, а не парой переменных:
# приложение читает по этому пути целый JSON. В base путь ведёт в
# /etc/sarex/yc-s3/, куда в контуре ничего не смонтировано.
- op: test
path: /spec/values/services/backend/envs/3/name
value: S3_SERVICE_ACCOUNT
- op: replace
path: /spec/values/services/backend/envs/3/value/_default
value: /vault/secrets/processing-s3
- op: add
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-processing-s3
value: secrets/data/minio/apps/processing
- op: add
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-processing-s3
value: |-
{{- with secret "secrets/data/minio/apps/processing" -}}
{
"host": "{{ index .Data.data "host" }}",
"bucket": "{{ index .Data.data "bucket" }}",
"access_key_id": "{{ index .Data.data "access_key_id" }}",
"secret_access_key": "{{ index .Data.data "secret_access_key" }}",
"region": "{{ index .Data.data "region" }}",
"verify": false
}
{{- end -}}
# --- engine-low -------------------------------------------------------------
# Патчи адресуются по индексу, поэтому перед каждым replace идёт op: test на
# имя переменной. Если в base порядок envs изменится, сборка упадёт явно,
# вместо того чтобы молча перезаписать соседнее значение.
- target: {kind: HelmRelease, name: engine-low}
patch: |
# Sentry — внешний домен, из контура недостижим. Значение прокидывается
# ещё и в каждый под задачи, поэтому зануляем в одном месте.
- op: test
path: /spec/values/services/backend/envs/2/name
value: WORKFLOWS_SENTRY_DSN
- op: replace
path: /spec/values/services/backend/envs/2/value/_default
value: ""
# В base адрес django неверный даже для кластеров, где он есть: сервис
# называется backend-svc и слушает 80, а не backend:8000. У api то же
# значение уже правильное.
- op: test
path: /spec/values/services/backend/envs/5/name
value: DJANGO_HOST
- op: replace
path: /spec/values/services/backend/envs/5/value/_default
value: http://backend-svc.django.svc.cluster.local:80
# S3 — как у api выше.
- op: test
path: /spec/values/services/backend/envs/6/name
value: S3_SERVICE_ACCOUNT
- op: replace
path: /spec/values/services/backend/envs/6/value/_default
value: /vault/secrets/processing-s3
# SMTP выключаем целиком: почтового релея в контуре нет. Вместе с флагом
# убираем аннотацию инжекции secrets/vault/common/smtp_auth — секрета в
# Vault нет, а vault-agent-init на несуществующем секрете не отрендерит
# шаблон и оставит под в Init:Error, до флага дело не дойдёт.
- op: test
path: /spec/values/services/backend/envs/22/name
value: ENABLE_SMTP
- op: replace
path: /spec/values/services/backend/envs/22/value/_default
value: "0"
- op: remove
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-processing-smtp
- op: remove
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-processing-smtp
# Смежные сервисы, которых в контуре нет: documentations (PDM,
# filestream), resources, bim-api, workspace, issues, comparisons,
# mailgun. Оставляем только S3 — единственное внешнее хранилище, которое
# в aero действительно есть.
- op: test
path: /spec/values/services/backend/envs/21/name
value: ENABLE_PDM_STORAGE
- op: replace
path: /spec/values/services/backend/envs/21/value/_default
value: "0"
- op: test
path: /spec/values/services/backend/envs/25/name
value: ENABLE_BIM_API_V2_DB
- op: replace
path: /spec/values/services/backend/envs/25/value/_default
value: "0"
- op: test
path: /spec/values/services/backend/envs/26/name
value: ENABLE_WORKSPACE_API_DB
- op: replace
path: /spec/values/services/backend/envs/26/value/_default
value: "0"
- op: test
path: /spec/values/services/backend/envs/27/name
value: ENABLE_ISSUE_API_DB
- op: replace
path: /spec/values/services/backend/envs/27/value/_default
value: "0"
- op: test
path: /spec/values/services/backend/envs/28/name
value: ENABLE_RESOURCES_API
- op: replace
path: /spec/values/services/backend/envs/28/value/_default
value: "0"
- op: test
path: /spec/values/services/backend/envs/30/name
value: ENABLE_PDM_API_DB
- op: replace
path: /spec/values/services/backend/envs/30/value/_default
value: "0"
- op: test
path: /spec/values/services/backend/envs/31/name
value: ENABLE_COMPARISONS_API_DB
- op: replace
path: /spec/values/services/backend/envs/31/value/_default
value: "0"
- op: test
path: /spec/values/services/backend/envs/32/name
value: ENABLE_MAIL_GUN
- op: replace
path: /spec/values/services/backend/envs/32/value/_default
value: "0"
# Планирование подов задач. engine работает kubernetes-исполнителем и сам
# создаёт Job'ы, подставляя им nodeSelector dedicated=processing и
# соответствующий toleration. Выделенных нод в контуре нет — все три
# равнозначны, — поэтому поды задач висли бы в Pending с
# didn't match Pod's node affinity/selector
# ровно как это было у postgresql (см. postRenderers в его релизе).
- op: test
path: /spec/values/services/backend/envs/66/name
value: ENABLE_TOLERATION
- op: replace
path: /spec/values/services/backend/envs/66/value/_default
value: "0"
- op: test
path: /spec/values/services/backend/envs/69/name
value: DEFAULT_NODE_SELECTOR_KEY
- op: replace
path: /spec/values/services/backend/envs/69/value/_default
value: ""
- op: test
path: /spec/values/services/backend/envs/70/name
value: DEFAULT_NODE_SELECTOR_VALUE
- op: replace
path: /spec/values/services/backend/envs/70/value/_default
value: ""
# S3 из Vault, как у api.
- op: add
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-processing-s3
value: secrets/data/minio/apps/processing
- op: add
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-processing-s3
value: |-
{{- with secret "secrets/data/minio/apps/processing" -}}
{
"host": "{{ index .Data.data "host" }}",
"bucket": "{{ index .Data.data "bucket" }}",
"access_key_id": "{{ index .Data.data "access_key_id" }}",
"secret_access_key": "{{ index .Data.data "secret_access_key" }}",
"region": "{{ index .Data.data "region" }}",
"verify": false
}
{{- end -}}

View File

@ -6,3 +6,6 @@ resources:
# Сервис измерений. Django обращается к нему при MEASUREMENTS_USE_MEASUREMENTS=1 # Сервис измерений. Django обращается к нему при MEASUREMENTS_USE_MEASUREMENTS=1
# (значение по умолчанию в base), поэтому без него часть API отвечает ошибкой. # (значение по умолчанию в base), поэтому без него часть API отвечает ошибкой.
- ../../../apps/measurements/aero - ../../../apps/measurements/aero
# Движок workflow. Развёрнут частично: только api и engine-low, без
# собственного фронтенда — подробности в apps/processing/aero.
- ../../../apps/processing/aero