Advanced example

CloudNativePG

Distributed PostgreSQL with primary/standby replication. Restore replicas on newly provisioned burst nodes.

CloudNativePG is the Kubernetes operator for PostgreSQL. It manages the full lifecycle of a highly available cluster with primary/standby architecture using streaming replication. When you scale replicas, new pods target burst nodes via nodeSelector. Cloudburst provisions a node, the pod schedules, and CloudNativePG restores the replica from the primary via streaming replication.

Scale replicas → Pod Pending → Cloudburst provisions node → Replica restores via streaming replication
CloudNativePG + Cloudburst: scale instances → replica pod Pending → Cloudburst provisions burst node → pod schedules → CloudNativePG restores replica from primary via streaming replication.
Prerequisites

1. Install CloudNativePG operator

kubectl apply --server-side -f \
  https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.28/releases/cnpg-1.28.1.yaml

Verify the operator is running:

kubectl rollout status deployment -n cnpg-system cnpg-controller-manager

2. NodePool and NodeClass for burst nodes

Create a NodePool and NodeClass so Cloudburst can provision nodes for PostgreSQL replicas. Use the same pattern as GCP or Hetzner. The NodePool template must include cloudburst.io/nodepool: cnpg-nodepool so the Cluster's nodeSelector matches.

apiVersion: cloudburst.io/v1alpha1
kind: NodePool
metadata:
  name: cnpg-nodepool
  namespace: default
spec:
  requirements:
    regionConstraint: "ANY"
    arch: ["x86_64"]
    maxPriceEurPerHour: 0.15
    allowedProviders: ["gcp"]  # or hetzner, aws, etc.
  limits:
    maxNodes: 3
    minNodes: 0
  template:
    labels:
      cloudburst.io/nodepool: "cnpg-nodepool"
      cloudburst.io/provider: "gcp"
  disruption:
    ttlSecondsAfterEmpty: 120
    ttlSecondsUntilExpired: 3600
  weight: 1

Add the corresponding NodeClass for your provider (see provider examples).

3. CloudNativePG Cluster with nodeSelector

Create a Cluster that schedules all instances on burst nodes. With instances: 2, the primary starts first. The replica pod is Pending until a burst node exists. Cloudburst provisions a node, the pod schedules, and CloudNativePG restores the replica from the primary via streaming replication.

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cnpg-cluster
  namespace: default
spec:
  instances: 2
  imageName: ghcr.io/cloudnative-pg/postgresql:16
  storage:
    size: 5Gi
    storageClass: longhorn  # or standard, local-path, etc.
  affinity:
    nodeSelector:
      cloudburst.io/nodepool: "cnpg-nodepool"
    enablePodAntiAffinity: true
    topologyKey: kubernetes.io/hostname

4. Apply and verify

kubectl apply -f cnpg-cluster.yaml
kubectl get cluster -n default
kubectl get pods -l cnpg.io/cluster=cnpg-cluster -w
kubectl get nodeclaims -w

Watch the flow: the primary pod schedules first (if a burst node exists or the primary can land on a stable node—otherwise both are Pending). When you have instances: 2 and only one node, the replica stays Pending. Cloudburst provisions a second node, the replica schedules, and CloudNativePG restores it from the primary via streaming replication.

5. Scale replicas

Increase instances to add more read replicas. Each new replica pod targets burst nodes via nodeSelector. Pending pods trigger Cloudburst to provision additional nodes.

kubectl patch cluster cnpg-cluster -n default --type merge -p '{"spec":{"instances":3}}'

For more on CloudNativePG (backups, PITR, PgBouncer), see the CloudNativePG documentation.

↑ Kind integrations · ↑ Back to examples