463 lines
18 KiB
Markdown
463 lines
18 KiB
Markdown
# FluxCD v2 Monorepooo
|
||
|
||
Репозиторий Infrastructure as Code, управляемый [FluxCD v2](https://fluxcd.io/) с использованием Kustomize-оверлеев и Helm-релизов.
|
||
|
||
## Карта инфраструктуры и межсервисных маршрутов
|
||
|
||
Диаграмма ниже показывает инфраструктурные компоненты кластера, их зависимости и типовые маршруты вызовов между бизнес-сервисами.
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
%% ===== Внешний контур =====
|
||
User([👤 Пользователь<br/>Web / Mobile]):::ext
|
||
Admin([🛡 Администратор<br/>kubectl / flux]):::ext
|
||
LE([🔐 Let's Encrypt<br/>ACME v2]):::ext
|
||
GitRepo([📦 Git Repository<br/>FluxCD source]):::ext
|
||
OCI([🐳 OCI Registry<br/>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<br/>:443 / :80<br/>LoadBalancer"]:::mesh
|
||
Pilot["istiod / Pilot<br/>xDS :15010/:15012"]:::mesh
|
||
Base[Istio Base<br/>CRDs + RBAC]:::mesh
|
||
Cert["cert-manager<br/>v1.x"]:::mesh
|
||
IssuerProd[ClusterIssuer<br/>letsencrypt-prod]:::mesh
|
||
IssuerIstio[ClusterIssuer<br/>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<br/>UI :8443"]:::platform
|
||
LPP["local-path-provisioner<br/>StorageClass: local-path"]:::platform
|
||
Vault["HashiCorp Vault<br/>:8200 KV/Transit"]:::platform
|
||
S3Proxy["S3 Proxy<br/>S3 API gateway"]:::platform
|
||
end
|
||
|
||
%% ===== Identity =====
|
||
subgraph IDENTITY["🪪 Identity & SSO"]
|
||
direction TB
|
||
Zitadel["Zitadel<br/>OIDC :8080"]:::identity
|
||
Keycloak["Keycloak<br/>OIDC/SAML :8080"]:::identity
|
||
OpenLDAP["OpenLDAP<br/>:389 / :636"]:::identity
|
||
Keycloak -- "LDAP federation" --> OpenLDAP
|
||
end
|
||
|
||
%% ===== Данные =====
|
||
subgraph DATA["🗄 Хранилища данных"]
|
||
direction TB
|
||
PG[("PostgreSQL<br/>:5432<br/>HA primary/replica")]:::data
|
||
Redis[("Redis<br/>:6379<br/>cache + pub/sub")]:::data
|
||
MinIO[("MinIO<br/>S3 :9000<br/>console :9001")]:::data
|
||
end
|
||
|
||
%% ===== Messaging =====
|
||
subgraph MSG["📨 Messaging"]
|
||
direction TB
|
||
Kafka[["Kafka<br/>:9092 / :9093 SASL<br/>3 brokers"]]:::msg
|
||
ZK[["ZooKeeper / KRaft<br/>:2181"]]:::msg
|
||
RMQ[["RabbitMQ<br/>:5672 / mgmt :15672"]]:::msg
|
||
Kafka --- ZK
|
||
end
|
||
|
||
%% ===== BPM =====
|
||
subgraph BPM["🔧 BPM"]
|
||
direction TB
|
||
Camunda["Camunda Platform<br/>REST :8080 / Tasklist"]:::app
|
||
Operate["Camunda Operate<br/>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<br/>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=<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` |
|