Фронтенд был исключён из-за адресов, вшитых в бандл на этапе сборки через константу __BUILD_ENV__. Опасение не подтвердилось: сборка обращается к тому же origin относительными путями — иначе в yc-k8s-test и d8-ugmk-prod не понадобился бы отдельный маршрут /workflows/api/ перед /workflows/. Маршруты добавлены на домен платформы, а не на отдельный поддомен: поддомен потребовал бы пересборки образа с другим __BUILD_ENV__. /workflows/api/ -> rewrite /api/ -> backend-svc.processing /workflows/ -> rewrite / -> frontend-svc.processing Порядок внутри пары значим: /workflows/api/ обязан идти перед /workflows/, иначе запросы к API уйдут в раздачу статики. Оба стоят перед /api/ и / — правила django их бы перехватили. Маршруты положены в существующий VirtualService platform, а не в отдельный: Istio не сливает несколько VirtualService на одной паре хост+gateway, и часть правил молча потерялась бы.
210 lines
12 KiB
YAML
210 lines
12 KiB
YAML
apiVersion: helm.toolkit.fluxcd.io/v2
|
||
kind: HelmRelease
|
||
metadata:
|
||
name: istio-config
|
||
namespace: default
|
||
spec:
|
||
interval: 2m
|
||
timeout: 10m
|
||
# disableWait РАЗРЫВАЕТ ДЕДЛОК, не украшательство.
|
||
#
|
||
# Чарт создаёт Certificate, а Flux после установки релиза ждёт готовности его
|
||
# ресурсов — в том числе этого сертификата. Выпустить его нельзя, пока нет
|
||
# ClusterIssuer, а издатели живут в слое infra-configs, который по dependsOn
|
||
# ждёт готовности infra-controllers, где и находится этот самый релиз. Круг:
|
||
# istio-config → Certificate → ClusterIssuer → infra-configs
|
||
# → infra-controllers → istio-config
|
||
# На практике это выглядело как вечное "Running 'upgrade' action" при
|
||
# Released: True и Certificate в состоянии
|
||
# "Issuing certificate as Secret does not exist".
|
||
#
|
||
# Ждать здесь всё равно нечего: чарт разворачивает только конфигурационные
|
||
# объекты (Gateway, VirtualService, Certificate), а не рабочие нагрузки.
|
||
# Сертификат выпустится асинхронно, как только появится издатель.
|
||
install:
|
||
disableWait: true
|
||
upgrade:
|
||
disableWait: true
|
||
# Список продублирован из base целиком: для CRD kustomize заменяет списки,
|
||
# а не сливает, поэтому частичный патч потерял бы зависимости от istio.
|
||
# cert-manager добавлен сверх base — чарт istio-config рендерит Certificate,
|
||
# и без готовых CRD установка падает.
|
||
dependsOn:
|
||
- name: istio-base
|
||
namespace: istio-system
|
||
- name: istiod
|
||
namespace: istio-system
|
||
- name: ingressgateway
|
||
namespace: istio-system
|
||
- name: cert-manager
|
||
namespace: cert-manager
|
||
values:
|
||
global:
|
||
env: aero
|
||
environments:
|
||
aero:
|
||
namespaces: []
|
||
# Блок обязателен, даже пустой: шаблоны gateway.yaml и virtualservice.yaml
|
||
# разыменовывают $env.istio.gateways / .virtualServices без проверки на
|
||
# nil и падают с "nil pointer evaluating interface {}".
|
||
istio:
|
||
# Один общий Gateway на весь контур вместо отдельного на каждый сервис.
|
||
# Так сделано потому, что у контура есть wildcard-домен: сертификат и
|
||
# Gateway покрывают *.sarex.local.lonsdaleites.ru целиком, а новый
|
||
# сервис публикуется добавлением ОДНОГО VirtualService — без правки
|
||
# сертификатов и Gateway. В прод-кластерах домены выписаны поштучно,
|
||
# там wildcard'а нет.
|
||
gateways:
|
||
contour:
|
||
name: contour-gateway
|
||
namespace: gateway
|
||
servers:
|
||
# ПОРЯДОК ЗНАЧИМ: первым обязан идти хост без звёздочки.
|
||
# Чарт собирает из hosts[0] имя порта
|
||
# name: {{ printf "%s-https-443" (index $server.hosts 0 ...) }}
|
||
# и НЕ заключает результат в кавычки. Хост "*.domain" дал бы
|
||
# токен "*-domain-https-443", который YAML читает как ссылку на
|
||
# якорь, и Helm падает с
|
||
# MalformedYAMLError: yaml: unknown anchor ... referenced
|
||
# Сами hosts чарт квотирует, поэтому wildcard ниже безопасен.
|
||
- hosts:
|
||
- sarex.local.lonsdaleites.ru
|
||
- "*.sarex.local.lonsdaleites.ru"
|
||
tls:
|
||
credentialName: contour-tls
|
||
# ВНИМАНИЕ: имя ресурса VirtualService чарт берёт из КЛЮЧА map
|
||
# ({{ $vsName }}), а поле name внутри — игнорирует, в отличие от
|
||
# gateways, где .name учитывается. Поэтому здесь его нет: ключ и есть
|
||
# имя. В остальных кластерах репозитория name у virtualServices
|
||
# присутствует, но ни на что не влияет.
|
||
virtualServices:
|
||
# Kubernetes Dashboard. Свой VirtualService чарт дашборда создаёт на
|
||
# домен dashboard.preprod.sarex.io — он к контуру aero отношения не
|
||
# имеет и никуда не резолвится. Этот выводит дашборд на домен
|
||
# контура; точка входа — kong-proxy, как во всех остальных кластерах.
|
||
dashboard:
|
||
namespace: gateway
|
||
hosts:
|
||
- dashboard.sarex.local.lonsdaleites.ru
|
||
gateways:
|
||
- gateway/contour-gateway
|
||
routes:
|
||
- path:
|
||
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
|
||
# Микрофронтенд workflows и его API. Порядок внутри пары
|
||
# значим: /workflows/api/ обязан идти перед /workflows/, иначе
|
||
# запросы к API уйдут в раздачу статики.
|
||
#
|
||
# Оба маршрута висят на домене платформы, а не на отдельном
|
||
# поддомене, потому что адреса бэкендов вшиты в JS-бандл на
|
||
# этапе сборки (константа __BUILD_ENV__) и указывают на тот же
|
||
# origin относительными путями. Отдельный поддомен означал бы
|
||
# пересборку образа.
|
||
#
|
||
# Маршруты живут в ЭТОМ VirtualService, а не в своём: Istio не
|
||
# сливает несколько VirtualService, привязанных к одной паре
|
||
# хост+gateway, — часть правил молча потерялась бы.
|
||
- path:
|
||
prefix: /workflows/api/
|
||
rewrite: /api/
|
||
service: backend-svc.processing.svc.cluster.local
|
||
port: 80
|
||
- path:
|
||
prefix: /workflows/
|
||
rewrite: /
|
||
service: frontend-svc.processing.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
|
||
hosts:
|
||
- rabbitmq.sarex.local.lonsdaleites.ru
|
||
gateways:
|
||
- gateway/contour-gateway
|
||
routes:
|
||
- path:
|
||
prefix: /
|
||
service: rabbitmq.rabbitmq.svc.cluster.local
|
||
port: 15672
|
||
# MinIO: консоль на /console/, S3 API в корне. Порядок маршрутов
|
||
# значим — более специфичный префикс должен идти первым, иначе его
|
||
# перехватит правило для /.
|
||
minio:
|
||
namespace: gateway
|
||
hosts:
|
||
- minio.sarex.local.lonsdaleites.ru
|
||
gateways:
|
||
- gateway/contour-gateway
|
||
routes:
|
||
- path:
|
||
prefix: /console/
|
||
service: minio-console.minio.svc.cluster.local
|
||
port: 9001
|
||
- path:
|
||
prefix: /
|
||
service: minio.minio.svc.cluster.local
|
||
port: 9000
|
||
requestAuthentications: {}
|
||
authorizationPolicies: {}
|
||
certManager:
|
||
certificates:
|
||
# Издатель — внутренний CA контура, а не ACME: до Let's Encrypt
|
||
# из закрытого контура не достучаться.
|
||
# См. infrastructure/cert-manager/aero/clusterissuer-ca.yaml
|
||
#
|
||
# Домены продублированы из aero/roles/sarex_stack/defaults/main.yml
|
||
# (platform_domain и производные). Единого источника нет — так же
|
||
# захардкожено во всех остальных кластерах репозитория.
|
||
#
|
||
# Один сертификат на весь контур, общий для всех его сервисов.
|
||
contour-tls:
|
||
# Имена перечислены ЯВНО, а не wildcard'ом: решатель http01
|
||
# принципиально не выдаёт wildcard-сертификаты, для них Let's
|
||
# Encrypt требует dns01, а webhook DNS-провайдера в контуре не
|
||
# настроен. Wildcard остался в hosts Gateway — там он про
|
||
# маршрутизацию, а не про TLS.
|
||
#
|
||
# Публикуешь новый сервис — добавь его имя сюда, иначе браузер
|
||
# получит сертификат, в котором этого имени нет.
|
||
dnsNames:
|
||
- sarex.local.lonsdaleites.ru
|
||
- dashboard.sarex.local.lonsdaleites.ru
|
||
- rabbitmq.sarex.local.lonsdaleites.ru
|
||
- minio.sarex.local.lonsdaleites.ru
|
||
issuerRef:
|
||
# Боевой издатель, см. infrastructure/cert-manager/aero/configs.
|
||
name: letsencrypt-issuer-istio
|
||
kind: ClusterIssuer
|