openova/platform/cnpg
e3mrah 9dc8506dd9
feat(charts): bp-external-secrets + bp-cnpg + bp-valkey wrapper charts (#285)
Storage-substrate batch (W2.5.A) — closes #254 by shipping the three
upstream-subchart umbrella Blueprints that the Flux HRs at
clusters/_template/bootstrap-kit/{15-external-secrets,16-cnpg,17-valkey}
.yaml (merged via PR #262) target.

Each chart follows the canonical umbrella pattern documented in
docs/BLUEPRINT-AUTHORING.md §11.1: Chart.yaml declares the upstream
chart under `dependencies:` so `helm dependency build` bundles the
upstream payload into the OCI artifact, and Catalyst-curated overlay
values + templates sit alongside in chart/values.yaml + chart/templates/.

Per-chart highlights:
- bp-external-secrets/1.0.0 — wraps external-secrets/external-secrets
  0.10.7. Ships a default `vault-region1` ClusterSecretStore (via Helm
  post-install/post-upgrade hook to defer the CR application until the
  upstream chart's CRDs are registered) wired to the in-cluster
  bp-openbao service. clusterSecretStore.enabled toggle lets cluster
  overlays opt out and author their own multi-region CRs.
- bp-cnpg/1.0.0 — wraps cnpg/cloudnative-pg 0.28.0. Operator-only
  surface (Cluster CRs are per-Application). CRDs ship in-chart so
  bp-powerdns / bp-keycloak / bp-gitea / bp-langfuse / bp-grafana /
  bp-temporal / bp-matrix / bp-llm-gateway / bp-bge / bp-nemo-guardrails
  / bp-openmeter / pool-domain-manager can `dependsOn: bp-cnpg` via
  Flux — closing #254 (bp-powerdns CreateContainerConfigError on
  pdns-pg-app secret).
- bp-valkey/1.0.0 — wraps bitnami/valkey 5.5.1. BSD-3 Redis-compatible
  cache, replication architecture, password auth ON, NetworkPolicy ON,
  replicas 0 by default for solo Sovereigns (cluster overlays bump for
  HA). Application-tier cache only — Catalyst control plane uses NATS
  JetStream KV (per ARCHITECTURE.md §5).

Per docs/BLUEPRINT-AUTHORING.md §11.2 (issue #182): every observability
toggle defaults `false` (ServiceMonitor / PodMonitor / PrometheusRule /
metrics sidecar) and is operator-tunable via per-cluster overlay once
bp-kube-prometheus-stack reconciles. Each chart ships
tests/observability-toggle.sh covering default-off, opt-in (--api-versions
monitoring.coreos.com/v1 to simulate the CRDs), and explicit-off cases.

Per docs/INVIOLABLE-PRINCIPLES.md #4 (never hardcode): every upstream
version, namespace, server URL, role, and password toggle is exposed
under values.yaml. Cluster overlays in clusters/<sovereign>/ may
override without rebuilding the Blueprint OCI artifact.

helm lint: 1 chart(s) linted, 0 chart(s) failed (each, INFO icon-recommended only)
helm template default render kinds:
  bp-external-secrets: ClusterRole, ClusterRoleBinding, ClusterSecretStore, CustomResourceDefinition, Deployment, Role, RoleBinding, Secret, Service, ServiceAccount, ValidatingWebhookConfiguration
  bp-cnpg:             ClusterRole, ClusterRoleBinding, ConfigMap, CustomResourceDefinition, Deployment, MutatingWebhookConfiguration, Service, ServiceAccount, ValidatingWebhookConfiguration
  bp-valkey:           ConfigMap, NetworkPolicy, PodDisruptionBudget, Secret, Service, ServiceAccount, StatefulSet

Closes #254

Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
2026-04-30 18:39:29 +04:00
..
chart feat(charts): bp-external-secrets + bp-cnpg + bp-valkey wrapper charts (#285) 2026-04-30 18:39:29 +04:00
blueprint.yaml feat(charts): bp-external-secrets + bp-cnpg + bp-valkey wrapper charts (#285) 2026-04-30 18:39:29 +04:00
README.md docs(seaweedfs+guacamole): replace MinIO with SeaweedFS as unified S3 encapsulation; add Guacamole to bp-relay 2026-04-28 10:23:46 +02:00

CNPG (CloudNative PostgreSQL)

Production-grade PostgreSQL operator. Application Blueprint (see docs/PLATFORM-TECH-STACK.md §4.1 — Data services). Used by Organizations that want managed Postgres; also the underlying engine for FerretDB (MongoDB-compatible) and Gitea metadata. Replication via WAL streaming to async standby (Application-tier choice).

Status: Accepted | Updated: 2026-04-27


Overview

CloudNative PostgreSQL (CNPG) provides production-grade PostgreSQL with:

  • Kubernetes-native operator
  • WAL streaming for multi-region DR
  • Automated backups to SeaweedFS/S3
  • High availability with automatic failover

Architecture

Single Region

flowchart TB
    subgraph Cluster["CNPG Cluster"]
        Primary[Primary]
        Replica1[Replica 1]
        Replica2[Replica 2]
    end

    subgraph Backup["Backup"]
        SeaweedFS[SeaweedFS]
    end

    Primary -->|"WAL Stream"| Replica1
    Primary -->|"WAL Stream"| Replica2
    Primary -->|"WAL Archive"| SeaweedFS

Multi-Region DR

flowchart TB
    subgraph Region1["Region 1 (Primary)"]
        PG1[CNPG Primary]
    end

    subgraph Region2["Region 2 (DR)"]
        PG2[CNPG Standby]
    end

    subgraph Backup["Backup"]
        SeaweedFS[SeaweedFS]
    end

    PG1 -->|"WAL Streaming"| PG2
    PG1 -->|"WAL Archive"| SeaweedFS
    PG2 -->|"WAL Restore"| SeaweedFS

Configuration

Cluster Definition

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: <org>-postgres
  namespace: databases
spec:
  instances: 3

  postgresql:
    parameters:
      max_connections: "200"
      shared_buffers: 256MB

  storage:
    size: 10Gi
    storageClass: <storage-class>

  backup:
    barmanObjectStore:
      destinationPath: s3://cnpg-backups/<org>
      endpointURL: http://seaweedfs.storage.svc:8333
      s3Credentials:
        accessKeyId:
          name: seaweedfs-credentials
          key: access-key
        secretAccessKey:
          name: seaweedfs-credentials
          key: secret-key
      wal:
        compression: gzip
    retentionPolicy: "30d"

  monitoring:
    enablePodMonitor: true

DR Replica (Region 2)

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: <org>-postgres-dr
  namespace: databases
spec:
  instances: 1

  replica:
    enabled: true
    source: <org>-postgres

  externalClusters:
    - name: <org>-postgres
      connectionParameters:
        host: postgres.<env>.<sovereign-domain>
        user: streaming_replica
      password:
        name: pg-replica-credentials
        key: password

Backup Strategy

Type Schedule Retention
WAL Archive Continuous 7 days
Base Backup Daily 2 AM 30 days
Point-in-Time On-demand Per backup

Scheduled Backup

apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
  name: <org>-daily-backup
  namespace: databases
spec:
  schedule: "0 2 * * *"
  backupOwnerReference: self
  cluster:
    name: <org>-postgres

Failover

Automatic (Within Region)

CNPG automatically promotes replicas when primary fails.

Manual (Cross-Region)

# Promote DR cluster
kubectl cnpg promote <org>-postgres-dr -n databases

Monitoring

Metric Description
cnpg_pg_replication_lag Replication lag in seconds
cnpg_pg_database_size_bytes Database size
cnpg_pg_stat_activity_count Active connections

PgBouncer Integration

Connection pooling with PgBouncer:

apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
  name: <org>-pooler
  namespace: databases
spec:
  cluster:
    name: <org>-postgres
  instances: 2
  type: rw
  pgbouncer:
    poolMode: transaction
    parameters:
      max_client_conn: "1000"
      default_pool_size: "20"

Part of OpenOva