使用Kubernetes CronJob在GKE上备份MySQL

时间:2020-01-09 10:34:21  来源:igfitidea点击:

说明

在本教程中,我们将学习如何使用Kubernetes CronJobs和Google Cloud Storage存储桶在GKE中保护MySQL数据库。

CronJobs是执行任务的计划事件,与Unix cronjobs不同,CronJobs是通过容器执行的。

我们将基于Google Cloud SDK映像构建MySQL备份映像,并使用它执行标准的mysqldump。然后,已转储的数据库将使用gsutil上传到安全的Cloud Storage Bucket。

入门

本教程中使用的清单和脚本可从Github获得。下载它们以遵循或者用作模板。

Kubernetes模板

IAM服务帐户

由cronjob启动的容器将需要访问存储桶。在这种情况下,服务帐户是个好主意,因为该帐户用于自动化流程,并且仅用于一个目的-将转储文件复制到存储桶中。

创建服务帐户

备份容器将需要对将存储SQL转储的存储桶进行写访问。这可以通过创建服务帐户,然后将适当的权限分配给存储桶来实现。

创建一个Kubernetes秘密

不应使用存储在其中的服务帐户凭据来构建我们的备份Docker容器。相反,它将作为Kubernetes Secret存储,MySQL备份容器可以访问它。

储存桶

创建一个存储桶。

MySQL备份Docker映像

下一步是创建一个将执行MySQL备份的新Docker映像。 Google提供预装CloudSDK的图像

备份脚本

需要一个shell脚本来执行实际的备份。脚本将是我们创建的映像的入口点,其工作将是执行MySQL转储并将转储上载到云存储。

#!/bin/bash
# Based on script created by camilb's (github.com/camilb)  
# Source: https://github.com/camilb/kube-mysqldump-cron/blob/master/Docker/dump.sh

DB_USER=${DB_USER:-${MYSQL_ENV_DB_USER}}
DB_PASS=${DB_PASS:-${MYSQL_ENV_DB_PASS}}
DB_NAME=${DB_NAME:-${MYSQL_ENV_DB_NAME}}
DB_HOST=${DB_HOST:-${MYSQL_ENV_DB_HOST}}
ALL_DATABASES=${ALL_DATABASES}
IGNORE_DATABASE=${IGNORE_DATABASE}
GS_BUCKET=${BACKUP_STORAGE_BUCKET}

if [[ ${DB_USER} == "" ]]; then
    echo "Missing DB_USER env variable"
    exit 1
fi
if [[ ${DB_PASS} == "" ]]; then
    echo "Missing DB_PASS env variable"
    exit 1
fi
if [[ ${DB_HOST} == "" ]]; then
    echo "Missing DB_HOST env variable"
    exit 1
fi

if [[ ${GS_STORAGE_BUCKET} == "" ]]; then
    echo "Missing GS_BUCKET env variable"
    exit 1
fi

if [[ ${ALL_DATABASES} == "" ]]; then
    if [[ ${DB_NAME} == "" ]]; then
        echo "Missing DB_NAME env variable"
        exit 1
    fi
    mysqldump --user="${DB_USER}" --password="${DB_PASS}" --host="${DB_HOST}" "Hyman@localhost" "${DB_NAME}" > /mysqldump/"${DB_NAME}".sql
    gsutil cp /mysqldump/"${DB_NAME}".sql ${GS_BUCKET}
else
    databases=`mysql --user="${DB_USER}" --password="${DB_PASS}" --host="${DB_HOST}" -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`
for db in $databases; do
    if [[ "$db" != "information_schema" ]] && [[ "$db" != "performance_schema" ]] && [[ "$db" != "mysql" ]] && [[ "$db" != _* ]] && [[ "$db" != "$IGNORE_DATABASE" ]]; then
        echo "Dumping database: $db"
        mysqldump --user="${DB_USER}" --password="${DB_PASS}" --host="${DB_HOST}" --databases $db > /mysqldump/$db.sql
        gsutil cp /mysqldump/$db.sql ${GS_BUCKET}
    fi
done
fi

Docker文件

Dockerfiles将非常简单。它将接受一些环境变量,这些变量将用于连接到目标数据库服务器。

先前创建的备份脚本也将被复制到该脚本中,并将其设置为容器的入口点。

FROM google/cloud-sdk:alpine

ENV GOOGLE_PROJECT \
ENV GOOGLE_CLIENT_EMAIL \ 
ENV DB_USER \
    DB_PASS \   
    DB_NAME  \
    DB_HOST  \
    ALL_DATABASES  \
    IGNORE_DATABASES  \
    GS_BUCKET demo-backup-theitroad

COPY service-account.json /root/service_key.json
COPY backup.sh /root/backup.sh

RUN gcloud config set project $GOOGLE_PROJECT && \
    gcloud auth activate-service-account --key-file /root/service_key.json && \
    gsutil ls gs://$GS_STORAGE_BUCKET/

VOLUME ["/root/.config"]

构建和发布Docker映像

有关构建容器的说明。

docker build -t gcr.io/theitroad/mysql-backup:0.0.1 .
docker push gcr.io/theitroad/mysql-backup:0.0.1

创建一个Kuberbetes CronJob

终于到了创建CronJob的时候了。我们将把工作安排为每晚运行。

---
apiVersion: v1
kind: CronJob
metadata:
  name: mysql-backup
spec:
  schedule: "1/* * * *"
  jobTemplate:
    spec:
      containers:
        - name: mysql-backup
          image: gcr.io/theitroad/mysqlbackup:0.0.1
          env:
            - name: GOOGLE_PROJECT
              value: myblog
            - name: GOOGLE_EMAIL
              value: Hyman@localhost
            - name: DB_HOST
              value: mysql-service
            - name: DB_USER
              value: root
            - name: DB_PASS
              valueFrom:
                secretKeyRef:
                  name: mysql-secrets
                  key: root-password
            - name: DB_NAME
              value: wordpress
            - name: GS_BUCKET
              value: demo-backup-bucket