Развёрнут частично, и это осознанно:
* 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 уронит сборку явно, а не перезапишет
соседнее значение.
213 lines
13 KiB
YAML
213 lines
13 KiB
YAML
---
|
||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||
kind: Kustomization
|
||
namespace: django
|
||
resources:
|
||
- ../base
|
||
|
||
patches:
|
||
# Свой nginx.conf вместо базового: в base зашиты upstream'ы на namespace,
|
||
# которых в контуре нет, и nginx из-за этого не стартовал. Подробности —
|
||
# в шапке nginx-configmap.yaml.
|
||
#
|
||
# ИМЕННО ПАТЧ, а не resources. Объект с тем же kind+name уже пришёл из
|
||
# ../base, и добавление его вторым ресурсом валит сборку целиком:
|
||
# may not add resource with an already registered id:
|
||
# ConfigMap.v1.[noGrp]/nginx-configmap.django
|
||
# Перекрывать базовый ресурс можно только патчем.
|
||
- path: nginx-configmap.yaml
|
||
target:
|
||
kind: ConfigMap
|
||
name: nginx-configmap
|
||
# --- celery: те же правки, что и у backend --------------------------------
|
||
# Worker крутит тот же образ и те же настройки, поэтому и расхождения с base
|
||
# у него ровно те же: нет Kafka, нет Zitadel, MinIO живёт внутри кластера.
|
||
# Обоснования — в блоке backend ниже, здесь не дублирую.
|
||
#
|
||
# SERVER_ZITADEL_ENABLED правки не требует: в base у celery он уже "False"
|
||
# (в отличие от backend).
|
||
- target: {kind: HelmRelease, name: celery}
|
||
patch: |
|
||
- op: remove
|
||
path: /spec/values/services/celery/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-django-kafka
|
||
- op: remove
|
||
path: /spec/values/services/celery/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-django-kafka
|
||
- op: remove
|
||
path: /spec/values/services/celery/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-django-common
|
||
- op: remove
|
||
path: /spec/values/services/celery/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-django-common
|
||
- op: replace
|
||
path: /spec/values/services/celery/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-django-s3
|
||
value: |-
|
||
{{- with secret "secrets/data/minio/apps/django" }}
|
||
AWS_S3_ENDPOINT_URL=http://minio.minio.svc.cluster.local:9000
|
||
S3_HOST=http://minio.minio.svc.cluster.local:9000
|
||
{{- $buckets := index .Data.data "buckets" }}
|
||
S3_BUCKET={{ if gt (len $buckets) 0 }}{{ index (index $buckets 0) "name" }}{{ else }}django{{ end }}
|
||
S3_LOGIN={{ index .Data.data "access_key" }}
|
||
S3_PASSWORD={{ index .Data.data "secret_key" }}
|
||
{{- end }}
|
||
|
||
# Стартовый скрипт без подключения django-kafka: этого секрета в контуре
|
||
# нет. migrate и создание администратора сюда НЕ добавляются — схемой
|
||
# владеет backend, а два процесса, катящих миграции наперегонки при
|
||
# одновременном старте, — это гонка на ровном месте.
|
||
- op: replace
|
||
path: /spec/values/services/celery/deployment/args/_default/0
|
||
value: |
|
||
set -a
|
||
[ -f /vault/secrets/django-postgresql ] && . /vault/secrets/django-postgresql
|
||
[ -f /vault/secrets/django-rabbitmq ] && . /vault/secrets/django-rabbitmq
|
||
[ -f /vault/secrets/django-s3 ] && . /vault/secrets/django-s3
|
||
[ -f /vault/secrets/django-jwt-private ] && export JWT_PRIVATE_KEY="$(cat /vault/secrets/django-jwt-private)"
|
||
[ -f /vault/secrets/django-jwt-public ] && export JWT_PUBLIC_KEY="$(cat /vault/secrets/django-jwt-public)"
|
||
set +a
|
||
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 production_f813140d — worker и web крутили бы разный код, и
|
||
# рассинхрон вылезал бы не при старте, а на конкретной задаче: worker
|
||
# десериализует аргументы по своей версии модели.
|
||
- op: replace
|
||
path: /spec/values/services/celery/image/name/_default
|
||
value: cr.yandex/crp3ccidau046kdj8g9q/backend:production_f813140d
|
||
|
||
# --- backend: убираем зависимости, которых в контуре нет ------------------
|
||
- target: {kind: HelmRelease, name: backend}
|
||
patch: |
|
||
# Kafka и Zitadel в контуре не развёрнуты. Само приложение без них живёт:
|
||
# * SERVER_KAFKA_ENABLED в base уже "False", а в sarex-backend продюсер
|
||
# создаётся только под флагом (config/settings/deps/kafka.py);
|
||
# * zitadel_enabled читается ровно в одном месте — update_ams_user()
|
||
# в sarex/core/utils.py, которая при выключенном флаге сразу выходит.
|
||
# К аутентификации Zitadel отношения не имеет.
|
||
#
|
||
# Но аннотации инжекции убрать ОБЯЗАТЕЛЬНО: vault-agent-init не отрендерит
|
||
# шаблон для несуществующего секрета, упадёт, и под навсегда останется в
|
||
# Init:Error — приложение до своих флагов даже не дойдёт.
|
||
#
|
||
# В JSON Pointer слэш внутри ключа экранируется как ~1, поэтому
|
||
# vault.hashicorp.com/agent-... записан как vault.hashicorp.com~1agent-...
|
||
- op: remove
|
||
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-django-kafka
|
||
- op: remove
|
||
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-django-kafka
|
||
- op: remove
|
||
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-django-common
|
||
- op: remove
|
||
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-django-common
|
||
|
||
# S3 внутри кластера, а не через внешний домен. В base шаблон прибит к
|
||
# https://minio.contour.infra.sarex.tech — чужому домену, который отсюда
|
||
# не резолвится. Через values это не перекрыть: адрес зашит ВНУТРИ
|
||
# vault-шаблона аннотации, поэтому заменяем аннотацию целиком.
|
||
# Ходим напрямую в сервис MinIO, как это делал compose-стек.
|
||
- op: replace
|
||
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-django-s3
|
||
value: |-
|
||
{{- with secret "secrets/data/minio/apps/django" }}
|
||
AWS_S3_ENDPOINT_URL=http://minio.minio.svc.cluster.local:9000
|
||
S3_HOST=http://minio.minio.svc.cluster.local:9000
|
||
{{- $buckets := index .Data.data "buckets" }}
|
||
S3_BUCKET={{ if gt (len $buckets) 0 }}{{ index (index $buckets 0) "name" }}{{ else }}django{{ end }}
|
||
S3_LOGIN={{ index .Data.data "access_key" }}
|
||
S3_PASSWORD={{ index .Data.data "secret_key" }}
|
||
{{- end }}
|
||
|
||
# Выключаем Zitadel. Операция test перед replace — страховка от смещения
|
||
# индекса: если в base порядок envs изменится, патч упадёт явно, вместо
|
||
# того чтобы молча перезаписать соседнюю переменную.
|
||
- op: test
|
||
path: /spec/values/services/backend/envs/2/name
|
||
value: SERVER_ZITADEL_ENABLED
|
||
- op: replace
|
||
path: /spec/values/services/backend/envs/2/value/_default
|
||
value: "False"
|
||
|
||
# --- Администратор платформы --------------------------------------------
|
||
# Учётка приезжает из Vault под именами, которые ждёт штатная
|
||
# createsuperuser --noinput. Секрет кладёт ansible
|
||
# (vault_app_secrets, secrets/apps/django/superuser).
|
||
- op: add
|
||
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-django-superuser
|
||
value: secrets/data/apps/django/superuser
|
||
- op: add
|
||
path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-django-superuser
|
||
value: |-
|
||
{{- with secret "secrets/data/apps/django/superuser" -}}
|
||
DJANGO_SUPERUSER_USERNAME={{ index .Data.data "username" }}
|
||
DJANGO_SUPERUSER_EMAIL={{ index .Data.data "email" }}
|
||
DJANGO_SUPERUSER_PASSWORD={{ index .Data.data "password" }}
|
||
{{- end -}}
|
||
|
||
# Стартовый скрипт целиком, а не точечная правка: JSON6902 умеет заменять
|
||
# только элемент списка, а вся логика запуска — один shell-блок args[0].
|
||
# Отличия от base:
|
||
# * не подключается django-kafka — этого секрета в контуре нет;
|
||
# * добавлены migrate и создание администратора.
|
||
#
|
||
# Почему migrate здесь, хотя его же делает /opt/sarex/entrypoint.sh:
|
||
# там он запущен без set -e, и его падение НИКАК не мешает uwsgi
|
||
# стартовать. Именно так контур несколько часов отдавал 200 на /admin/
|
||
# с пустой схемой БД, пока backend не мог аутентифицироваться. Здесь
|
||
# команда выполняется под set -e из command базы (/bin/sh -ec), поэтому
|
||
# неудача валит под в CrashLoopBackOff — то есть становится видимой.
|
||
# Повторный прогон внутри entrypoint.sh при уже накатанной схеме
|
||
# отрабатывает вхолостую за секунды.
|
||
- op: replace
|
||
path: /spec/values/services/backend/deployment/args/_default/0
|
||
value: |
|
||
set -a
|
||
[ -f /vault/secrets/django-postgresql ] && . /vault/secrets/django-postgresql
|
||
[ -f /vault/secrets/django-rabbitmq ] && . /vault/secrets/django-rabbitmq
|
||
[ -f /vault/secrets/django-s3 ] && . /vault/secrets/django-s3
|
||
[ -f /vault/secrets/django-superuser ] && . /vault/secrets/django-superuser
|
||
[ -f /vault/secrets/django-jwt-private ] && export JWT_PRIVATE_KEY="$(cat /vault/secrets/django-jwt-private)"
|
||
[ -f /vault/secrets/django-jwt-public ] && export JWT_PUBLIC_KEY="$(cat /vault/secrets/django-jwt-public)"
|
||
set +a
|
||
|
||
python manage.py migrate --noinput
|
||
|
||
# Идемпотентно по построению: команда отрабатывает при КАЖДОМ старте
|
||
# пода, а на уже существующем логине штатно возвращает
|
||
# "That username is already taken" с ненулевым кодом. Ошибка ожидаема
|
||
# и гасится веткой else, иначе set -e ронял бы под на втором запуске.
|
||
if [ -n "${DJANGO_SUPERUSER_USERNAME:-}" ]; then
|
||
if python manage.py createsuperuser --noinput; then
|
||
echo "entrypoint: администратор создан"
|
||
else
|
||
echo "entrypoint: администратор уже существует, пропускаем"
|
||
fi
|
||
fi
|
||
|
||
exec /opt/sarex/entrypoint.sh
|