--- 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 выключен: очереди подключим вместе с остальными фоновыми задачами. # s3-proxy ВКЛЮЧЁН — он отдаёт медиафайлы браузеру с CORS и Range, а бакет # уже создан, так что проверять его есть на чём. - target: {kind: HelmRelease, name: celery} patch: | $patch: delete apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: name: celery namespace: django # --- 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