A production-ready PostgreSQL cluster for Kubernetes built with CloudNativePG. This project provides a complete database platform with high availability, automated secrets management, S3-compatible backups, and comprehensive monitoring.
Support the project:
| Application | Description |
|---|---|
| CloudNativePG | PostgreSQL operator for Kubernetes with HA, backups, and rolling updates |
| PostgreSQL 16.3 | 3-node cluster with replication and failover |
| PgBouncer | Connection pooler with session mode (1000 max connections) |
| Application | Description |
|---|---|
| OpenBao | Vault-compatible secrets backend with Raft consensus |
| External Secrets Operator | Kubernetes-native secret synchronization |
| Secrets Store CSI Driver | Mount secrets as volumes in pods |
| Application | Description |
|---|---|
| RustFS | S3-compatible object storage for backups |
| Barman Cloud | PostgreSQL backup and recovery via CNPG plugin |
| Application | Description |
|---|---|
| Pigsty pg_exporter | Comprehensive PostgreSQL metrics exporter |
| VictoriaMetrics | Time-series database for metrics storage |
For detailed setup instructions, configuration examples, and deployment strategies:
Supercharge Postgres on K8s: A CNPG + PostgreSQL + Pigsty + Observability Guide
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Kubernetes Cluster β
β β
ββββββββββββββββ β βββββββββββββββββββ βββββββββββββββββββββββββββ β
β Client ββββββββββββββββΌβββ PgBouncer ββββββββ PostgreSQL Cluster β β
β Application β β β (2 replicas) β β (3 nodes: 1 primary, β β
ββββββββββββββββ β βββββββββββββββββββ β 2 replicas) β β
β βββββββββββββ¬ββββββββββββββ β
β β β
β βββββββββββββββββββ β β
β β OpenBao β Credentials β Backups β
β β (3 replicas) ββββββββββββββββββββ€ β
β β Raft HA β β β
β ββββββββββ¬βββββββββ βΌ β
β β βββββββββββββββββββ β
β β β RustFS β β
β βΌ β (S3 Storage) β β
β βββββββββββββββββββ β 40Gi β β
β β External Secretsβ βββββββββββββββββββ β
β β Operator β β
β βββββββββββββββββββ βββββββββββββββββββ
β β Pigsty Exporterβ
β Metrics βββββββββββββββββββββ (Monitoring) β
β ββββββββββ¬βββββββββ
β β β
ββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββ
β
βΌ
βββββββββββββββββββ
β VictoriaMetrics β
β (Metrics DB) β
βββββββββββββββββββ
- Kubernetes cluster (1.25+)
- CloudNativePG Operator
- External Secrets Operator
- Secrets Store CSI Driver
- VictoriaMetrics Operator (for monitoring)
- Storage class:
openebs-lvmor equivalent
# Add Helm repository
helm repo add openbao https://openbao.github.io/openbao-helm
helm repo update
# Install OpenBao
helm install openbao openbao/openbao \
--namespace openbao \
--create-namespace \
-f openbao/values.yml
# Initialize and unseal (follow OpenBao documentation)
kubectl exec -n openbao openbao-0 -- bao operator init
kubectl exec -n openbao openbao-0 -- bao operator unseal <key># Enable Kubernetes auth
kubectl exec -n openbao openbao-0 -- bao auth enable kubernetes
# Configure the auth method (see external-secret-operator/k8s-role.md for details)
kubectl exec -n openbao openbao-0 -- bao write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc:443"
# Create policy for External Secrets Operator
kubectl exec -n openbao openbao-0 -- bao policy write eso-policy - <<EOF
path "secrets/*" {
capabilities = ["read", "list"]
}
EOF
# Create role
kubectl exec -n openbao openbao-0 -- bao write auth/kubernetes/role/openbao-readonly \
bound_service_account_names=openbao-sa \
bound_service_account_namespaces=postgres \
policies=eso-policy \
ttl=1h# Create namespace and deploy
kubectl apply -f rustfs/rustfs-stack.yml
# Verify deployment
kubectl get pods -n rustfs# Create namespace
kubectl create namespace postgres
# Apply secret store and generators
kubectl apply -f external-secret-operator/secret-store.yml
kubectl apply -f external-secret-operator/password-generator.yml
kubectl apply -f external-secret-operator/es-superuser.yml
kubectl apply -f external-secret-operator/es-application.yml
kubectl apply -f external-secret-operator/push-secret.yml# Apply CNPG resources
kubectl apply -f cnpg/object-store.yml
kubectl apply -f cnpg/es-object-store.yml
kubectl apply -f cnpg/cluster.yml
kubectl apply -f cnpg/connection-pooler.yml
# Verify cluster status
kubectl get cluster -n postgres
kubectl get pods -n postgres# Apply Pigsty exporter and monitoring rules
kubectl apply -f pigsty-exporter/es-exporter-cred.yml
kubectl apply -f pigsty-exporter/exporter.yml
kubectl apply -f pigsty-exporter/pod-monitor.yml
kubectl apply -f pigsty-exporter/vmservicescrape.yml
kubectl apply -f pigsty-exporter/vmrule.yml# Get connection credentials
kubectl get secret cluster-app-user -n postgres -o jsonpath='{.data.password}' | base64 -d
# Connect via pgbouncer (LoadBalancer)
kubectl get svc -n postgres psql-cluster-pooler
# Port forward for local access
kubectl port-forward svc/psql-cluster-pooler -n postgres 5432:5432
psql -h localhost -U app -d appThe cluster is configured in cnpg/cluster.yml:
# Key settings
instances: 3
postgresql:
parameters:
max_connections: "200"
shared_buffers: "256MB"
effective_cache_size: "768MB"
wal_buffers: "8MB"
min_wal_size: "1GB"
max_wal_size: "2GB"Resources per instance:
- Memory: 384Mi - 1Gi
- CPU: 200m - 2 cores
- Storage: 5Gi (OpenEBS LVM)
PgBouncer is configured in cnpg/connection-pooler.yml:
instances: 2
type: rw # Read-write connections
poolMode: session # Session pooling mode
parameters:
max_client_conn: "1000"
default_pool_size: "10"Backups are configured in cnpg/object-store.yml:
retentionPolicy: "30d"
barmanObjectStore:
destinationPath: s3://ar-cnpg-backup/hl-cnpg-cluster/
endpointURL: http://rustfs-service.rustfs.svc:7000
wal:
compression: gzip
data:
compression: gzipManual backup:
kubectl apply -f cnpg/backup.yml
kubectl get backup -n postgresExternal Secrets Operator handles credential rotation:
- Superuser credentials: Auto-generated, 24h refresh
- Application credentials: Auto-generated, 24h refresh
- Backup credentials: Synced from OpenBao vault
Configure the secret store in external-secret-operator/secret-store.yml:
provider:
vault:
server: "http://openbao.openbao.svc:8200"
path: "secrets"
version: "v2"cnpg-postgres-stack/
βββ cnpg/ # PostgreSQL cluster configurations
β βββ cluster.yml # 3-node PostgreSQL cluster definition
β βββ connection-pooler.yml # PgBouncer pooler configuration
β βββ backup.yml # On-demand backup resource
β βββ object-store.yml # S3 backup destination config
β βββ es-object-store.yml # External secret for backup creds
βββ external-secret-operator/ # Secret management
β βββ secret-store.yml # OpenBao connection config
β βββ password-generator.yml # Automatic password generation
β βββ es-superuser.yml # PostgreSQL superuser secret
β βββ es-application.yml # Application user secret
β βββ push-secret.yml # Sync secrets back to vault
β βββ k8s-role.md # Kubernetes auth setup guide
βββ openbao/ # Secrets backend
β βββ Chart.yml # Helm chart definition
β βββ values.yml # OpenBao Helm values (3-node HA)
βββ pigsty-exporter/ # Monitoring stack
β βββ exporter.yml # pg_exporter deployment
β βββ pg_exporter.yml # Metrics collector config
β βββ vmrule.yml # Recording & alerting rules
β βββ pod-monitor.yml # Prometheus PodMonitor
β βββ vmservicescrape.yml # VictoriaMetrics scrape config
β βββ es-exporter-cred.yml # Exporter credentials secret
βββ rustfs/ # S3-compatible storage
β βββ rustfs-stack.yml # Complete RustFS deployment
βββ LICENSE # MIT License
βββ README.md # This file
| Component | Storage | Class |
|---|---|---|
| PostgreSQL (per instance) | 5Gi Γ 3 | openebs-lvm |
| OpenBao data (per instance) | 2Gi Γ 3 | openebs-lvm |
| OpenBao audit (per instance) | 1Gi Γ 3 | openebs-lvm |
| RustFS | 40Gi | openebs-lvm |
| Total | ~64Gi |
The Pigsty exporter provides comprehensive PostgreSQL metrics:
- Connection statistics and pooler metrics
- Replication lag and streaming status
- Query performance (pg_stat_statements)
- Table and index bloat detection
- WAL archiving status
- Lock contention monitoring
- Background worker statistics
Access metrics:
# Port forward to exporter
kubectl port-forward svc/pg-exporter -n postgres 9630:9630
# View metrics
curl http://localhost:9630/metricsVictoriaMetrics integration:
- Recording rules aggregate metrics for dashboards
- Alert rules monitor database health
- ServiceScrape configured for 30s intervals
Contributions are welcome. If you find a bug or have an improvement:
- Fork the repository
- Create a feature branch
- Submit a pull request
Please open an issue first to discuss significant changes.
This project is licensed under the MIT License - see the LICENSE file for details.
This project is intended for educational purposes and development environments.
The default configuration uses trust-based authentication which is not suitable for production. Before deploying to production:
- Change
pg_hbaauthentication fromtrusttoscram-sha-256 - Enable TLS for all connections
- Review and harden OpenBao seal configuration
- Implement proper network policies
- Configure appropriate resource limits for your workload
Users are solely responsible for ensuring their deployment meets security requirements for their environment.
