How do I set up PostgreSQL backup and restore workflows in Kubernetes?
In this guide, we will set up a PostgreSQL database in a Kubernetes cluster and configure backup and restore workflows using Pulumi. We will use Kubernetes CronJobs to schedule the backups and PersistentVolumeClaims to store the backup data.
Key Points
- Deploy a PostgreSQL instance in Kubernetes.
- Set up a PersistentVolumeClaim for backup storage.
- Create a Kubernetes CronJob to handle backups.
- Create a Kubernetes Job to handle restores.
Below is the complete Pulumi program written in TypeScript:
import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";
// Define the namespace
const namespace = new k8s.core.v1.Namespace("pg-backup-restore-ns", {
metadata: { name: "pg-backup-restore" }
});
// Define the PersistentVolumeClaim for backup storage
const backupPvc = new k8s.core.v1.PersistentVolumeClaim("pg-backup-pvc", {
metadata: {
namespace: namespace.metadata.name,
},
spec: {
accessModes: ["ReadWriteOnce"],
resources: {
requests: {
storage: "10Gi",
},
},
},
});
// Define the PostgreSQL deployment
const pgDeployment = new k8s.apps.v1.Deployment("pg-deployment", {
metadata: {
namespace: namespace.metadata.name,
},
spec: {
selector: { matchLabels: { app: "postgres" } },
template: {
metadata: { labels: { app: "postgres" } },
spec: {
containers: [{
name: "postgres",
image: "postgres:13",
env: [
{ name: "POSTGRES_DB", value: "mydatabase" },
{ name: "POSTGRES_USER", value: "myuser" },
{ name: "POSTGRES_PASSWORD", value: "mypassword" },
],
ports: [{ containerPort: 5432 }],
volumeMounts: [{
name: "pgdata",
mountPath: "/var/lib/postgresql/data",
}],
}],
volumes: [{
name: "pgdata",
persistentVolumeClaim: {
claimName: backupPvc.metadata.name,
},
}],
},
},
},
});
// Define the CronJob for backups
const backupCronJob = new k8s.batch.v1beta1.CronJob("pg-backup-cronjob", {
metadata: {
namespace: namespace.metadata.name,
},
spec: {
schedule: "0 2 * * *", // Daily at 2am
jobTemplate: {
spec: {
template: {
spec: {
containers: [{
name: "pg-backup",
image: "postgres:13",
env: [
{ name: "PGHOST", value: "postgres" },
{ name: "PGUSER", value: "myuser" },
{ name: "PGPASSWORD", value: "mypassword" },
{ name: "PGDATABASE", value: "mydatabase" },
],
command: [
"sh",
"-c",
"pg_dumpall -c > /backup/all-databases.sql",
],
volumeMounts: [{
name: "backup-storage",
mountPath: "/backup",
}],
}],
restartPolicy: "OnFailure",
volumes: [{
name: "backup-storage",
persistentVolumeClaim: {
claimName: backupPvc.metadata.name,
},
}],
},
},
},
},
},
});
// Define the Job for restoring from backup
const restoreJob = new k8s.batch.v1.Job("pg-restore-job", {
metadata: {
namespace: namespace.metadata.name,
},
spec: {
template: {
spec: {
containers: [{
name: "pg-restore",
image: "postgres:13",
env: [
{ name: "PGHOST", value: "postgres" },
{ name: "PGUSER", value: "myuser" },
{ name: "PGPASSWORD", value: "mypassword" },
{ name: "PGDATABASE", value: "mydatabase" },
],
command: [
"sh",
"-c",
"psql -f /backup/all-databases.sql",
],
volumeMounts: [{
name: "backup-storage",
mountPath: "/backup",
}],
}],
restartPolicy: "OnFailure",
volumes: [{
name: "backup-storage",
persistentVolumeClaim: {
claimName: backupPvc.metadata.name,
},
}],
},
},
},
});
Summary
In this guide, we deployed a PostgreSQL instance in a Kubernetes cluster and set up backup and restore workflows using Pulumi. We configured a PersistentVolumeClaim to store backup data, a CronJob to schedule regular backups, and a Job to restore data from backups. This setup ensures that your PostgreSQL data is regularly backed up and can be restored when needed.
Deploy this code
Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.
Sign upNew to Pulumi?
Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.
Sign upThank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.