Installing PostgreSQL on Kubernetes Using CloudNativePG (CNPG)

Create CNPG Directory & postgres.yaml Manifest

Create a directory for CNPG configuration and add the postgres.yaml file:
vi postgres.yaml

Cluster 1 — app-db-cluster (Application Database)

apiVersion: postgresql.cnpg.io/v1
kind: Cluster

metadata:
  name: app-db-cluster
  namespace: prod-database

spec:

  instances: 2
  imageName: ghcr.io/cloudnative-pg/postgresql:16.2

  affinity:
    nodeSelector:
      role: “database”

    tolerations:
      – key: “database”
        operator: “Equal”
        value: “true”
        effect: “NoSchedule”

  bootstrap:

    initdb:
      database: appdb
      owner: appuser
      dataChecksums: true
      encoding: ‘UTF8’
  enableSuperuserAccess: true

  postgresql:

    parameters:
      checkpoint_timeout: “15min”
      max_connections: “512”
      max_locks_per_transaction: “512”
      max_wal_size: “16GB”
      random_page_cost: “1”
      shared_buffers: “2GB”

  resources:

    requests:
      cpu: “4”
      memory: “8Gi”

    limits:

      cpu: “4”
      memory: “8Gi”

  storage:
    size: 40Gi
    storageClass: standard-local-storage

Cluster 2 — customer-db-cluster (Customer Database)

apiVersion: postgresql.cnpg.io/v1
kind: Cluster

metadata:
  name: customer-db-cluster
  namespace: prod-database

spec:
  instances: 2
  imageName: ghcr.io/cloudnative-pg/postgresql:16.2

  affinity:
    nodeSelector:
      role: “database”

    tolerations:
      – key: “database”
        operator: “Equal”
        value: “true”
        effect: “NoSchedule”

  bootstrap:

    initdb:
      database: customerdb
      owner: custowner
      dataChecksums: true
      encoding: ‘UTF8’
  enableSuperuserAccess: true

  postgresql:

    parameters:
      checkpoint_timeout: “15min”
      max_connections: “512”
      max_locks_per_transaction: “512”
      max_wal_size: “16GB”
      random_page_cost: “1”
      shared_buffers: “3GB”

  resources:

    requests:
      cpu: “6”
      memory: “12Gi”

    limits:
      cpu: “6”
      memory: “12Gi”

  storage:
    size: 50Gi
    storageClass: standard-local-storage


Add CNPG Helm Repo & Install Operator
*************************************
This command will add the CloudNativePG repository to your Helm configuration.
helm repo add cnpg https://cloudnative-pg.github.io/charts

This command installs the CloudNativePG Helm chart under the release name cnpg into the cnpg-system namespace

helm upgrade --install cnpg   --namespace cnpg-system   --create-namespace   cnpg/cloudnative-pg


Validate Configuration (Dry Run)
********************************
Dry Run the Manifest to Check for any Syntax Errors:
kubectl apply -f postgres.yaml --dry-run=server


Deploy Both Clusters
********************************
kubectl apply -f postgres.yaml


Verify Pods
********************************
This command is used to list all the pods in the ped-prod namespace:
kubectl get pods -n prod-database

This command is useful for keeping an eye on your database-related pods and their status:
kubectl get pods-n ped-prod-o wide-w |grep database


 List Secrets
********************************
The command kubectl get secrets-n ped-prod is used to list all the secrets in the ped-prod namespace:
kubectl get secrets -n prod-database


Validate Replication Roles
********************************
kubectl exec -t app-db-cluster-1 -n prod-database -- psql -U postgres -c "SELECT pg_is_in_recovery();"


Install CNPG Plugin (kubectl cnpg)
********************************
curl -sSfL https://github.com/cloudnative-pg/cloudnative-pg/raw/main/hack/install-cnpg-plugin.sh | sudo sh -s -- -b /usr/local/bin


Expected Output:
-----------------
cloudnative-pg/cloudnative-pg info checking GitHub for latest tag cloudnative-pg/cloudnative-pg info found version: 1.25.1 for v1.25.1/linux/x86_64 cloudnative-pg/cloudnative-pg info installed /usr/local/bin/kubectl-cnpg

Now check status by running below command:
kubectl cnpg status


List CNPG Clusters
********************************
kubectl get clusters.postgresql.cnpg.io -n prod-database


Check Status of customer-db-cluster
********************************
kubectl cnpg status customer-db-cluster customer-db-cluster-1 -n prod-database


Check Status of app-db-cluster
********************************
kubectl cnpg status app-db-cluster app-db-cluster-1 -n prod-database

--------------********************************-----------------------

Conclusion

  • With CNPG:

    • PostgreSQL becomes fully declarative

    • Replication & failover are automatic

    • Secrets and TLS are handled by the operator

    • Pod placement & resource policies are cleanly managed

    • You get production-grade HA PostgreSQL on Kubernetes
  • This deployment includes:

    • app-db-cluster

    • customer-db-cluster running reliably inside the prod-database namespace.

12 Comments

    • Thank you! I’m glad you found the articles and reviews informative, it motivates me to keep sharing quality content.

    • I really appreciate that! I believe detailed reviews help the community most, so happy it resonated.

  1. Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.

    • Really appreciate your feedback! It means a lot to know the content is motivating. More inspiring posts are on the way!

Leave a Reply

Your email address will not be published. Required fields are marked *