MySQL
kubernetes
ibmcloudprivate

Kubernetes環境でCronJobでMySQLを定期的にバックアップ

Kubernetes環境にMySQLのコンテナをデプロイした場合に、CronJobを使ってMySQLのバックアップを定期的に取得する方法を試したメモ。

MySQLのコンテナをデプロイするまでは以下を参照。

ICPにMySQLに接続するLibertyアプリケーションをデプロイ

概要

image.png

MySQLのコンテナとは別に、バックアップ取得のためのMySQL運用コンテナを定期的に起動してmysqldumpコマンドを実行し、コンテナにマウントしたPV上にバックアップを取得する。運用コンテナでmysqldumpコマンドを使うため、そちらもMySQLの公式イメージを使用する。

PV/PVCの作成

hostPathで使うディレクトリを作成する。

root@myicp01:/export# pwd
/export
root@myicp01:/export# mkdir mysql-backup
root@myicp01:/export# ls -l
total 20
drwxrwxrwx  2 root root   4096 Jul 12 02:19 logstash
drwxr-xr-x 15 root root   4096 Jul 12 02:13 MC_jenkins02
drwxr-xr-x  3 root root   4096 Jul  4 07:15 MC_microclimate02
drwxr-xr-x  5  999 docker 4096 Jul 12 01:19 mysql
drwxr-xr-x  2 root root   4096 Jul 12 02:49 mysql-backup
root@myicp01:/export#

バックアップファイルを保管するPVを作成する。

mysql-backup-pv-volume.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
  name: mysql-backup-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/export/mysql-backup"
kubectl apply -f mysql-backup-pv-volume.yaml

PVCを作成する。

mysql-backup-pv-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-backup-pv-claim
  namespace: ns3
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
kubectl apply -f mysql-backup-pv-claim.yaml

確認する。

# kubectl get pvc -n ns3
NAME                    STATUS    VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql-backup-pv-claim   Bound     mysql-backup-pv-volume   10Gi       RWO            manual         1m
mysql-pv-claim          Bound     mysql-pv-volume          10Gi       RWO            manual         2d
#

単発のバックアップ

まずは単発でバックアップを行うJobを作成する。

mysql-backup-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: mysql-backup
  namespace: ns3
spec:
  template:
    spec:
      containers:
      - image: mysql:5.6
        name: mysql-backup
        volumeMounts:
        - name: mysql-backup-persistent-storage
          mountPath: /backup
        command: ["/bin/sh"]
        args: ["-c", "/usr/bin/mysqldump -u root -ppassword -h mysql mydb > /backup/mydb.dump"]
      restartPolicy: Never
      volumes:
      - name: mysql-backup-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-backup-pv-claim
  backoffLimit: 4
kubectl apply -f mysql-backup-job.yaml

Jobが成功してバックアップファイルができていることを確認。

# kubectl get jobs -n ns3
NAME           DESIRED   SUCCESSFUL   AGE
mysql-backup   1         1            4m
#
# ls -l /export/mysql-backup/
total 4
-rw-r--r-- 1 root root 2121 Jul 12 03:25 mydb.dump
#

接続情報を外部化

ユーザーとパスワードを直に書いてしまっているので、ConfigMap/Secretから取得するように変更する。Libertyからの接続用に作成済みの以下のConfigMap/Sercretを使う。

liberty-mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: liberty-mysql-secret
  namespace: ns3
type: Opaque
data:
  libertyPassword: bGliZXJ0eQ==
liberty-mysql-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: liberty-mysql-config
  namespace: ns3
data:
  MYSQL_SERVERNAME: "mysql"
  MYSQL_PORTNUMBER: "3306"
  MYSQL_USER: "liberty"

環境変数経由で取得するように変更。

mysql-backup-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: mysql-backup
  namespace: ns3
spec:
  template:
    spec:
      containers:
      - image: mysql:5.6
        name: mysql-backup
        env:
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: liberty-mysql-secret
              key: libertyPassword
        - name: MYSQL_USER
          valueFrom:
            configMapKeyRef:
              name: liberty-mysql-config
              key: MYSQL_USER
        - name: MYSQL_SERVERNAME
          valueFrom:
            configMapKeyRef:
              name: liberty-mysql-config
              key: MYSQL_SERVERNAME
        volumeMounts:
        - name: mysql-backup-persistent-storage
          mountPath: /backup
        command: ["/bin/sh"]
        args: ["-c", "/usr/bin/mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} -h${MYSQL_SERVERNAME} mydb > /backup/mydb.dump"]
      restartPolicy: Never
      volumes:
      - name: mysql-backup-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-backup-pv-claim
  backoffLimit: 4

CronJob

CronJobを使って定期的にバックアップを取得する。

mysql-backup-cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: mysql-backup
  namespace: ns3
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - image: mysql:5.6
            name: mysql-backup
            env:
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: liberty-mysql-secret
                  key: libertyPassword
            - name: MYSQL_USER
              valueFrom:
                configMapKeyRef:
                  name: liberty-mysql-config
                  key: MYSQL_USER
            - name: MYSQL_SERVERNAME
              valueFrom:
                configMapKeyRef:
                  name: liberty-mysql-config
                  key: MYSQL_SERVERNAME
            volumeMounts:
            - name: mysql-backup-persistent-storage
              mountPath: /backup
            command: ["/bin/sh"]
            args: ["-c", "/usr/bin/mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} -h${MYSQL_SERVERNAME} mydb > /backup/mydb.dump"]
          restartPolicy: Never
          volumes:
          - name: mysql-backup-persistent-storage
            persistentVolumeClaim:
              claimName: mysql-backup-pv-claim
kubectl apply -f mysql-backup-cronjob.yaml

1分毎にJobが作成され、バックアップが更新されていることを確認する。

# kubectl get cronjobs -n ns3
NAME           SCHEDULE      SUSPEND   ACTIVE    LAST SCHEDULE   AGE
mysql-backup   */1 * * * *   False     0         13s             4m
# kubectl get jobs -n ns3
NAME                      DESIRED   SUCCESSFUL   AGE
mysql-backup-1531367640   1         1            2m
mysql-backup-1531367700   1         1            1m
mysql-backup-1531367760   1         1            18s
# kubectl get po -n ns3
NAME                            READY     STATUS      RESTARTS   AGE
hellomysql-5564fcdfc6-hcrg6     1/1       Running     2          2d
mysql-774b87bc4c-672b5          1/1       Running     2          2d
mysql-backup-1531367640-gnnc9   0/1       Completed   0          2m
mysql-backup-1531367700-g4btp   0/1       Completed   0          1m
mysql-backup-1531367760-2k85b   0/1       Completed   0          34s
# ls -l /export/mysql-backup/
total 4
-rw-r--r-- 1 root root 2121 Jul 12 03:56 mydb.dump
#

メモ

Jobによって作成されたPodのメンテナンスや失敗時の動作や監視など要検討。

参考資料

Jobs - Run to Completion

Running automated tasks with cron jobs

Define a Command and Arguments for a Container

kubernetes1.4 で実装された ScheduledJob を試してみた!

CronJob(ScheduledJob)

mysqldumpまとめ