Compare commits
No commits in common. "c2a9bae0dbed08a36de7ffbeb6d680a70d83e623" and "8e14cd1e0bc921374d3adeb064c41bff3303f959" have entirely different histories.
c2a9bae0db
...
8e14cd1e0b
@ -44,8 +44,7 @@ platform = "ansible-playbook deploy.yml -e aero_platform_up=true"
|
||||
gen-env = "ansible-playbook deploy.yml --tags env"
|
||||
# docker login в приватный реестр по ключу json_key
|
||||
login = "ansible-playbook deploy.yml --tags login"
|
||||
# Показать логин+пароль администратора платформы. Саму учётку создаёт под
|
||||
# backend при старте (apps/django/aero), эта задача только печатает креды.
|
||||
# Сгенерировать логин+пароль и создать Django-суперпользователя в backend
|
||||
superuser = "ansible-playbook deploy.yml -e sarex_create_superuser=true --tags superuser"
|
||||
lint = "ansible-lint"
|
||||
|
||||
|
||||
@ -83,8 +83,6 @@ registry_secrets:
|
||||
- {name: regcred, namespace: postgresql}
|
||||
- {name: regcred, namespace: rabbitmq}
|
||||
- {name: regcred, namespace: minio}
|
||||
# Образы backend и frontend лежат в приватном cr.yandex.
|
||||
- {name: regcred, namespace: django}
|
||||
|
||||
# Поднимать стек (docker compose up -d). Требует запущенной службы docker и
|
||||
# docker login в cr.yandex — по умолчанию выключено.
|
||||
@ -127,8 +125,6 @@ gitea_sync_paths:
|
||||
- infrastructure/postgresql
|
||||
- infrastructure/rabbitmq
|
||||
- infrastructure/minio
|
||||
# Прикладной слой: django (backend + frontend).
|
||||
- apps/django
|
||||
|
||||
# Рабочая копия репозитория gitea на хосте (клон, живёт между прогонами).
|
||||
gitea_sync_workdir: "{{ deploy_dir }}/gitea-sync"
|
||||
@ -235,49 +231,6 @@ vault_app_secrets:
|
||||
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 }}"
|
||||
# Учётка администратора платформы. Её разбирает не приложение, а стартовый
|
||||
# скрипт пода 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 }}"
|
||||
@ -293,15 +246,6 @@ vault_app_secrets:
|
||||
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:
|
||||
@ -323,7 +267,3 @@ sarex_services:
|
||||
- processing-frontend
|
||||
- engine
|
||||
- nginx
|
||||
|
||||
# Namespace прикладного слоя django в k3s. Используется задачей создания
|
||||
# суперпользователя (tasks/main.yml) — backend переехал из compose в кластер.
|
||||
django_namespace: django
|
||||
|
||||
@ -92,28 +92,6 @@
|
||||
no_log: true
|
||||
tags: [env]
|
||||
|
||||
# Учётка администратора платформы. Живёт отдельно от общего цикла выше по двум
|
||||
# причинам: у логина свой алфавит (Django не примет username со спецсимволами)
|
||||
# и оба значения не должны попасть в .env — compose-стек их не использует,
|
||||
# потребитель один, и это Vault.
|
||||
#
|
||||
# Генерируется всегда, а не по флагу sarex_create_superuser: значения уезжают
|
||||
# в secrets/apps/django/superuser (см. vault_app_secrets), откуда их забирает
|
||||
# стартовый скрипт пода backend. Без них vault-agent не отрендерит шаблон и
|
||||
# под встанет в Init:Error. lookup('password') идемпотентен — на повторных
|
||||
# прогонах возвращает уже сохранённое значение, а не генерирует новое.
|
||||
- name: Сгенерировать/загрузить логин администратора платформы
|
||||
ansible.builtin.set_fact:
|
||||
superuser_name: "{{ lookup('password', secrets_store ~ '/' ~ inventory_hostname ~ '/SAREX_SUPERUSER_NAME chars=ascii_lowercase,digits length=10') }}"
|
||||
no_log: true
|
||||
tags: [env, superuser]
|
||||
|
||||
- name: Сгенерировать/загрузить пароль администратора платформы
|
||||
ansible.builtin.set_fact:
|
||||
superuser_password: "{{ lookup('password', secrets_store ~ '/' ~ inventory_hostname ~ '/SAREX_SUPERUSER_PASSWORD chars=ascii_letters,digits length=' ~ secret_length) }}"
|
||||
no_log: true
|
||||
tags: [env, superuser]
|
||||
|
||||
# RSA-ключи JWT (RS512): генерируем на control-node, persist в secrets_store.
|
||||
- name: Сгенерировать приватный RSA-ключ JWT
|
||||
ansible.builtin.command: "openssl genrsa -out {{ jwt_private_key_path }} 4096"
|
||||
@ -203,16 +181,54 @@
|
||||
changed_when: true
|
||||
tags: [up]
|
||||
|
||||
# --- Django-суперпользователь ----------------------------------------------
|
||||
# Самого создания здесь больше нет — его делает под backend при каждом старте
|
||||
# (apps/django/aero/kustomization.yaml, args стартового скрипта). Так учётка
|
||||
# появляется вместе с приложением, а не отдельной командой оператора, и
|
||||
# переживает пересоздание пода без ручного вмешательства.
|
||||
#
|
||||
# Ansible остаётся владельцем самих значений: генерирует их выше (тег env) и
|
||||
# кладёт в Vault. Здесь — только показать логин по явному запросу
|
||||
# (uv run poe superuser передаёт sarex_create_superuser=true).
|
||||
- name: Показать учётные данные администратора платформы
|
||||
# --- Django-суперпользователь: генерация логина+пароля, создание -----------
|
||||
# Только по явной команде (uv run poe superuser передаёт sarex_create_superuser=true),
|
||||
# чтобы обычный deploy не дёргал backend. Логин/пароль персистятся в secrets_store
|
||||
# (переиспользуются при повторе — идемпотентно).
|
||||
- name: Сгенерировать логин суперпользователя
|
||||
ansible.builtin.set_fact:
|
||||
superuser_name: "{{ lookup('password', secrets_store ~ '/' ~ inventory_hostname ~ '/SAREX_SUPERUSER_NAME chars=ascii_lowercase,digits length=10') }}"
|
||||
when: sarex_create_superuser | default(false) | bool
|
||||
no_log: true
|
||||
tags: [superuser]
|
||||
|
||||
- name: Сгенерировать пароль суперпользователя
|
||||
ansible.builtin.set_fact:
|
||||
superuser_password: "{{ lookup('password', secrets_store ~ '/' ~ inventory_hostname ~ '/SAREX_SUPERUSER_PASSWORD chars=ascii_letters,digits length=' ~ secret_length) }}"
|
||||
when: sarex_create_superuser | default(false) | bool
|
||||
no_log: true
|
||||
tags: [superuser]
|
||||
|
||||
- name: Создать/обновить Django-суперпользователя в backend
|
||||
when: sarex_create_superuser | default(false) | bool
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- "{{ compose_cmd.split()[0] }}"
|
||||
- exec
|
||||
- -e
|
||||
- "SU_NAME={{ superuser_name }}"
|
||||
- -e
|
||||
- "SU_PASS={{ superuser_password }}"
|
||||
- -e
|
||||
- "SU_EMAIL={{ superuser_name }}@{{ platform_domain }}"
|
||||
- sarex-backend
|
||||
- python
|
||||
- manage.py
|
||||
- shell
|
||||
- -c
|
||||
- >-
|
||||
import os;
|
||||
from django.contrib.auth import get_user_model;
|
||||
U = get_user_model();
|
||||
u, c = U.objects.get_or_create(username=os.environ['SU_NAME'], defaults={'email': os.environ['SU_EMAIL']});
|
||||
u.is_staff = True; u.is_superuser = True; u.set_password(os.environ['SU_PASS']); u.save();
|
||||
print('created' if c else 'updated')
|
||||
register: superuser_result
|
||||
changed_when: true
|
||||
no_log: true
|
||||
tags: [superuser]
|
||||
|
||||
- name: Показать учётные данные суперпользователя
|
||||
ansible.builtin.debug:
|
||||
msg: "Django superuser → login: {{ superuser_name }} password: {{ superuser_password }}"
|
||||
when: sarex_create_superuser | default(false) | bool
|
||||
|
||||
@ -1,183 +0,0 @@
|
||||
---
|
||||
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
|
||||
|
||||
# Тег образа выравнен с 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
|
||||
@ -1,140 +0,0 @@
|
||||
# Копия nginx-configmap из base с правками под контур aero.
|
||||
#
|
||||
# Патчем это сделать нельзя: конфиг лежит одной строкой в data.nginx.conf,
|
||||
# и kustomize умеет только заменить значение целиком.
|
||||
#
|
||||
# ЧТО ИЗМЕНЕНО ОТНОСИТЕЛЬНО base — три вещи:
|
||||
#
|
||||
# 1. Убран location /api/pm/. Сервис pm в контуре не нужен и не планируется.
|
||||
#
|
||||
# 2. Для workspaces и processing адрес вынесен в переменную и добавлен
|
||||
# resolver. Причина: nginx резолвит все upstream'ы ПРИ СТАРТЕ и падает
|
||||
# целиком, если хоть один не найден:
|
||||
# nginx: [emerg] host not found in upstream "backend-svc.pm..."
|
||||
# Из-за этого весь frontend уходил в CrashLoopBackOff, хотя не работал
|
||||
# лишь один маршрут. С переменной nginx откладывает резолвинг до запроса:
|
||||
# сейчас эти пути отдают 502, а когда сервисы приедут — заработают сами,
|
||||
# без правки конфига и перезапуска.
|
||||
#
|
||||
# 3. backend-svc оставлен прямой ссылкой: он в этом же namespace и существует
|
||||
# всегда, откладывать его резолвинг незачем — наоборот, ошибка в имени
|
||||
# обнаружится сразу при старте.
|
||||
#
|
||||
# Адрес resolver'а — CoreDNS кластера. В k3s он называется kube-dns
|
||||
# (имя сохранено для совместимости), namespace kube-system.
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nginx-configmap
|
||||
namespace: django
|
||||
data:
|
||||
nginx.conf: |
|
||||
worker_processes auto;
|
||||
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
use epoll;
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
|
||||
# Basic Settings
|
||||
large_client_header_buffers 8 128k;
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 300;
|
||||
types_hash_max_size 2048;
|
||||
client_max_body_size 5000M;
|
||||
client_header_buffer_size 5M;
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Logging Settings
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
# GZIP Settings
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
# Резолвер нужен для upstream'ов, заданных переменной (см. ниже).
|
||||
resolver kube-dns.kube-system.svc.cluster.local valid=30s ipv6=off;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
root /opt/react_client/;
|
||||
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' '*' always;
|
||||
add_header 'Access-Control-Allow-Headers' '*' always;
|
||||
|
||||
location = /static/index.bundle.js {
|
||||
add_header Cache-Control 'no-store no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||
if_modified_since off;
|
||||
expires off;
|
||||
}
|
||||
|
||||
# location /api/pm/ из base удалён: сервис pm контуру не нужен.
|
||||
|
||||
location ~^/(api|admin)/ {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://backend-svc.django.svc.cluster.local:80;
|
||||
}
|
||||
|
||||
# workspaces появится позже — резолвим лениво, через переменную.
|
||||
location ~^/workspaces-v2/(.+).js {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
rewrite /workspaces-v2/(.+) /$1 break;
|
||||
set $up_workspaces frontend-svc.workspaces.svc.cluster.local;
|
||||
proxy_pass http://$up_workspaces:80;
|
||||
}
|
||||
|
||||
location ~^/workspaces-v2/(.+)\.wasm$ {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
rewrite ^/workspaces-v2/(.+) /$1 break;
|
||||
set $up_workspaces_wasm frontend-svc.workspaces.svc.cluster.local;
|
||||
proxy_pass http://$up_workspaces_wasm:80;
|
||||
}
|
||||
|
||||
location @index {
|
||||
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||
if_modified_since off;
|
||||
expires off;
|
||||
try_files /static/index.html =404;
|
||||
}
|
||||
|
||||
# processing появится позже — тоже лениво.
|
||||
location ~^/workflows/(.+).js {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
rewrite /workflows/(.+) /$1 break;
|
||||
set $up_processing frontend-svc.processing.svc.cluster.local;
|
||||
proxy_pass http://$up_processing:80;
|
||||
}
|
||||
|
||||
location /service-worker.js {
|
||||
try_files /static/$uri @index;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri @index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,15 @@
|
||||
# Слой 3: прикладные сервисы контура.
|
||||
#
|
||||
# Первым переезжает django — backend и frontend. Остальные его части
|
||||
# (celery, srx-admin, s3-proxy) выключены в apps/django/aero и подключатся
|
||||
# следующим шагом.
|
||||
# Сейчас пуст. Тестовое приложение (apps/hello) удалено за ненадобностью: оно
|
||||
# существовало, чтобы доказать работоспособность подложки — доставку Flux'ом,
|
||||
# внедрение sidecar istio и получение секрета из Vault. Теперь это же
|
||||
# подтверждают боевые сервисы: rabbitmq и minio поднимаются с кредами,
|
||||
# приезжающими из Vault через vault-agent-injector.
|
||||
#
|
||||
# Слой намеренно оставлен пустым, а не удалён: следующий этап — перенос
|
||||
# прикладных сервисов из compose в k3s, и они приедут именно сюда. Пустой
|
||||
# resources корректен для kustomize; Flux при этом удалит из кластера то, что
|
||||
# раньше применял этот слой (prune: true).
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- ../../../apps/django/aero
|
||||
resources: []
|
||||
|
||||
@ -93,36 +93,6 @@ spec:
|
||||
prefix: /
|
||||
service: dashboard-kong-proxy.kubernetes-dashboard.svc.cluster.local
|
||||
port: 80
|
||||
# Платформа sarex: frontend в корне, backend на /api/ и /admin/.
|
||||
# Порядок маршрутов значим — более специфичные префиксы идут
|
||||
# первыми, иначе их перехватит правило для /.
|
||||
platform:
|
||||
namespace: gateway
|
||||
hosts:
|
||||
- sarex.local.lonsdaleites.ru
|
||||
gateways:
|
||||
- gateway/contour-gateway
|
||||
routes:
|
||||
# Медиафайлы отдаёт s3-proxy: он добавляет CORS и поддерживает
|
||||
# Range-запросы, которых у S3 API «как есть» нет. Backend
|
||||
# формирует ссылки вида /media/<key>, поэтому маршрут должен
|
||||
# идти ПЕРЕД правилом для /.
|
||||
- path:
|
||||
prefix: /media/
|
||||
service: s3-proxy-svc.django.svc.cluster.local
|
||||
port: 80
|
||||
- path:
|
||||
prefix: /api/
|
||||
service: backend-svc.django.svc.cluster.local
|
||||
port: 80
|
||||
- path:
|
||||
prefix: /admin/
|
||||
service: backend-svc.django.svc.cluster.local
|
||||
port: 80
|
||||
- path:
|
||||
prefix: /
|
||||
service: frontend-svc.django.svc.cluster.local
|
||||
port: 80
|
||||
# Management UI RabbitMQ.
|
||||
rabbitmq:
|
||||
namespace: gateway
|
||||
|
||||
Loading…
Reference in New Issue
Block a user