# FluxCD v2 Monorepo
Репозиторий 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
%% ===== Бизнес-сервисы =====
subgraph APPS["💼 Бизнес-сервисы"]
direction TB
ExampleApp["example-app
HTTP :8080"]:::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| ExampleApp
Gateway ==>|VirtualService
mTLS| Camunda
Gateway ==>|VirtualService| Operate
Gateway ==>|/auth| Keycloak
Gateway ==>|/oauth| Zitadel
Gateway ==>|/dashboard| Dashboard
Gateway ==>|/minio| MinIO
Admin -.->|kubectl| Dashboard
%% ===== Подключения к данным =====
Camunda -- "JDBC" --> PG
Operate -- "JDBC" --> PG
ExampleApp -- "JDBC" --> PG
Zitadel -- "JDBC" --> PG
Keycloak -- "JDBC" --> PG
Camunda -- "cache TTL" --> Redis
ExampleApp -- "cache + pub/sub" --> Redis
Keycloak -- "session cache" --> Redis
%% ===== S3 / объектное хранилище =====
ExampleApp -- "PUT/GET" --> S3Proxy
Camunda -- "attachments" --> S3Proxy
S3Proxy -- "S3 API" --> MinIO
%% ===== Секреты =====
ExampleApp -. "approle" .-> Vault
Camunda -. "approle" .-> Vault
Keycloak -. "kv/secrets" .-> Vault
Zitadel -. "kv/secrets" .-> Vault
%% ===== Storage / PVC =====
PG -.->|PVC| LPP
Redis -.->|PVC| LPP
Kafka -.->|PVC| LPP
ZK -.->|PVC| LPP
RMQ -.->|PVC| LPP
MinIO -.->|PVC| LPP
Vault -.->|PVC| LPP
%% ===== Межсервисные маршруты =====
ExampleApp -- "REST POST /process
start workflow" --> Camunda
Camunda -- "REST callback
job worker" --> ExampleApp
Camunda -- "produce
topic: bpm.events" --> Kafka
ExampleApp -- "consume
topic: bpm.events" --> Kafka
ExampleApp -- "produce
topic: app.audit" --> Kafka
Operate -- "consume
zeebe-records" --> Kafka
ExampleApp -- "publish
queue: tasks" --> RMQ
Camunda -- "consume
queue: tasks" --> RMQ
%% ===== AuthN / AuthZ =====
ExampleApp -. "validate JWT
JWKS" .-> Keycloak
Camunda -. "validate JWT
JWKS" .-> Zitadel
Operate -. "OIDC login" .-> Zitadel
Dashboard -. "OIDC" .-> Keycloak
%% ===== Service mesh observability =====
Camunda -. "envoy sidecar
metrics" .-> Pilot
ExampleApp -. "envoy sidecar
metrics" .-> Pilot
Operate -. "envoy sidecar" .-> 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
```
**Легенда:**
- 🟪 **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` |