# FluxCD v2 Monorepooo Репозиторий Infrastructure as Code, управляемый [FluxCD v2](https://fluxcd.io/) с использованием Kustomize-оверлеев и Helm-релизов. ## Карта инфраструктуры и межсервисных маршрутов Диаграмма ниже показывает инфраструктурные компоненты кластера, их зависимости и типовые маршруты вызовов между бизнес-сервисами. ```mermaid flowchart LR %% ===== Внешний контур ===== User([👤 Пользователь
Web / Mobile]):::ext Admin([🛡 Администратор
kubectl / flux]):::ext LE([🔐 Let's Encrypt
ACME v2]):::ext GitRepo([📦 Git Repository
FluxCD source]):::ext OCI([🐳 OCI Registry
cr.yandex]):::ext %% ===== GitOps ===== subgraph GITOPS["⚙️ GitOps Control Plane"] direction TB FluxSource[source-controller]:::flux FluxKust[kustomize-controller]:::flux FluxHelm[helm-controller]:::flux FluxNotif[notification-controller]:::flux FluxSource --> FluxKust FluxSource --> FluxHelm FluxKust --> FluxNotif FluxHelm --> FluxNotif end %% ===== Edge / Service Mesh ===== subgraph EDGE["🌐 Edge & Service Mesh — istio-system"] direction TB Gateway["Istio Gateway
:443 / :80
LoadBalancer"]:::mesh Pilot["istiod / Pilot
xDS :15010/:15012"]:::mesh Base[Istio Base
CRDs + RBAC]:::mesh Cert["cert-manager
v1.x"]:::mesh IssuerProd[ClusterIssuer
letsencrypt-prod]:::mesh IssuerIstio[ClusterIssuer
letsencrypt-istio]:::mesh Pilot -->|sidecar inject| Gateway Base --> Pilot Cert --> IssuerProd Cert --> IssuerIstio IssuerIstio -. TLS cert .-> Gateway end %% ===== Платформа ===== subgraph PLATFORM["🛠 Платформа"] direction TB Dashboard["K8s Dashboard
UI :8443"]:::platform LPP["local-path-provisioner
StorageClass: local-path"]:::platform Vault["HashiCorp Vault
:8200 KV/Transit"]:::platform S3Proxy["S3 Proxy
S3 API gateway"]:::platform end %% ===== Identity ===== subgraph IDENTITY["🪪 Identity & SSO"] direction TB Zitadel["Zitadel
OIDC :8080"]:::identity Keycloak["Keycloak
OIDC/SAML :8080"]:::identity OpenLDAP["OpenLDAP
:389 / :636"]:::identity Keycloak -- "LDAP federation" --> OpenLDAP end %% ===== Данные ===== subgraph DATA["🗄 Хранилища данных"] direction TB PG[("PostgreSQL
:5432
HA primary/replica")]:::data Redis[("Redis
:6379
cache + pub/sub")]:::data MinIO[("MinIO
S3 :9000
console :9001")]:::data end %% ===== Messaging ===== subgraph MSG["📨 Messaging"] direction TB Kafka[["Kafka
:9092 / :9093 SASL
3 brokers"]]:::msg ZK[["ZooKeeper / KRaft
:2181"]]:::msg RMQ[["RabbitMQ
:5672 / mgmt :15672"]]:::msg Kafka --- ZK end %% ===== BPM ===== subgraph BPM["🔧 BPM"] direction TB Camunda["Camunda Platform
REST :8080 / Tasklist"]:::app Operate["Camunda Operate
UI :8081"]:::app end %% ===== Бизнес-сервисы (каждый в своём namespace) ===== subgraph APPS["💼 Бизнес-сервисы — namespaces"] direction LR CI["ns: control-interface"]:::app Django["ns: django"]:::app EAV["ns: eav"]:::app Workspaces["ns: workspaces"]:::app Projects["ns: projects"]:::app PM["ns: pm"]:::app Contracts["ns: contracts"]:::app Resources["ns: resources"]:::app Subs["ns: subscriptions"]:::app SysLog["ns: system-log"]:::app MsgHub["ns: message-hub"]:::app FaaS["ns: faas"]:::app Flows["ns: flows"]:::app Docs["ns: documentations"]:::app DocLink["ns: document-link"]:::app Attach["ns: attachments"]:::app Transmittal["ns: transmittal"]:::app CDE["ns: cde"]:::app Drawings["ns: drawings"]:::app BIM["ns: bim"]:::app Stamp["ns: stamp-verification"]:::app Inspect["ns: inspections"]:::app Checklists["ns: checklists"]:::app Remarks["ns: remarks"]:::app Issues["ns: issues"]:::app RFI["ns: rfi"]:::app Reviews["ns: reviews"]:::app Prescr["ns: prescriptions"]:::app Compare["ns: comparisons"]:::app Measure["ns: measurements"]:::app Mapper["ns: mapper"]:::app XSection["ns: cross-section"]:::app Process["ns: processing"]:::app Notes["ns: notes"]:::app end %% ===== GitOps потоки ===== Admin ==>|git push| GitRepo GitRepo ==>|pull/poll| FluxSource OCI ==>|OCI charts| FluxSource FluxKust ==>|apply manifests| EDGE FluxKust ==>|apply manifests| PLATFORM FluxKust ==>|apply manifests| IDENTITY FluxHelm ==>|HelmRelease| DATA FluxHelm ==>|HelmRelease| MSG FluxHelm ==>|HelmRelease| BPM FluxHelm ==>|HelmRelease| APPS %% ===== Внешний трафик ===== User ==>|HTTPS 443| Gateway LE -. ACME HTTP-01 .-> Cert Gateway ==>|VirtualService
mTLS| CI Gateway ==>|/api| Django Gateway ==>|/bim| BIM Gateway ==>|/cde| CDE Gateway ==>|/docs| Docs Gateway ==>|/pm| PM Gateway ==>|VirtualService| Camunda Gateway ==>|VirtualService| Operate Gateway ==>|/auth| Keycloak Gateway ==>|/oauth| Zitadel Gateway ==>|/dashboard| Dashboard Gateway ==>|/minio| MinIO Admin -.->|kubectl| Dashboard %% ===== Frontend → backend (через control-interface) ===== CI -- "API gateway" --> Django CI -- "API gateway" --> PM CI -- "API gateway" --> Projects CI -- "API gateway" --> Workspaces %% ===== Подключения к данным ===== Django -- "JDBC/ORM" --> PG EAV -- "JDBC" --> PG PM -- "JDBC" --> PG Contracts -- "JDBC" --> PG Resources -- "JDBC" --> PG Projects -- "JDBC" --> PG Workspaces -- "JDBC" --> PG Subs -- "JDBC" --> PG SysLog -- "JDBC" --> PG Docs -- "JDBC" --> PG DocLink -- "JDBC" --> PG CDE -- "JDBC" --> PG BIM -- "JDBC" --> PG Drawings -- "JDBC" --> PG Inspect -- "JDBC" --> PG Checklists -- "JDBC" --> PG Issues -- "JDBC" --> PG Remarks -- "JDBC" --> PG RFI -- "JDBC" --> PG Reviews -- "JDBC" --> PG Prescr -- "JDBC" --> PG Compare -- "JDBC" --> PG Measure -- "JDBC" --> PG Mapper -- "JDBC" --> PG XSection -- "JDBC" --> PG Notes -- "JDBC" --> PG Stamp -- "JDBC" --> PG Transmittal -- "JDBC" --> PG Camunda -- "JDBC" --> PG Operate -- "JDBC" --> PG Zitadel -- "JDBC" --> PG Keycloak -- "JDBC" --> PG %% ===== Redis (общий кэш / sessions) ===== Django -- "session/cache" --> Redis CI -- "session" --> Redis PM -- "cache" --> Redis Workspaces -- "cache" --> Redis Subs -- "pub/sub realtime" --> Redis MsgHub -- "pub/sub" --> Redis Flows -- "state" --> Redis FaaS -- "queue" --> Redis Camunda -- "cache" --> Redis Keycloak -- "session" --> Redis %% ===== S3 / объектное хранилище ===== Attach -- "PUT/GET" --> S3Proxy Docs -- "filestream" --> S3Proxy BIM -- "IFC/RVT" --> S3Proxy Drawings -- "DWG/PDF" --> S3Proxy CDE -- "files" --> S3Proxy Compare -- "rendered diff" --> S3Proxy Stamp -- "signed PDF" --> S3Proxy Transmittal -- "bundles" --> S3Proxy Process -- "raw + результаты" --> S3Proxy Mapper -- "tiles" --> S3Proxy Measure -- "snapshots" --> S3Proxy XSection -- "профили" --> S3Proxy S3Proxy -- "S3 API" --> MinIO %% ===== Vault (secrets) ===== Django -. "kv" .-> Vault Camunda -. "approle" .-> Vault Keycloak -. "kv" .-> Vault Zitadel -. "kv" .-> Vault FaaS -. "approle" .-> Vault Flows -. "approle" .-> Vault %% ===== Storage / PVC ===== PG -.->|PVC| LPP Redis -.->|PVC| LPP Kafka -.->|PVC| LPP ZK -.->|PVC| LPP RMQ -.->|PVC| LPP MinIO -.->|PVC| LPP Vault -.->|PVC| LPP %% ===== Kafka (event bus) ===== SysLog -- "consume audit.*" --> Kafka MsgHub -- "produce notify.*" --> Kafka Subs -- "consume notify.*" --> Kafka Flows -- "produce/consume flows.*" --> Kafka Camunda -- "produce bpm.events" --> Kafka Operate -- "consume zeebe-records" --> Kafka BIM -- "produce bim.processed" --> Kafka Drawings -- "produce drawings.uploaded" --> Kafka Process -- "consume processing.jobs" --> Kafka Compare -- "consume drawings.uploaded" --> Kafka Inspect -- "produce inspect.events" --> Kafka Issues -- "consume inspect.events" --> Kafka Remarks -- "produce remarks.events" --> Kafka Reviews -- "consume remarks.events" --> Kafka %% ===== RabbitMQ (work queues) ===== FaaS -- "consume tasks.*" --> RMQ Flows -- "publish tasks.*" --> RMQ Process -- "publish jobs" --> RMQ Mapper -- "consume tile.jobs" --> RMQ XSection -- "consume xs.jobs" --> RMQ Stamp -- "consume sign.jobs" --> RMQ Camunda -- "consume bpm.tasks" --> RMQ %% ===== Межсервисные REST маршруты ===== PM -- "REST" --> Projects PM -- "REST" --> Contracts PM -- "REST" --> Resources Projects -- "REST" --> Workspaces Contracts -- "REST" --> Resources Inspect -- "REST" --> Checklists Inspect -- "REST" --> Issues Issues -- "REST" --> Remarks Reviews -- "REST" --> RFI Reviews -- "REST" --> Prescr RFI -- "REST" --> DocLink DocLink --> Docs DocLink --> CDE CDE -- "REST" --> Docs CDE -- "REST" --> Drawings CDE -- "REST" --> BIM Transmittal -- "REST" --> CDE Transmittal -- "REST" --> Docs Drawings -- "REST" --> Compare Drawings -- "REST" --> Stamp Measure -- "REST" --> Mapper Mapper -- "REST" --> XSection XSection --> Process BIM -- "REST" --> Process Notes -- "REST" --> DocLink Flows -- "trigger" --> FaaS Flows -- "start" --> Camunda Camunda -- "callback" --> Flows EAV -- "schemas" --> Django MsgHub -- "deliver email/push" --> Subs %% ===== AuthN / AuthZ ===== Django -. "OIDC validate" .-> Keycloak CI -. "OIDC login" .-> Keycloak PM -. "JWT" .-> Keycloak Camunda -. "JWT" .-> Zitadel Operate -. "OIDC" .-> Zitadel Dashboard -. "OIDC" .-> Keycloak BIM -. "JWT" .-> Keycloak CDE -. "JWT" .-> Keycloak Docs -. "JWT" .-> Keycloak %% ===== Service mesh sidecar metrics ===== CI -. "envoy" .-> Pilot Django -. "envoy" .-> Pilot Camunda -. "envoy" .-> Pilot BIM -. "envoy" .-> Pilot Flows -. "envoy" .-> Pilot %% ===== Стили ===== classDef ext fill:#1f2937,stroke:#9ca3af,stroke-width:2px,color:#f9fafb classDef flux fill:#6366f1,stroke:#3730a3,stroke-width:2px,color:#fff classDef mesh fill:#7c3aed,stroke:#4c1d95,stroke-width:2px,color:#fff classDef platform fill:#0ea5e9,stroke:#075985,stroke-width:2px,color:#fff classDef identity fill:#f59e0b,stroke:#92400e,stroke-width:2px,color:#fff classDef data fill:#10b981,stroke:#065f46,stroke-width:2px,color:#fff classDef msg fill:#ef4444,stroke:#991b1b,stroke-width:2px,color:#fff classDef app fill:#ec4899,stroke:#9d174d,stroke-width:2px,color:#fff style GITOPS fill:#e0e7ff,stroke:#6366f1,stroke-width:2px style EDGE fill:#ede9fe,stroke:#7c3aed,stroke-width:2px style PLATFORM fill:#e0f2fe,stroke:#0ea5e9,stroke-width:2px style IDENTITY fill:#fef3c7,stroke:#f59e0b,stroke-width:2px style DATA fill:#d1fae5,stroke:#10b981,stroke-width:2px style MSG fill:#fee2e2,stroke:#ef4444,stroke-width:2px style BPM fill:#fce7f3,stroke:#ec4899,stroke-width:2px style APPS fill:#fce7f3,stroke:#ec4899,stroke-width:2px ``` 📂 **Подробные диаграммы по каждому бизнес-сервису:** [`docs/apps/`](./docs/apps/README.md) **Легенда:** - 🟪 **Edge / Mesh** — терминация TLS, маршрутизация и mTLS между сервисами (Istio + cert-manager) - 🟦 **Платформа** — служебные компоненты (storage, secrets, S3 proxy, dashboard) - 🟧 **Identity** — единый вход и федерация пользователей (Zitadel, Keycloak, OpenLDAP) - 🟩 **Данные** — постоянные хранилища (PostgreSQL, Redis, MinIO) - 🟥 **Messaging** — асинхронный обмен (Kafka, RabbitMQ) - 🟪 **Бизнес-сервисы** — прикладная логика (Camunda, бизнес-приложения) ## Структура репозитория ``` ├── clusters/ # Точка входа для каждого кластера (Flux читает отсюда) │ └── contour/ # Кластер contour │ ├── flux-system/ # Автогенерируется через `flux bootstrap` (не редактировать) │ ├── helm-repositories.yaml # Определения HelmRepository │ ├── infrastructure.yaml # Flux Kustomization → ./infrastructure │ └── apps.yaml # Flux Kustomization → ./apps │ ├── infrastructure/ # Инфраструктурные компоненты │ ├── kustomization.yaml # Список всех инфра-сервисов │ └── example-infra/ # Пример инфра-компонента │ ├── kustomization.yaml # Собирает base + patches │ ├── base/ # Базовые манифесты (namespace, HelmRelease) │ └── patches/ # Патчи поверх base │ ├── apps/ # Прикладные сервисы │ ├── kustomization.yaml # Список всех приложений │ └── example-app/ # Пример приложения │ ├── kustomization.yaml # Собирает base + patches │ ├── base/ # Базовые манифесты (Deployment, Service, ConfigMap) │ └── patches/ # Патчи поверх base ``` ## Как это работает Flux отслеживает директорию `clusters/<имя-кластера>/`. Каждый кластер содержит два Flux Kustomization CRD верхнего уровня: 1. **infrastructure.yaml** — реконсилирует `./infrastructure`. Содержит HelmReleases и вспомогательные ресурсы. 2. **apps.yaml** — реконсилирует `./apps`. Содержит Deployments, Services и другие ресурсы приложений. `apps` зависит от `infrastructure`, что гарантирует готовность инфраструктуры до деплоя приложений. Каждый сервис (в `infrastructure/` или `apps/`) имеет собственную структуру: - **base/** — базовые манифесты, общие для всех окружений - **patches/** — патчи, применяемые поверх base - **kustomization.yaml** — на уровне сервиса, собирает base + patches через Kustomize ## Начало работы ### Бутстрап Flux ```bash flux bootstrap git \ --url= \ --branch=master \ --path=clusters/contour ``` ### Проверка реконсиляции ```bash flux get kustomizations flux get helmreleases -A flux events --watch ``` ## Добавление нового инфраструктурного компонента 1. Создайте директорию с base и patches: ``` infrastructure/my-component/ ├── kustomization.yaml # resources: [./base], patches: [patches/...] ├── base/ │ ├── kustomization.yaml │ ├── namespace.yaml │ └── helmrelease.yaml └── patches/ └── values.yaml ``` 2. Зарегистрируйте в `infrastructure/kustomization.yaml`: ```yaml resources: - example-infra - my-component # Добавьте эту строку ``` 3. Если нужен новый HelmRepository, добавьте его в `clusters/<кластер>/helm-repositories.yaml`. ## Добавление нового приложения 1. Создайте директорию с base и patches: ``` apps/my-app/ ├── kustomization.yaml # resources: [./base], patches: [patches/...] ├── base/ │ ├── kustomization.yaml │ ├── namespace.yaml │ ├── deployment.yaml │ └── service.yaml └── patches/ └── replicas.yaml ``` 2. Зарегистрируйте в `apps/kustomization.yaml`: ```yaml resources: - example-app - my-app # Добавьте эту строку ``` ## Добавление нового кластера 1. Создайте точку входа `clusters/<имя>/` с `infrastructure.yaml`, `apps.yaml` и `helm-repositories.yaml` 2. Выполните бутстрап Flux с `--path=clusters/<имя>` ## Справочник API-версий | Ресурс | apiVersion | |------------------|-----------------------------------------| | Kustomization | `kustomize.toolkit.fluxcd.io/v1` | | GitRepository | `source.toolkit.fluxcd.io/v1` | | HelmRepository | `source.toolkit.fluxcd.io/v1` | | HelmRelease | `helm.toolkit.fluxcd.io/v2` |