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/, поэтому маршрут должен # идти ПЕРЕД правилом для /. - 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 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