Automate PostgreSQL Database Backups in Kubernetes with CronJobs and Azure File Share
Tired of manually backing up your PostgreSQL database? Automate the process using Kubernetes CronJobs, ConfigMaps, Persistent Volumes, and a lightweight PostgreSQL client Docker image.
In this step-by-step guide, you’ll learn how to:
✅ Create a Docker image with postgresql-client to perform backups.
✅ Use Kubernetes ConfigMaps to manage your backup script.
✅ Set up Persistent Volumes (PV & PVC) for storage.
✅ Automate backups using CronJobs with retention policies.
🛠 Prerequisites
Before getting started, ensure you have:
✔ A Kubernetes cluster on Azure Kubernetes Service (AKS) or another Kubernetes environment.
✔ kubectl installed and configured.
✔ A running PostgreSQL database in Kubernetes.
✔ Azure CLI installed for managing Azure resources.
✔ Docker installed to build and push images.
✔ A DockerHub or private container registry to store the backup image.
✔ Azure File Share created for storing backups persistently.
💡 Azure File Share will be used as persistent storage for backups.
Let’s get started! 🚀
💡 Why Automate PostgreSQL Backups?
Manual backups are risky — you might forget, or worse, data loss could occur before you act. With this Kubernetes-native solution, backups run automatically on a schedule, ensuring:
✔ Reliability — No missed backups!
✔ Security — Stored in Persistent Volumes (PVC).
✔ Efficiency — Old backups are deleted after 7 days.
🔧 Step 1: Build & Push the PostgreSQL Backup Docker Image
We’ll create a lightweight Docker image that only installs postgresql-client. This avoids unnecessary overhead from a full PostgreSQL installation.
📌 Dockerfile
# Use the official Ubuntu base image FROM ubuntu:latest # Install PostgreSQL client RUN apt-get update && \ apt-get install -y postgresql-client && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Set default command CMD ["psql", "--version"]
🛠 Build & Push the Image
docker build -t your-dockerhub-username/postgres-backup:latest . docker push your-dockerhub-username/postgres-backup:latest
🔹 Replace your-dockerhub-username with your actual DockerHub username.
Step 2: Create Persistent Storage for Backups (PV & PVC)
We’ll store backups in an Azure File Share-backed Persistent Volume (PV & PVC).
📌 PersistentVolume (PV)
apiVersion: v1 kind: PersistentVolume metadata: name: postgresql-backup-pv spec: capacity: storage: 10Gi accessModes: - ReadWriteMany azureFile: secretName: "" # Add your secret here secretNamespace: "" shareName: "" # Add your Azure File Share name here readOnly: false
📌 PersistentVolumeClaim (PVC)
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgresql-backup-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi volumeName: postgresql-backup-pv
🔹 Modify shareName and secretName based on your Azure setup.
Apply these:
kubectl apply -f pv.yaml kubectl apply -f pvc.yaml
📜 Step 3: Create ConfigMap for Backup Script
We need to mount the backup.sh script inside the CronJob container. Instead of hardcoding it, let’s use a ConfigMap.
📌 backup.sh (Backup Script)
#!/bin/bash NAMESPACE=${NAMESPACE:-"default"} POSTGRES_SVC=${POSTGRES_SVC} POSTGRES_USER=${POSTGRES_USER} POSTGRES_DB=${POSTGRES_DB} BACKUP_DIR="/backup" DATE=$(date +"%Y-%m-%d") BACKUP_FILE="${BACKUP_DIR}/${POSTGRES_DB}_${DATE}.sql" TAR_FILE="${BACKUP_DIR}/${POSTGRES_DB}_${DATE}.tar.gz" POSTGRES_PASS=${POSTGRES_PASS} # Perform the backup PGPASSWORD="$POSTGRES_PASS" pg_dump -h "$POSTGRES_SVC" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -F c -f "$BACKUP_FILE" # Compress the backup if [ $? -eq 0 ]; then tar -czf "$TAR_FILE" -C "$BACKUP_DIR" "$(basename "$BACKUP_FILE")" rm -f "$BACKUP_FILE" echo "Backup completed: $TAR_FILE" else echo "Backup failed!" exit 1 fi # Delete backups older than 7 days find "$BACKUP_DIR" -type f -name "${POSTGRES_DB}_*.tar.gz" -mtime +7 -exec rm -f {} \;
📌 Create ConfigMap
kubectl create configmap backup-script --from-file=backup.sh
🔹 This mounts backup.sh in the CronJob without modifying the container.
⏳ Step 4: Automate Backups with a Kubernetes CronJob
The CronJob runs the backup script every night at 12:30 AM(UTC).
📌 CronJob YAML
apiVersion: batch/v1 kind: CronJob metadata: name: postgresql-backup spec: schedule: "30 0 * * *" # Runs daily at 12:30 AM UTC successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 1 jobTemplate: spec: template: spec: containers: - name: postgresql-backup image: your-dockerhub-username/postgres-backup:latest #update the values imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c"] args: - | cp /scripts/backup.sh /tmp/backup.sh chmod +x /tmp/backup.sh until pg_isready -h "$POSTGRES_SVC" -U "$POSTGRES_USER"; do echo "Waiting for PostgreSQL to be ready..." sleep 5 done echo "Running backup script..." /tmp/backup.sh env: - name: POSTGRES_SVC value: "your-postgres-service" #update the values - name: POSTGRES_USER valueFrom: secretKeyRef: name: your-secret #update the values key: POSTGRES_USER - name: POSTGRES_PASS valueFrom: secretKeyRef: name: your-secret #update the values key: POSTGRES_PASSWORD - name: POSTGRES_DB value: "your-database" #update the values volumeMounts: - name: backup mountPath: /backup - name: script-volume mountPath: /scripts restartPolicy: OnFailure volumes: - name: backup persistentVolumeClaim: claimName: postgresql-backup-pvc - name: script-volume configMap: name: backup-script
🔹 Replace your-dockerhub-username and your-postgres-service with actual values.
🛠 Apply CronJob
kubectl apply -f cronjob.yaml
🚀 Wrapping Up
Congratulations! 🎉 You have successfully automated PostgreSQL backups on Kubernetes using:
✔ Dockerized PostgreSQL client for backup execution.
✔ ConfigMaps to manage scripts.
✔ Persistent Storage (PV & PVC) to retain backups.
✔ CronJobs to schedule automated backups.
💬 What’s Next?
Want to take your PostgreSQL backup automation to the next level?
Hire me on Fiverr for customized solutions tailored to your needs!
Have any questions or improvements? Drop a comment below!
🔥 Have you automated PostgreSQL backups yet? Let me know in the comments! 🚀
Top comments (0)