CloudNativePG (CNPG) is a Kubernetes-native PostgreSQL offering which provides high-availability, self-healing, seamless backups, and rolling updates. In short, if you like PostgreSQL and Kubernetes, you will love it. I won’t cover installing it, its pretty straight forward if you read their documentation. This is about migrating data from all the other deployments into a new CNPG cluster.

The PostgreSQL command line tools are expected to be on the path for any of this to work.

The Process

For this example, I’ll use NextCloud, because it was the most recent thing I migrated.

Collect Connection Details

First, collect all the information for the connection:

  • Namespace: office
  • Host/Service Name: nextcloud-postgresql
  • User: nextcloud
  • Password: some-very-secure-password
  • Database: nextcloud

Connecting

Setup a port forward for the current database:

kubectl port-forward -n office svc/nextcloud-postgresql 5432:5432

Scale Down Application Deployment

Scale down the application so the database state doesn’t change between the dump and the load. That would be bad.

kubectl scale deployment -n office nextcloud --replicas 0

Dump the Data

Dump the schema using pg_dump, you will be prompted for the password:

pg_dump -h localhost -U nextcloud nextcloud > nextcloud.sql

Scale Down Database StatefulSet

Now that its dumped, scale down the database so it doesn’t accidentally get in the way.

kubectl scale statefulset -n office nextcloud-postgresql --replicas 0

Creating and Loading

I created script to prompt for all the details. Use this script, or a variation of its commands to create the resources and load the dump.

#!/bin/sh

# Stop on any error
set -e

echo -n "Postgres Host: "
read PGHOST

echo -n "Postgres User: "
read PGUSER

echo -n "Postgres Password: "
read -s PGPASSWORD
echo

echo -n "Database: "
read DB_NAME

echo -n "Database User: "
read DB_USER

echo -n "Database Password: "
read -s DB_PASS
echo

echo -n "Database Dump: "
read DB_FILE

echo "Creating user"
createuser "${DB_USER}"
psql --command "alter user \"${DB_USER}\" with encrypted password '${DB_PASS}';"

echo "Creating database"
createdb --owner "${DB_USER}" -T template0 "${DB_NAME}"

echo "Granting privileges to user"
psql --command "grant all privileges on database \"${DB_NAME}\" to \"${DB_USER}\";"

echo "Loading dump"
psql "${DB_NAME}" -f "${DB_FILE}"

Update Configuration

This part is very application specific. In the NextCloud Helm chart I had to disable the PostgreSQL sub-chart and configure the external database configuration to use the new host and credentials.

If the deployment is managed with Helm, then pushing a new config update with the updated connection details should also scale up the deployment to the default. If it does not, just do the opposite of scaling down.

kubectl scale deployment -n office nextcloud --replicas 1

Now all thats left is cleaning up residual resources.