Databases 5 min read

Automate MySQL Backups with Kubernetes CronJob: A Step‑by‑Step Guide

This article explains how to centralize MySQL backup management on Kubernetes by creating a dedicated namespace, PVC, and CronJob, then shows commands to monitor jobs and restore databases from compressed backup files, providing a complete, repeatable solution for DBAs.

DevOps Operations Practice
DevOps Operations Practice
DevOps Operations Practice
Automate MySQL Backups with Kubernetes CronJob: A Step‑by‑Step Guide

Backup Procedure

Create a dedicated namespace for backup resources: kubectl create namespace mysql-backup Define a PersistentVolumeClaim (PVC) to store backup files. Adjust storageClassName to match the cluster configuration.

# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-backup-pvc
  namespace: mysql-backup
  labels:
    app: mysql-backup
spec:
  storageClassName: "nfs-client"
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Gi

Create the PVC: kubectl create -f pvc.yaml Deploy a CronJob that runs daily, dumps all MySQL databases, compresses the dump, and retains backups for seven days.

# cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: mysql-backup-01
  namespace: mysql-backup
spec:
  schedule: "0 2 * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 7
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      backoffLimit: 3
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: mysql-backup
            image: mysql:8.0.43
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - |
              BACKUP_DIR="/backup/mysql-backup"
              BACKUP_FILE="${BACKUP_DIR}/mysql-backup-01-$(date +%Y%m%d%H%M%S).sql.gz"
              RETENTION_DAYS=7
              mkdir -p ${BACKUP_DIR}
              mysqldump -h mysql.mysql-backup -u root -p123456 \
                --all-databases --single-transaction --quick --lock-tables=false \
                | gzip > ${BACKUP_FILE}
              if [ -f ${BACKUP_FILE} ]; then
                echo "Backup succeeded: ${BACKUP_FILE}"
                find ${BACKUP_DIR} -name "mysql-backup-01-*.sql.gz" -mtime +${RETENTION_DAYS} -delete
                echo "Deleted backups older than ${RETENTION_DAYS} days"
              else
                echo "Backup failed: file not created"
                exit 1
              fi
            volumeMounts:
            - name: backup-storage
              mountPath: /backup
          volumes:
          - name: backup-storage
            persistentVolumeClaim:
              claimName: mysql-backup-pvc

Create the CronJob: kubectl create -f cronjob.yaml Monitor the resources:

kubectl get cronjob -n mysql-backup
kubectl get jobs -n mysql-backup

Restore Procedure

Decompress a backup file: gzip -d mysql-backup-01-20260303092641.sql.gz Copy the resulting .sql file into the target MySQL pod and run the restore command. Replace the placeholders with the actual host, user, password, and database name.

mysql -h <host> -u <user> -p<password> --one-database <database> < mysql-backup-01-20260303092641.sql

This approach centralizes MySQL backup scheduling, retention, and recovery using native Kubernetes resources.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesmysqlbackupCronJobDatabase AdministrationPVC
DevOps Operations Practice
Written by

DevOps Operations Practice

We share professional insights on cloud-native, DevOps & operations, Kubernetes, observability & monitoring, and Linux systems.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.