Docker container regularly backs up the database and sends it to the specified mailbox (design idea)

Docker container regularly backs up the database and sends it to the specified mailbox (design idea)

Project address and instructions: https://gitee.com/noovertime/mysqlmail

1. Background:

My original intention was to write a script to monitor the server's high utilization processes and send them to me via email. Then I suddenly realized that I could use this method to backup my database, so I started to work on it!

2. Design ideas:

By writing a shell script, calling the Linux mail tool, using mysqldump to save the database's sql file, adding it to an attachment through the mail tool, and finally sending it to my mailbox.

3. Write a startup script

First, let's write a startup script. To facilitate future personalized configuration, we extract all the variables in the script into an application.yml file. The file is as follows:

 RUNTIME: 084900 ##Startup time. Due to the container time zone issue, the current time minus 8 hours is required. HOST: 172.17.0.3 ##Database IP address USER: root ##Database user PASSWORD: 123456 ##Database password DATABASE: solo ##Database name TARGETMAIL: [email protected] ##Email address to send

Next, let's write a shell script. The logic is also very simple. When the current time is the same as the startup time, the sendmail function is called to send an email.

 #!/bin/bash
#author: chenteng

RUNTIME=$(cat ./application.yml | grep RUNTIME| awk '{print $2}')
HOST=$(cat ./application.yml | grep HOST| awk '{print $2}')
USER=$(cat ./application.yml | grep USER| awk '{print $2}')
PASSWORD=$(cat ./application.yml | grep PASSWORD| awk '{print $2}')
DATABASE=$(cat ./application.yml | grep DATABASE| awk '{print $2}')
TARGETMAIL=$(cat ./application.yml | grep TARGETMAIL| awk '{print $2}')

function sendmail(){
  mysqldump -h$HOST -u$USER -p$PASSWORD --complete-insert --skip-add-drop-table --hex-blob $DATABASE > $DATABASE.sql
  echo -e "mysqlbak_$CURRENT_TIME" |mail -s "mysqlbak_$CURRENT_TIME" -a $DATABASE.sql $TARGETMAIL
  sleep 1
}
while true
do 
  CURRENT_TIME=$(date +%H%M%S)
  if [ $CURRENT_TIME = $RUNTIME ];then
    echo "starting bak mysql database"
    sendmail
    continue
  else
    echo $CURRENT_TIME
    sleep 1
  fi
done

4. Build an Image

Because we will eventually put it on the k8s platform, we need to build an image. Before building the image, please put application.yml demo.sh Dockerfile in the same directory
The Dockerfile is as follows:
PS: Added mysql client and mail client

 FROM centos
RUN mkdir /app && yum install -y mysql.x86_64 sendmail mailx libreport-plugin-mailx 
WORKDIR /app
COPY demo.sh .
COPY application.yml .
CMD ["/bin/sh","demo.sh"]

Use the docker build command to build the image, remember to add the last dot

 docker build -t mysqlmail-bak:1.0.1 .

5. Adding a sidecar container

Sidecar container: A sidecar container is a container that runs in a pod with the main container, empowers the business container, and shares a network space, so you can use 127.0.0.1:3306 to connect to the database of the main container.

5.1 Create a configuration file

To facilitate debugging, I also mounted the shell script inside.
Create two configmaps, corresponding to the configuration file and shell script in the container respectively. If debugging is not required later, you can cancel the mounting of mysqlshell.

 apiVersion: v1
kind: ConfigMap
metadata:
  name: mysqlmail-conf
  namespace: solo
data:
  application.yml: |
    RUNTIME: 105800
    HOST: 127.0.0.1
    USER: root
    PASSWORD: 123456
    DATABASE: solo
    TARGETMAIL: [email protected]
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysqlmail-shell
  namespace: solo
data:
  demo.sh: |
    #!/bin/bash
    #author: chenteng
    RUNTIME=$(cat ./application.yml | grep RUNTIME| awk '{print $2}')
    HOST=$(cat ./application.yml | grep HOST| awk '{print $2}')
    USER=$(cat ./application.yml | grep USER| awk '{print $2}')
    PASSWORD=$(cat ./application.yml | grep PASSWORD| awk '{print $2}')
    DATABASE=$(cat ./application.yml | grep DATABASE| awk '{print $2}')
    TARGETMAIL=$(cat ./application.yml | grep TARGETMAIL| awk '{print $2}')
    function sendmail(){
      mysqldump -h$HOST -u$USER -p$PASSWORD --complete-insert --skip-add-drop-table --column-statistics=0 --hex-blob $DATABASE > $DATABASE.sql
      echo -e "mysqlbak_$CURRENT_TIME" |mail -s "mysqlbak_$CURRENT_TIME" -a $DATABASE.sql $TARGETMAIL
      sleep 1
    }
    while true
    do 
      CURRENT_TIME=$(date +%H%M%S)
      if [ $CURRENT_TIME = $RUNTIME ];then
        echo "starting bak mysql database"
        sendmail
        continue
      else
        echo $CURRENT_TIME
        sleep 1
      fi
    done

5.2 Create a stateful service deployment file

Our deploy file uses the yaml file of the mysql stateful service created in the previous article. If you are interested, you can read my previous migration article.

 apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: solo
spec:
  serviceName: mysql-service
  selector:
    matchLabels:
      app:mysql
  replicas: 1
  template:
    metadata:
      labels:
        app:mysql
    spec:
      containers:
      - name: mysqlmail-bak
        imagePullPolicy: IfNotPresent
        image: mysqlmail-bak:1.0.1
        volumeMounts:
        - name: mysqlmail-conf
          mountPath: /app/application.yml
          subPath: application.yml
        - name: mysqlmail-shell
          mountPath: /app/demo.sh
          subPath: demo.sh
      - name: mysql-pod
        imagePullPolicy: IfNotPresent
        image:mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
        ports:
        - containerPort: 3306
          name: msyql-listin
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
          subPath: mysql-data
        - name: mysql-conf
          mountPath: /etc/mysql/conf.d/my.cnf
          subPath: my.cnf
      volumes:
      - name: mysql-data
        hostPath:
          path: /data/mysql
      - name: mysql-conf
        configMap:
          name: mysql-conf
      - name: mysqlmail-conf
        configMap: 
          name: mysqlmail-conf
      - name: mysqlmail-shell
        configMap:
          name: mysqlmail-shell
---

apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  namespace: solo
  labels:
    app:mysql
spec:
  ports:
  - targetPort: 3306
    port: 3306
  clusterIP: None
  selector:
     app:mysql

6. Testing

The time we set above is RUNTIME: 105800, which is 18:58 in Shanghai time zone. Let's take a look at the effect and view the log.
Note: When a pod contains multiple containers, use the -c parameter to specify which container to view.

 [root@VM-24-15-centos solo]# kubectl logs -n solo mysql-0 -c mysqlmail-bak | grep mysql -C 5
105755
105756
105757
105758
105759
Starting back mysql database
mysqldump: [Warning] Using a password on the command line interface can be insecure.
105801
105802

From the log, you can see that the email has been sent successfully! We checked our mailbox and found that it had also been successful. Our experiment was now perfectly completed!

insert image description here

This is the end of this article about how to schedule database backup in Docker container and send it to a specified mailbox. For more information about scheduled database backup in Docker, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of psql database backup and recovery in docker
  • Database backup in docker environment (postgresql, mysql) example code

<<:  A brief discussion on browser compatibility issues in JavaScript

>>:  How to use vue3+TypeScript+vue-router

Recommend

Review of the best web design works in 2012 [Part 1]

At the beginning of the new year, I would like to...

Analysis of MySql index usage strategy

MySql Index Index advantages 1. You can ensure th...

Do you know how to use the flash wmode attribute in web pages?

When doing web development, you may encounter the...

How to implement MySQL master-slave replication based on Docker

Preface MySQL master-slave replication is the bas...

A brief discussion on size units in CSS

The compatibility of browsers is getting better a...

How to display texture at the position of swipe in CocosCreator

Table of contents 1. Project requirements 2. Docu...

Vue.js framework implements shopping cart function

This article shares the specific code of Vue.js f...

How to implement a password strength detector in react

Table of contents Preface use Component Writing D...

DIV background semi-transparent text non-translucent style

DIV background is semi-transparent, but the words ...

MySQL series: redo log, undo log and binlog detailed explanation

Implementation of transactions The redo log ensur...

Using CSS to implement loading animation of Android system

There are two common loading icons on the web, on...

Use elasticsearch to delete index data regularly

1. Sometimes we use ES Due to limited resources o...