Skip to content

cnpg-database-manager

Version: 0.1.3 Type: application AppVersion: 1.0

Multi-database and multi-tenant management for CloudNativePG clusters with automatic secret generation and isolation

Homepage: https://github.com/encircle360-oss/helm-charts/tree/main/charts/cnpg-database-manager

⚠️ UNDER CONSTRUCTION This chart is currently under active development and has not been battle-tested in production environments. NOT PRODUCTION READY - Use at your own risk and thoroughly test in non-production environments first.

Why This Chart?

The official CloudNativePG cluster chart only supports single database per deployment. This chart fills the gap by providing:

  • Multi-Database Management: Deploy multiple databases in one PostgreSQL cluster
  • Automatic Secret Generation: Each database gets isolated credentials
  • Secret Replication: Optional secret distribution to application namespaces
  • Multi-Tenant Ready: Perfect for consolidating multiple lightweight databases

Use this chart when you want to consolidate multiple applications into one PostgreSQL cluster while maintaining security isolation.

Prerequisites

  • Kubernetes 1.24+
  • Helm 3.8+
  • CloudNativePG operator installed (v1.25+)

Installing the Chart

To install the chart with the release name my-databases:

helm repo add encircle360-oss https://encircle360-oss.github.io/helm-charts/
helm repo update
helm install my-databases encircle360-oss/cnpg-database-manager

Uninstalling the Chart

To uninstall/delete the my-databases deployment:

helm uninstall my-databases

Configuration

Basic Example - Single Cluster with Multiple Databases

clusters:
  main:
    enabled: true
    instances: 3
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 50Gi
      storageClass: standard
    databases:
      - name: keycloak
        owner: keycloak
      - name: paperless
        owner: paperless
      - name: n8n
        owner: n8n

This creates: - One PostgreSQL cluster named main with 3 instances - Three separate databases with isolated credentials - Automatic secret generation for each database

Multi-Cluster Setup

clusters:
  production:
    enabled: true
    instances: 3
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 100Gi
    databases:
      - name: api-prod
        owner: api
      - name: web-prod
        owner: web

  staging:
    enabled: true
    instances: 1
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 20Gi
    databases:
      - name: api-staging
        owner: api
      - name: web-staging
        owner: web

Backup Configuration

clusters:
  main:
    enabled: true
    instances: 3
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 50Gi
    backup:
      enabled: true
      schedule: "0 0 * * *"
      retentionPolicy: "30d"
      s3:
        bucket: my-postgres-backups
        region: eu-central-1
        path: /cluster-main
        credentials:
          existingSecret: s3-credentials
    databases:
      - name: production-db
        owner: app

Monitoring with Prometheus

clusters:
  main:
    enabled: true
    instances: 3
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 50Gi
    monitoring:
      enabled: true
      podMonitor:
        enabled: true
    databases:
      - name: app-db
        owner: app

Secret Replication to Application Namespaces

clusters:
  main:
    enabled: true
    instances: 3
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 50Gi
    databases:
      - name: keycloak
        owner: keycloak
        secretNamespace: keycloak-ns
      - name: paperless
        owner: paperless
        secretNamespace: paperless-ns

This automatically replicates database secrets to the application namespaces.

Advanced PostgreSQL Configuration

clusters:
  main:
    enabled: true
    instances: 3
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 100Gi
      storageClass: fast-ssd
    resources:
      requests:
        memory: "4Gi"
        cpu: "2000m"
      limits:
        memory: "8Gi"
        cpu: "4000m"
    postgresql:
      parameters:
        max_connections: "300"
        shared_buffers: "2GB"
        effective_cache_size: "6GB"
        maintenance_work_mem: "512MB"
        checkpoint_completion_target: "0.9"
        wal_buffers: "16MB"
        default_statistics_target: "100"
        random_page_cost: "1.1"
        effective_io_concurrency: "200"
        work_mem: "6990kB"
        min_wal_size: "1GB"
        max_wal_size: "4GB"
    databases:
      - name: highload-app
        owner: app

Maintainers

Name Email Url
encircle360-oss oss@encircle360.com

Source Code

Values

Key Type Default Description
clusters object {} (no clusters deployed by default) PostgreSQL cluster configurations. Each key represents a cluster name.

Configuration Parameters

The chart uses a dynamic configuration structure where each PostgreSQL cluster is defined under the clusters key. Below are the detailed configuration options:

Cluster Configuration

Parameter Type Required Default Description
clusters.<name>.enabled bool Yes - Enable or disable this cluster
clusters.<name>.instances int Yes - Number of PostgreSQL instances (replicas)
clusters.<name>.imageName string Yes - PostgreSQL container image with tag
clusters.<name>.storage.size string Yes - Size of persistent volume (e.g., 50Gi)
clusters.<name>.storage.storageClass string No - Storage class name
clusters.<name>.resources.requests.memory string No - Memory request (e.g., 2Gi)
clusters.<name>.resources.requests.cpu string No - CPU request (e.g., 1000m)
clusters.<name>.resources.limits.memory string No - Memory limit (e.g., 4Gi)
clusters.<name>.resources.limits.cpu string No - CPU limit (e.g., 2000m)
clusters.<name>.maxConnections string No "200" Maximum number of connections
clusters.<name>.sharedBuffers string No "256MB" Shared memory buffers
clusters.<name>.effectiveCacheSize string No "1GB" Effective cache size
clusters.<name>.maintenanceWorkMem string No "64MB" Maintenance work memory
clusters.<name>.checkpointCompletionTarget string No "0.9" Checkpoint completion target
clusters.<name>.walBuffers string No "16MB" WAL buffers
clusters.<name>.defaultStatisticsTarget string No "100" Default statistics target
clusters.<name>.randomPageCost string No "1.1" Random page cost
clusters.<name>.effectiveIoConcurrency string No "200" Effective I/O concurrency
clusters.<name>.workMem string No "4MB" Work memory per operation
clusters.<name>.minWalSize string No "1GB" Minimum WAL size
clusters.<name>.maxWalSize string No "4GB" Maximum WAL size
clusters.<name>.parameters object No {} Additional custom PostgreSQL parameters
clusters.<name>.monitoring.enabled bool No false Enable Prometheus monitoring
clusters.<name>.backup.enabled bool No false Enable automated backups
clusters.<name>.backup.schedule string No "0 0 0 * * *" Backup schedule (cron format)
clusters.<name>.backup.retentionPolicy string No "30d" Backup retention policy
clusters.<name>.backup.s3.bucket string Yes (if S3) - S3 bucket name for backups
clusters.<name>.backup.s3.endpoint string Yes (if S3) - S3 endpoint URL
clusters.<name>.backup.s3.region string No - S3 region
clusters.<name>.backup.s3.accessKeyId string Yes (if S3) - S3 access key ID
clusters.<name>.backup.s3.secretAccessKey string Yes (if S3) - S3 secret access key
clusters.<name>.backup.s3.credentials.existingSecret string No - Existing secret (alternative to accessKeyId/secretAccessKey)
clusters.<name>.initdb.postInitSQL array No [] Custom SQL statements after init

Database Configuration

Parameter Type Required Default Description
clusters.<name>.databases[].name string Yes - Database name
clusters.<name>.databases[].owner string Yes - Database owner/user name
clusters.<name>.databases[].targetNamespace string No - Target namespace for secret replication
clusters.<name>.databases[].existingSecret string No - Use existing secret for credentials
clusters.<name>.databases[].encoding string No "UTF8" Database encoding
clusters.<name>.databases[].locale string No "C" Database locale

How It Works

Database and User Creation

For each database defined in clusters.<name>.databases[]:

  1. Database Resource: A CloudNativePG Database resource is created
  2. User/Owner: A PostgreSQL user is automatically created with the owner name
  3. Secret Generation: A Kubernetes Secret is created with connection details:
  4. username: The database owner
  5. password: Auto-generated secure password
  6. dbname: Database name
  7. host: Cluster service endpoint
  8. port: PostgreSQL port (5432)
  9. jdbc-url: JDBC connection string
  10. uri: PostgreSQL URI connection string

Secret Naming

Secrets follow the naming pattern: <cluster-name>-<database-name>-app

Example: For cluster main and database keycloak, the secret is main-keycloak-app

Secret Replication

If secretNamespace is specified for a database, the secret is automatically replicated to that namespace using Kubernetes secret reflection or a custom replication mechanism.

Use Cases

Microservices Consolidation

Instead of running separate PostgreSQL instances for each microservice:

clusters:
  microservices:
    enabled: true
    instances: 3
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 100Gi
    databases:
      - name: auth-service
        owner: auth
        secretNamespace: auth
      - name: user-service
        owner: users
        secretNamespace: users
      - name: order-service
        owner: orders
        secretNamespace: orders
      - name: payment-service
        owner: payments
        secretNamespace: payments

Multi-Tenant SaaS

Isolate tenant databases while sharing infrastructure:

clusters:
  saas-prod:
    enabled: true
    instances: 5
    imageName: ghcr.io/cloudnative-pg/postgresql:17.2
    storage:
      size: 500Gi
    databases:
      - name: tenant-acme
        owner: tenant_acme
      - name: tenant-widgets
        owner: tenant_widgets
      - name: tenant-global
        owner: tenant_global

Development/Staging/Production

Manage all environments from one chart:

clusters:
  dev:
    enabled: true
    instances: 1
    storage:
      size: 10Gi
    databases:
      - name: app-dev
        owner: dev

  staging:
    enabled: true
    instances: 2
    storage:
      size: 50Gi
    databases:
      - name: app-staging
        owner: staging

  prod:
    enabled: true
    instances: 3
    storage:
      size: 200Gi
    backup:
      enabled: true
    databases:
      - name: app-prod
        owner: prod

Troubleshooting

Check Cluster Status

kubectl get cluster
kubectl describe cluster <cluster-name>

Check Database Creation

kubectl get database
kubectl describe database <cluster-name>-<database-name>

View Generated Secrets

kubectl get secret <cluster-name>-<database-name>-app -o yaml

Check Operator Logs

kubectl logs -n cnpg-system deployment/cnpg-controller-manager

Comparison with Official Charts

Feature Official cluster Chart This Chart
Cluster Management
Multiple Databases ❌ (one per deployment) ✅ (many per cluster)
Automatic Secrets
Secret Replication
Multi-Cluster
Backup Configuration
Monitoring

Support & Professional Services

Community Support

For issues and questions about this Helm chart: - Open an issue in GitHub Issues - Start a discussion in GitHub Discussions

For CloudNativePG specific issues: - Visit the CloudNativePG GitHub repository - Check the CloudNativePG documentation

Professional Support

For professional support, consulting, custom development, or enterprise solutions, contact hello@encircle360.com

Disclaimer

⚠️ This chart is under active development and NOT production-ready.

This Helm chart is provided "AS IS" without warranty of any kind. encircle360 GmbH and the contributors: - Make no warranties about the completeness, reliability, or accuracy of this chart - Are not liable for any damages arising from the use of this chart - Strongly recommend thorough testing in non-production environments only - Do not recommend this chart for production use at this time

Use this chart at your own risk. For production-ready PostgreSQL solutions with SLA requirements, contact our professional support services at hello@encircle360.com

License

This chart is licensed under the Apache License 2.0. See LICENSE for details.

Default Values

For a complete list of configuration options, see the values.yaml file.