iac/README.md

13 KiB
Raw Blame History

FluxCD v2 Monorepo

Репозиторий Infrastructure as Code, управляемый FluxCD v2 с использованием Kustomize-оверлеев и Helm-релизов.

Карта инфраструктуры и межсервисных маршрутов

Диаграмма ниже показывает инфраструктурные компоненты кластера, их зависимости и типовые маршруты вызовов между бизнес-сервисами.

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

    %% ===== Бизнес-сервисы =====
    subgraph APPS["💼 Бизнес-сервисы"]
        direction TB
        ExampleApp["example-app<br/>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<br/>mTLS| ExampleApp
    Gateway ==>|VirtualService<br/>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<br/>start workflow" --> Camunda
    Camunda -- "REST callback<br/>job worker" --> ExampleApp
    Camunda -- "produce<br/>topic: bpm.events" --> Kafka
    ExampleApp -- "consume<br/>topic: bpm.events" --> Kafka
    ExampleApp -- "produce<br/>topic: app.audit" --> Kafka
    Operate -- "consume<br/>zeebe-records" --> Kafka
    ExampleApp -- "publish<br/>queue: tasks" --> RMQ
    Camunda -- "consume<br/>queue: tasks" --> RMQ

    %% ===== AuthN / AuthZ =====
    ExampleApp -. "validate JWT<br/>JWKS" .-> Keycloak
    Camunda -. "validate JWT<br/>JWKS" .-> Zitadel
    Operate -. "OIDC login" .-> Zitadel
    Dashboard -. "OIDC" .-> Keycloak

    %% ===== Service mesh observability =====
    Camunda -. "envoy sidecar<br/>metrics" .-> Pilot
    ExampleApp -. "envoy sidecar<br/>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

flux bootstrap git \
  --url=<URL_ВАШЕГО_РЕПОЗИТОРИЯ> \
  --branch=master \
  --path=clusters/contour

Проверка реконсиляции

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:

    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:

    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