Cloud Native PostgreSQL

Cloud Native PostgreSQL in Thalassa Cloud Kubernetes

CloudNativePG (CNPG) is a Kubernetes operator that simplifies deploying and managing PostgreSQL databases in Kubernetes clusters. By installing CloudNativePG in your Thalassa Cloud Kubernetes cluster, you can run production-ready PostgreSQL databases with high availability, automated backups, and seamless integration with Kubernetes features. This guide walks you through installing CloudNativePG, creating PostgreSQL clusters, configuring high availability, and integrating with Thalassa Cloud’s storage and networking features.

Prerequisites

Before installing CloudNativePG, ensure you have a few things in place. First, you need a running Kubernetes cluster in Thalassa Cloud. CloudNativePG works with Kubernetes 1.24 or later, and Thalassa Cloud clusters meet this requirement.

You’ll also need cluster access configured using kubectl. Use tcloud kubernetes connect to configure access, or set up kubeconfig manually. You’ll need cluster administrator permissions to install CloudNativePG, as it requires creating cluster-level resources.

Finally, ensure your cluster has sufficient resources. CloudNativePG itself is lightweight, but PostgreSQL clusters require CPU, memory, and storage. Plan for at least one node with adequate resources for your database workloads, and consider using dedicated node pools for database instances. For information about storage options, see the Storage documentation and Persistent Volumes documentation. For details about node management, see the Nodes documentation.

Setting up CloudNative PG

Installing the CloudNative PG Operator

The recommended way to install CloudNativePG is using the official Helm chart, which provides a straightforward installation process and makes it easy to configure the operator.

First, add the CloudNativePG Helm repository:

helm repo add cnpg https://cloudnative-pg.github.io/charts
helm repo update

Install CloudNativePG using Helm:

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

This installs CloudNativePG in the cnpg-system namespace with default settings. The installation includes the operator and all necessary CRDs for managing PostgreSQL clusters.

Verify that CloudNativePG is running:

kubectl get pods -n cnpg-system

You should see pods for the CloudNativePG operator. Check their status:

kubectl get pods -n cnpg-system
kubectl logs -n cnpg-system -l app.kubernetes.io/name=cloudnative-pg

The logs should show that the operator is running and ready to manage PostgreSQL clusters.

Verify that the CRDs are installed:

kubectl get crd | grep postgresql

You should see CRDs for clusters.postgresql.cnpg.io and related resources.

Creating Your First PostgreSQL Cluster

With CloudNativePG installed, you can create your first PostgreSQL cluster. CloudNativePG uses Cluster custom resources to define PostgreSQL clusters.

Create a simple PostgreSQL cluster:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: postgres-cluster
  namespace: default
spec:
  instances: 3
  postgresql:
    parameters:
      max_connections: "100"
      shared_buffers: "256MB"
      effective_cache_size: "1GB"
  storage:
    size: 20Gi
    storageClass: tc-block
  resources:
    requests:
      memory: "512Mi"
      cpu: "500m"
    limits:
      memory: "1Gi"
      cpu: "1000m"

This creates a PostgreSQL cluster with 3 instances (1 primary and 2 replicas) using Thalassa Cloud’s block storage. For information about high availability configurations, see the Highly Available Deployments documentation. Apply this cluster:

kubectl apply -f postgres-cluster.yaml

CloudNativePG will create the cluster, which includes StatefulSets for the PostgreSQL instances, Services for connectivity, and PersistentVolumeClaims for storage. The process typically takes a few minutes as pods start and PostgreSQL initializes.

Monitor the cluster creation:

kubectl get cluster postgres-cluster
kubectl get pods -l cnpg.io/cluster=postgres-cluster

The cluster status shows the current state, including whether instances are ready and which instance is the primary.

Connecting to Your PostgreSQL Cluster

Once the cluster is created, you can connect to it using the services that CloudNativePG creates. The operator creates several services for different connection purposes.

List the services:

kubectl get svc -l cnpg.io/cluster=postgres-cluster

You’ll see services like postgres-cluster-rw (read-write, points to primary), postgres-cluster-ro (read-only, points to replicas), and postgres-cluster-r (read, can point to primary or replicas).

Get connection details:

kubectl get secret postgres-cluster-superuser -o jsonpath='{.data.password}' | base64 -d

This shows the superuser password. The default superuser is postgres, and the database name is postgres.

Connect to the cluster from within the cluster:

kubectl run psql-client --rm -it --image=postgres:15 --restart=Never -- psql -h postgres-cluster-rw -U postgres

This creates a temporary pod with the PostgreSQL client and connects to the cluster. You’ll be prompted for the password.

For applications running in the cluster, use the service names to connect. The postgres-cluster-rw service always points to the primary instance for write operations, while postgres-cluster-ro provides read-only access to replicas.

Configuring High Availability

CloudNativePG provides high availability through PostgreSQL streaming replication. The operator automatically manages replication, monitors instance health, and performs failover when the primary fails.

High Availability

The number of instances in your cluster determines availability. With 3 instances, you have 1 primary and 2 replicas. If the primary fails, one of the replicas is automatically promoted to primary, and applications can continue operating.

Monitor cluster status to see which instance is primary:

kubectl get cluster postgres-cluster -o yaml

The status shows the current primary instance and the health of all instances.

Configure automatic failover behavior:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: postgres-cluster
spec:
  instances: 3
  postgresql:
    parameters:
      synchronous_commit: "on"
      synchronous_standby_names: "ANY 1 (node1, node2)"
  bootstrap:
    initdb:
      database: myapp
      owner: myapp
      secret:
        name: postgres-credentials

This configuration enables synchronous replication, ensuring that transactions are committed on at least one replica before being considered committed on the primary. This provides stronger consistency guarantees but may impact performance.

Managing Backups

CloudNativePG supports automated backups to object storage. You can configure backup schedules and retention policies, and restore clusters from backups when needed.

Configure backups using a Backup resource:

apiVersion: postgresql.cnpg.io/v1
kind: Backup
metadata:
  name: postgres-cluster-backup
  namespace: default
spec:
  cluster:
    name: postgres-cluster
  method: barmanObjectStore
  barmanObjectStore:
    destinationPath: s3://my-bucket/postgres-backups
    s3Credentials:
      accessKeyId:
        name: backup-credentials
        key: ACCESS_KEY_ID
      secretAccessKey:
        name: backup-credentials
        key: SECRET_ACCESS_KEY
    wal:
      retention: "7d"
    data:
      retention: "30d"
    endpoint: https://objects.nl-01.thalassa.cloud
    endpointCA:
      name: s3-ca-cert

This creates a backup configuration that stores backups in S3-compatible object storage. CloudNativePG uses Barman for backup management, which provides point-in-time recovery capabilities.

Create on-demand backups:

kubectl cnpg backup postgres-cluster --backup-name manual-backup

List backups:

kubectl get backups

Restore from a backup by creating a new cluster from the backup:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: postgres-cluster-restored
spec:
  instances: 3
  bootstrap:
    recovery:
      backup:
        name: postgres-cluster-backup
      source: postgres-cluster

This creates a new cluster restored from the specified backup.

Integrating with Thalassa Cloud Storage

CloudNativePG works seamlessly with Thalassa Cloud’s block storage. When you specify storageClass: tc-block in your cluster definition, CloudNativePG creates PersistentVolumeClaims that Thalassa Cloud fulfills with high-performance block storage.

Configure storage for your cluster:

spec:
  storage:
    size: 50Gi
    storageClass: tc-block
    resizeInUseVolumes: true

The resizeInUseVolumes: true option allows volumes to be resized while in use, which is useful as your database grows.

Info

For information about storage classes and persistent volumes, see the Storage Classes documentation and Persistent Volumes documentation.

For backup storage, you can use Thalassa Cloud’s S3-compatible object storage. Configure backups to use object storage:

barmanObjectStore:
  destinationPath: s3://my-backup-bucket/postgres
  endpoint: https://objects.nl-01.thalassa.cloud

This stores backups in object storage, providing durable, scalable backup storage that’s separate from your primary database storage.

Scaling Clusters

CloudNativePG makes it easy to scale PostgreSQL clusters up or down by changing the number of instances. You can also scale storage and compute resources independently.

Scale the number of instances:

kubectl patch cluster postgres-cluster -p '{"spec":{"instances":5}}' --type=merge

This increases the cluster from 3 to 5 instances, adding more replicas for improved read performance and availability.

Scale storage by editing the cluster:

kubectl edit cluster postgres-cluster

Update the storage size in the spec. CloudNativePG will resize the volumes, and you may need to expand filesystems. See the Resize Persistent Volume guide for details.

Scale compute resources:

spec:
  resources:
    requests:
      memory: "2Gi"
      cpu: "2000m"
    limits:
      memory: "4Gi"
      cpu: "4000m"

Update the resources section to change CPU and memory allocation. You may need to restart pods for resource changes to take effect.

Monitoring and Observability

CloudNativePG provides metrics and status information that you can monitor to understand cluster health and performance.

Check cluster status:

kubectl get cluster postgres-cluster -o yaml

This shows detailed status including instance health, primary/replica status, and any issues.

View cluster events:

kubectl get events --field-selector involvedObject.name=postgres-cluster

Events show cluster operations like failovers, backups, and scaling operations.

CloudNativePG exposes Prometheus metrics that you can scrape for monitoring. Configure Prometheus to scrape the operator and cluster metrics:

apiVersion: v1
kind: ServiceMonitor
metadata:
  name: cnpg-metrics
spec:
  selector:
    matchLabels:
      cnpg.io/cluster: postgres-cluster
  endpoints:
  - port: metrics

This creates a ServiceMonitor that Prometheus can use to collect metrics from your PostgreSQL cluster.

Best Practices

Following best practices helps you run PostgreSQL clusters effectively and maintain reliable database operations.

Production Instance Count

Use appropriate instance counts. For production, use at least 3 instances (1 primary, 2 replicas) for high availability. For development, a single instance may be sufficient.

Backup Configuration

Enable backups for production clusters. Configure automated backups to object storage with appropriate retention policies. Test restore procedures regularly to ensure backups are working correctly.

  • Configure resource requests and limits appropriately: PostgreSQL benefits from sufficient memory for caching and CPU for query processing. Monitor resource usage and adjust based on workload characteristics.

  • Plan for storage growth: Databases tend to grow over time, so plan storage capacity accordingly. Use volume resizing capabilities to expand storage as needed.

For more information see the official CloudNativePG documentation.

Summary

CloudNativePG lets you easily run PostgreSQL databases in your Thalassa Cloud Kubernetes cluster. It handles setup, high availability, backups, and database management for you. The operator works well with Thalassa Cloud storage and networking, so you get fast storage for data and object storage for backups. You can manage everything using Kubernetes resources.

For more information about CloudNativePG, see the official CloudNativePG documentation. For details about storage in Thalassa Cloud, see the Storage documentation. For information about persistent volumes used by CloudNativePG, see the Persistent Volumes documentation and Storage Classes documentation. For information about Thalassa Cloud’s managed PostgreSQL service, see the DBaaS documentation. For details about resizing volumes as databases grow, see the Resize Persistent Volume guide.