Оба пода уходили в рестарты, причины разные и обе — мои.
1. bim-api:
psycopg2.OperationalError: FATAL: database "bimapidb" does not exist
Имя базы у приложения ЗАХАРДКОЖЕНО и переменной не задаётся — в
entrypoint_api.sh (yoyo apply ... /bimapidb) и в models/database.py
(PooledPostgresqlExtDatabase('bimapidb', ...)). Переменной DB_NAME в
коде нет вообще, я подставлял её впустую. Запись в contour.databases
переименована bim_db -> bimapidb, DB_NAME из vault-шаблона убран.
Пустая bim_db остаётся в СУБД: бутстрап умеет только создавать. Данных
в ней нет — проверено, ноль таблиц.
2. bim-worker:
Exception: ENV_VARIABLE NOT SET: GOOGLE_APPLICATION_CREDENTIALS
settings.py делает check_settings(): проходит по ВСЕМ ключам ENV_FIELDS
и падает на первом незаданном, до проверки флагов дело не доходит.
Убирать переменную вместе с Google-хранилищем было нельзя. Возвращена;
файла по этому пути нет и не нужно — при FEATURE_ENABLE_GCLOUD=false
его никто не открывает, важно лишь наличие самой переменной.
Отсюда правило для этого приложения: набор переменных должен повторять
apps/bim/dsinv целиком, образ там тот же (870965d1...). Менять можно
только значения — адреса, бакет, брокер, — но не состав.
225 lines
11 KiB
YAML
225 lines
11 KiB
YAML
---
|
||
# BIM API — приложение из aero/bimbackend (Python, api + worker).
|
||
#
|
||
# ЭТО НЕ ТО ЖЕ, ЧТО apps/bim/base. В base описан platform/bim-backend-v2 —
|
||
# другой сервис, на Go, с единственным httpserver. Спутать их легко: ОБА
|
||
# пушат в реестр один и тот же образ bim-api, и различаются только тегами и
|
||
# содержимым. У bimbackend теги — полный SHA коммита (CI пушит
|
||
# bim-api:${CI_COMMIT_SHA} с master), у bim-backend-v2 — contour_*.
|
||
# Поэтому здесь ../base намеренно НЕ подключён.
|
||
#
|
||
# Манифесты обычные, а не HelmRelease с universal-chart: в репозитории этот
|
||
# сервис так и описан (apps/bim/dsinv), своего чарта у него нет, и заводить
|
||
# его ради контура значило бы поддерживать ещё одну сущность.
|
||
apiVersion: v1
|
||
kind: ServiceAccount
|
||
metadata:
|
||
name: bim-api-sa
|
||
namespace: bim
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: bim-api
|
||
namespace: bim
|
||
labels:
|
||
app: bim-api
|
||
spec:
|
||
replicas: 1
|
||
revisionHistoryLimit: 10
|
||
selector:
|
||
matchLabels:
|
||
app: bim-api
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: bim-api
|
||
annotations:
|
||
# Порт Vault исключён из перехвата sidecar'ом: сам Vault живёт вне
|
||
# кластера, и заворачивать обращения к нему в mesh незачем.
|
||
traffic.sidecar.istio.io/excludeOutboundPorts: "8200"
|
||
vault.hashicorp.com/agent-init-first: "true"
|
||
vault.hashicorp.com/agent-inject: "true"
|
||
vault.hashicorp.com/agent-pre-populate-only: "true"
|
||
vault.hashicorp.com/auth-path: auth/kubernetes
|
||
vault.hashicorp.com/role: bim
|
||
# БД. Имена переменных — DB_*, как их читает settings.py bimbackend,
|
||
# а не POSTGRES_*, как у остальных приложений контура.
|
||
vault.hashicorp.com/agent-inject-secret-bim-db: secrets/data/apps/bim/postgres
|
||
vault.hashicorp.com/agent-inject-template-bim-db: |-
|
||
{{- with secret "secrets/data/apps/bim/postgres" -}}
|
||
DB_HOST={{ index .Data.data "host" }}
|
||
DB_PORT={{ index .Data.data "port" }}
|
||
DB_USER={{ index .Data.data "username" }}
|
||
DB_PASSWORD={{ index .Data.data "password" }}
|
||
{{- end -}}
|
||
vault.hashicorp.com/agent-inject-secret-bim-rabbitmq: secrets/data/rabbitmq/apps/bim
|
||
vault.hashicorp.com/agent-inject-template-bim-rabbitmq: |-
|
||
{{- with secret "secrets/data/rabbitmq/apps/bim" -}}
|
||
RABBIT_USER={{ index .Data.data "username" }}
|
||
RABBIT_PASSWORD={{ index .Data.data "password" }}
|
||
{{- end -}}
|
||
vault.hashicorp.com/agent-inject-secret-bim-s3: secrets/data/minio/apps/bim
|
||
vault.hashicorp.com/agent-inject-template-bim-s3: |-
|
||
{{- with secret "secrets/data/minio/apps/bim" -}}
|
||
AWS_ACCESS_KEY_ID={{ index .Data.data "access_key" }}
|
||
AWS_SECRET_ACCESS_KEY={{ index .Data.data "secret_key" }}
|
||
{{- end -}}
|
||
# Публичный ключ JWT отдаётся файлом. Оба флага аутентификации ниже
|
||
# выключены, то есть читаться он не должен, — но путь в переменной
|
||
# обязан существовать, иначе рискуем падением при импорте настроек.
|
||
vault.hashicorp.com/agent-inject-secret-jwt-public: secrets/data/vault/common/rsa_keys
|
||
vault.hashicorp.com/agent-inject-template-jwt-public: |-
|
||
{{- with secret "secrets/data/vault/common/rsa_keys" -}}
|
||
{{ index .Data.data "public_key" }}
|
||
{{- end -}}
|
||
spec:
|
||
serviceAccountName: bim-api-sa
|
||
imagePullSecrets:
|
||
- name: regcred
|
||
containers:
|
||
- name: bim-api
|
||
# Тег — полный SHA, как их пушит CI aero/bimbackend с master. Именно
|
||
# этот образ крутится в dsinv. contour_*-теги у образа bim-api брать
|
||
# НЕЛЬЗЯ: их собирает bim-backend-v2, это чужое приложение.
|
||
image: cr.yandex/crp3ccidau046kdj8g9q/bim-api:870965d1967cd761965029b0480884ab7fa7c951
|
||
imagePullPolicy: IfNotPresent
|
||
# Штатный entrypoint не умеет читать секреты из файлов, поэтому
|
||
# оборачиваем его: подгружаем отрендеренное vault-агентом и передаём
|
||
# управление. exec — чтобы приложение осталось процессом с PID 1 и
|
||
# корректно получало сигналы остановки.
|
||
command: ["/bin/sh", "-ec"]
|
||
args:
|
||
- |
|
||
set -a
|
||
[ -f /vault/secrets/bim-db ] && . /vault/secrets/bim-db
|
||
[ -f /vault/secrets/bim-rabbitmq ] && . /vault/secrets/bim-rabbitmq
|
||
[ -f /vault/secrets/bim-s3 ] && . /vault/secrets/bim-s3
|
||
set +a
|
||
exec ./entrypoint_api.sh
|
||
ports:
|
||
- containerPort: 5555
|
||
name: http
|
||
protocol: TCP
|
||
- containerPort: 9000
|
||
name: prom
|
||
protocol: TCP
|
||
env:
|
||
- name: JWT_PUBLIC_KEY_PATH
|
||
value: /vault/secrets/jwt-public
|
||
- name: FEATURE_ENABLE_JWT_AUTH
|
||
value: "false"
|
||
- name: FEATURE_ENABLE_SAREX_AUTH
|
||
value: "false"
|
||
- name: FEATURE_ENABLE_WORKSPACES
|
||
value: "true"
|
||
# Google-хранилища в контуре нет и не будет — флаг выключен.
|
||
# Том с ключом, который есть в dsinv, здесь не нужен, а сама
|
||
# переменная ниже нужна, см. комментарий к ней.
|
||
- name: FEATURE_ENABLE_GCLOUD
|
||
value: "false"
|
||
# Значение НЕ УДАЛЯТЬ, даже при выключенном флаге выше. settings.py
|
||
# делает check_settings(): проходит по всем ключам ENV_FIELDS и
|
||
# падает на первом же незаданном —
|
||
# Exception: ENV_VARIABLE NOT SET: GOOGLE_APPLICATION_CREDENTIALS
|
||
# Флаги проверяются позже, до них дело не доходит. Файла по этому
|
||
# пути нет и не будет: при FEATURE_ENABLE_GCLOUD=false его никто не
|
||
# открывает, важно лишь наличие самой переменной.
|
||
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||
value: /etc/sarex/google-storage/service_account.json
|
||
# ВНИМАНИЕ: S3 в этом приложении НЕ НАСТРАИВАЕТСЯ на MinIO.
|
||
# В storage/s3.py адрес зашит в код:
|
||
# endpoint_url='https://storage.yandexcloud.net'
|
||
# переменной окружения для него нет. Из контура он недостижим,
|
||
# поэтому любые операции с файлами будут падать по таймауту —
|
||
# это принято осознанно, API и остальные эндпоинты живут.
|
||
# Починить можно только пересборкой образа с вынесенным endpoint
|
||
# либо переводом на BIM_CURRENT_STORAGE=local (тип есть в
|
||
# storage/storages.py).
|
||
- name: FEATURE_ENABLE_S3
|
||
value: "true"
|
||
- name: S3_BUCKET
|
||
value: sarex-media-storage
|
||
- name: BIM_CURRENT_STORAGE
|
||
value: s3
|
||
- name: AWS_DEFAULT_REGION
|
||
value: ru-central1
|
||
- name: FEATURE_ENABLE_PROCESSING
|
||
value: "1"
|
||
# Адреса смежных сервисов приведены к именам контура. В dsinv это
|
||
# workflows-service:8000 и workspaces-service:8000 — таких сервисов
|
||
# здесь нет, оба называются backend-svc и слушают 80.
|
||
- name: PROCESSING_API_URL
|
||
value: http://backend-svc.processing.svc.cluster.local:80/internal
|
||
- name: PROCESSING_C2M_VERSION
|
||
value: stable
|
||
- name: WORKSPACES_API_URL
|
||
value: http://backend-svc.workspaces.svc.cluster.local:80/internal
|
||
# Сервиса сравнений в контуре нет и не планируется, флага для его
|
||
# отключения приложение не предоставляет. Имя оставлено говорящим:
|
||
# в логах будет видно, куда именно оно не достучалось.
|
||
- name: COMPARATOR_API_URL
|
||
value: http://comparator-api-service.comparator.svc.cluster.local/internal
|
||
- name: BIM_API_EXTERNAL_HOST_SCHEMA
|
||
value: https
|
||
- name: BIM_API_EXTERNAL_HOST
|
||
value: bim.sarex.local.lonsdaleites.ru
|
||
- name: BIM_API_INTERNAL_HOST_SCHEMA
|
||
value: http
|
||
- name: BIM_API_INTERNAL_HOST
|
||
value: bim-api-service.bim.svc.cluster.local:5555
|
||
- name: WEBHOOK_URL
|
||
value: http://bim-api-service.bim.svc.cluster.local:5555
|
||
# Брокер общий, vhost по умолчанию. В dsinv vhost называется api,
|
||
# но в контуре отдельных vhost'ов нет — см. secrets/rabbitmq/*.
|
||
- name: RABBIT_HOST
|
||
value: rabbitmq.rabbitmq.svc.cluster.local:5672
|
||
- name: RABBIT_VHOST
|
||
value: "/"
|
||
- name: MESH_OPTIMIZER_PATH
|
||
value: gltfpack
|
||
- name: DEBUG
|
||
value: "0"
|
||
- name: STORAGE_SEGMENT
|
||
value: sarex-production-storage
|
||
- name: STORAGE_PROJECT
|
||
value: sarex-production
|
||
- name: TMP_DIR
|
||
value: /tmp
|
||
- name: prometheus_multiproc_dir
|
||
value: /tmp
|
||
- name: BUNDLE_VERSION
|
||
value: v1
|
||
- name: DISABLE_INSTANCING
|
||
value: "0"
|
||
resources:
|
||
requests:
|
||
cpu: 25m
|
||
memory: 200Mi
|
||
volumeMounts:
|
||
- mountPath: /tmp
|
||
name: tmp-volume
|
||
volumes:
|
||
- name: tmp-volume
|
||
emptyDir: {}
|
||
---
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: bim-api-service
|
||
namespace: bim
|
||
labels:
|
||
app: bim-api
|
||
spec:
|
||
# ClusterIP, а не NodePort с прибитым портом 31352, как в dsinv: наружу
|
||
# сервис выходит через общий Gateway и VirtualService контура, отдельный
|
||
# порт на нодах ему не нужен.
|
||
type: ClusterIP
|
||
ports:
|
||
- name: http
|
||
port: 5555
|
||
targetPort: 5555
|
||
protocol: TCP
|
||
selector:
|
||
app: bim-api
|