130 lines
3.8 KiB
Markdown
130 lines
3.8 KiB
Markdown
+++
|
|
title = "Backup MySQL Databases in Kubernetes"
|
|
date = 2021-03-03
|
|
updated = 2021-03-03
|
|
description = "In this post, we will show you how to create a MySQL server backup using Kubernetes CronJobs."
|
|
|
|
[taxonomies]
|
|
tags = ["docker", "kubernetes", "cronjob", "bash", "backup"]
|
|
|
|
[extra]
|
|
toc = false
|
|
quick_navigation_buttons = true
|
|
+++
|
|
In this post, we will show you how to create a MySQL server backup using Kubernetes CronJobs.
|
|
|
|
In our case, we do not have a managed MySQL server. But we want to backup it to our NAS, so that we have a backup in case of emergency.
|
|
For this we first build a container that can execute our tasks, because we will certainly need several tasks to backup our cluster.
|
|
|
|
## CronJob Agent Container
|
|
|
|
First, we'll show you our Dockerfile so you know what we need.
|
|
|
|
```Dockerfile
|
|
FROM alpine:3.10
|
|
|
|
# Update
|
|
RUN apk --update add --no-cache bash nodejs-current yarn curl busybox-extras vim rsync git mysql-client openssh-client
|
|
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl && chmod +x ./kubectl && mv ./kubectl /usr/local/bin/kubectl
|
|
|
|
# Scripts
|
|
RUN mkdir /srv/jobs
|
|
COPY jobs/* /srv/jobs/
|
|
|
|
# Backup Folder
|
|
RUN mkdir /var/backup
|
|
RUN mkdir /var/backup/mysql
|
|
```
|
|
|
|
## Backup Script
|
|
|
|
And now our backup script which the container executes.
|
|
|
|
Our script is quite simple, we get all tables with the mysql client, export them as sql file, pack them in a zip file and send them in a 8 hours interval to our NAS.
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
############# SET VARIABLES #############
|
|
|
|
# Env Variables
|
|
BACKUPSERVER="8.8.8.8" # Backup Server Ip
|
|
BACKUPDIR=/var/backup/mysql
|
|
BACKUPREMOTEDIR="/mnt/backup/kubernetes/"
|
|
HOST="mariadb.default"
|
|
NOW="$(date +"%Y-%m-%d")"
|
|
STARTTIME=$(date +"%s")
|
|
USER=mysqlUser
|
|
PASS=mysqlPassword
|
|
|
|
|
|
############# BUILD ENVIROMENT #############
|
|
# Check if temp Backup Directory is empty
|
|
mkdir $BACKUPDIR
|
|
|
|
if [ "$(ls -A $BACKUPDIR)" ]; then
|
|
echo "Take action $BACKUPDIR is not Empty"
|
|
rm -f $BACKUPDIR/*.gz
|
|
rm -f $BACKUPDIR/*.mysql
|
|
else
|
|
echo "$BACKUPDIR is Empty"
|
|
fi
|
|
|
|
############# BACKUP SQL DATABASES #############
|
|
for DB in $(mysql -u$USER -p$PASS -h $HOST -e 'show databases' -s --skip-column-names); do
|
|
mysqldump -u$USER -p$PASS -h $HOST --lock-tables=false $DB > "$BACKUPDIR/$DB.sql";
|
|
done
|
|
|
|
############# ZIP BACKUP #############
|
|
cd $BACKUPDIR
|
|
tar -zcvf backup-${NOW}.tar.gz *.sql
|
|
|
|
############# MOVE BACKUP TO REMOTE #############
|
|
rsync -avz $BACKUPDIR/backup-${NOW}.tar.gz root@$BACKUPSERVER:$BACKUPREMOTEDIR
|
|
|
|
# done
|
|
```
|
|
|
|
## Kubernetes CronJob Deployment
|
|
|
|
Finally we show you the kubernetes deployment for our agent.
|
|
|
|
In the deployment, our agent is defined as a CronJob that runs every 8 hours.
|
|
In addition, we have added an SSH key as a Conifg map so that this can write to the NAS and a certain security is given.
|
|
|
|
```yaml
|
|
apiVersion: batch/v1beta1
|
|
kind: CronJob
|
|
metadata:
|
|
name: backup-mariadb
|
|
namespace: default
|
|
spec:
|
|
schedule: "0 8 * * *"
|
|
successfulJobsHistoryLimit: 1
|
|
failedJobsHistoryLimit: 1
|
|
jobTemplate:
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: cronjob-agent
|
|
image: xxx/cronjob-agent
|
|
command: ["bash", "/srv/jobs/backup-mariadb.sh"]
|
|
volumeMounts:
|
|
- mountPath: /root/.ssh/id_rsa.pub
|
|
name: cronjob-default-config
|
|
subPath: id_rsa.pub
|
|
- mountPath: /root/.ssh/id_rsa
|
|
name: cronjob-default-config
|
|
subPath: id_rsa
|
|
readOnly: true
|
|
- mountPath: /root/.ssh/config
|
|
name: cronjob-default-config
|
|
subPath: config
|
|
volumes:
|
|
- name: cronjob-default-config
|
|
configMap:
|
|
name: cronjob-default-config
|
|
defaultMode: 256
|
|
restartPolicy: Never
|
|
``` |