一、使用CronJob定期备份MySQL

3.2.1 搭建MySQL

1、创建一个 MySQL 的 PVC

# 定义PVC
[root@k8s-master01 ~]# vim mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-data
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs-csi

# 创建PVC
[root@k8s-master01 ~]# kaf mysql-pvc.yaml

# 验证
[root@k8s-master01 ~]# kg pvc
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
mysql-data   Bound    pvc-1c159b41-7afd-467f-a8b9-ecfdf9089ef5   10Gi       RWX            nfs-csi        <unset>                 2s

2、创建一个 MySQL 的 Deployment

[root@k8s-master01 ~]# vim deployment-mysql.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mysql
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate  # 单实例策略,适合有状态应用
  template:
    metadata:
      labels:
        app: mysql   # 必须与selector.matchLabels一致
    spec:
      containers:
      - name: mysql
        image: registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:8.0.20
        ports:
        - containerPort: 3306  # 暴露MySQL默认端口
          protocol: TCP
        env:
        - name: MYSQL_ROOT_PASSWORD  # 建议生产环境改用Secret
          value: "123456"            # 示例密码,实际需加密
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql  # MySQL数据持久化目录
        livenessProbe:               # 存活探针
          tcpSocket:
            port: 3306
          initialDelaySeconds: 30    # 容器启动30秒后开始探测
          timeoutSeconds: 3          # 探测超时时间
          periodSeconds: 30          # 每30秒探测一次
          successThreshold: 1
          failureThreshold: 2        # 连续失败2次标记为不健康
        readinessProbe:              # 就绪探针(配置同存活探针)
          tcpSocket:
            port: 3306
          initialDelaySeconds: 30
          timeoutSeconds: 3
          periodSeconds: 30
          successThreshold: 1
          failureThreshold: 2
      volumes:                       # 卷定义(与containers同级)
      - name: data
        persistentVolumeClaim:
          claimName: mysql-data      # 关联的PVC名称
      dnsPolicy: ClusterFirst        # DNS解析策略(默认值)

3、创建MySQL,并查看启动状态

[root@k8s-master01 ~]# kaf deployment-mysql.yaml 

# 验证
[root@k8s-master01 ~]# kgp
NAME                    READY   STATUS    RESTARTS   AGE
mysql-676759b6c-g9jj7   1/1     Running   0          53s

4、MySQL 启动后,会在数据目录初始化基础数据,此时可以在后端存储中看到

[root@k8s-node02 ~]# ls /data/nfs/pvc-1c159b41-7afd-467f-a8b9-ecfdf9089ef5
 auto.cnf        client-cert.pem      ib_logfile0     performance_schema   undo_001
 binlog.000001   client-key.pem       ib_logfile1     private_key.pem      undo_002
 binlog.000002  '#ib_16384_0.dblwr'   ibtmp1          public_key.pem
 binlog.index   '#ib_16384_1.dblwr'  '#innodb_temp'   server-cert.pem
 ca-key.pem      ib_buffer_pool       mysql           server-key.pem
 ca.pem          ibdata1              mysql.ibd       sys

5、创建一个 MySQL 的 Service

[root@k8s-master01 ~]# k expose  deploy  mysql --port 3306

3.2.2 MySQL手工备份测试

1、创建测试数据,用于备份

[root@k8s-master01 ~]# kgp
NAME                    READY   STATUS    RESTARTS   AGE
mysql-676759b6c-g9jj7   1/1     Running   0          53s

# 进入数据库创建测试数据表
[root@k8s-master01 ~]# k exec -it mysql-676759b6c-g9jj7 -- bash
root@mysql-676759b6c-vzrgn:/# mysql -uroot -p123456
mysql> create database zq;
mysql> use zq;
mysql> CREATE TABLE test (
    id INT AUTO_INCREMENT PRIMARY KEY,
    f_name VARCHAR(10),
    l_name VARCHAR(20)
);
mysql> show tables;
+--------------+
| Tables_in_zq |
+--------------+
| test         |
+--------------+
1 row in set (0.00 sec)

2、手工备份进行测试

[root@k8s-master01 ~]# k exec -it mysql-676759b6c-g9jj7 -- bash
root@mysql-676759b6c-vzrgn:/# mysqldump -uroot -p'123456' -A > /tmp/all.sql;
root@mysql-676759b6c-vzrgn:/# ls /tmp/all.sql 
/tmp/all.sql

3.2.3 创建Cronjob备份Mysql

1、创建一个用于放置 CronJob 的命名空间

[root@k8s-master01 ~]# k create ns cronjob

2、创建一个备份MySQL 的 PVC

# 定义PVC
[root@k8s-master01 ~]# vim mysql-backup-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-backup-data
  namespace: cronjob
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs-csi

# 创建PVC
[root@k8s-master01 ~]# kaf mysql-backup-pvc.yaml 

# 验证
[root@k8s-master01 ~]# kg pvc -n cronjob
NAME                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
mysql-backup-data   Bound    pvc-9a631121-b284-4ea9-b476-9aa15f6532b0   10Gi       RWX            nfs-csi        <unset>                 8s

3、定义Cronjob的yaml文件

[root@k8s-master01 ~]# vim mysql-backup.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: mysql-backup
  namespace: cronjob
spec:
  schedule: "00 01 * * *"        # 每天凌晨1点执行(UTC时间)
  timeZone: Asia/Shanghai        # 需 Kubernetes 1.25+ 版本支持
  successfulJobsHistoryLimit: 5  # 保留成功Job记录数
  failedJobsHistoryLimit: 5      # 保留失败Job记录数
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:8.0.20
            command:
            - sh
            - -c
            - |
              mysqldump -hmysql.default -P3306 -uroot -p'123456' -A > /mnt/all-$(date +%Y%m%d-%H%M%S).sql
              ls -l /mnt
            volumeMounts:
            - name: backup-data
              mountPath: /mnt
          restartPolicy: Never   # 必须为 Never 或 OnFailure
          volumes:
          - name: backup-data
            persistentVolumeClaim:
              claimName: mysql-backup-data

2、创建Cronjob

[root@k8s-master01 ~]# kaf mysql-backup.yaml

3、查看创建情况

[root@k8s-master01 ~]# kg cj -n cronjob
NAME           SCHEDULE      TIMEZONE        SUSPEND   ACTIVE   LAST SCHEDULE   AGE
mysql-backup   00 01 * * *   Asia/Shanghai   False     0        <none>          93s

4、因为这里是凌晨1点才会触发定时任务,这里手工模拟触发定时任务

[root@k8s-master01 ~]# k create  job mysql-backup-test --from=cronjob.batch/mysql-backup -n cronjob

5、查看资源创建情况

# 查看job创建情况
[root@k8s-master01 ~]# kg job -n cronjob
NAME                STATUS     COMPLETIONS   DURATION   AGE
mysql-backup-test   Complete   1/1           7s         19

# 查看pod创建情况
[root@k8s-master01 ~]# kgp -n cronjob
NAME                      READY   STATUS      RESTARTS   AGE
mysql-backup-test-mfh9j   0/1     Completed   0          25s

# 查看备份记录
[root@k8s-master01 ~]# k logs -f mysql-backup-test-mfh9j -n cronjob
mysqldump: [Warning] Using a password on the command line interface can be insecure.
total 4032
-rw-r--r-- 1 root root 3720615 Mar 21 10:52 all-20250321-105223.sq

# 查看备份位置
[root@k8s-node02 ~]# ls /data/nfs/pvc-9a631121-b284-4ea9-b476-9aa15f6532b0
all-20250321-105223.sql

6、环境复原

kubectl delete -f deployment-mysql.yaml  -f mysql-backup.yaml -f mysql-backup-pvc.yaml -f mysql-pvc.yaml