定时任务定时备份docker中mysql并将数据自动保存到另外一台服务器

本文介绍了一种在Docker环境下实现MySQL数据定时备份的方法,包括编写shell脚本、配置crontab定时任务、通过scp进行远程备份及设置ssh免密登录。

定时任务定时备份docker中mysql的数据

定时备份脚本 backupdb.sh:

#!/bin/sh
db_user="数据库用户名"
db_passwd="数据库密码"
db_name="需要备份的数据库名"
CONTAINERNAME="容器名"
REMOTE_USER="备份主机用户名"
REMOTE_IP="备份主机ip"
REMOTE_DIR="备份主机的备份目录
name="$(date +"%Y%m%d%H%M%S")"
docker exec -i $CONTAINERNAME /usr/bin/mysqldump -u$db_user -p$db_passwd $db_name >>/usr/data/backup/$name.sql
# 通过scp的方式将备份的数据转移到另外一台服务器
scp /usr/data/backup/$name.sql $REMOTE_USER@$REMOTE_IP:$REMOTE_DIR
# 保留最近一个月的数据
find /usr/data/backup -type f -mtime +20 -name "*.sql" -exec rm -rf {} \;

注意需要在docker安装mysql的时候,需要在宿主机新建文件夹 /usr/data/backup

在window中编辑过的脚本需要去除空格和换行:

# 去除脚本中的空格和换行
sed -i 's/\r$//' /usr/data/backup/backupdb.sh


# 脚本中docker主机执行中执行容器命令时候 docker exec -it  需要将 t 去掉,否则在执行定时任务脚本的时候会报错 the input device is not a TTY

通过scp的方式将数据保存到另外一台服务器需要设置ssh免密登录:
请参考:
SSH免密登录,实现A服务器免密登录B服务器

启动定时任务:

# 启动定时任务
crontab -e
# 将定时任务写入其中 分 时 日 月 年
* * * * * /bin/bash /usr/data/backup/backupdb.sh

# 查看定时任务列表
crontab -l
<think>我们正在处理用户关于在Docker容器中实现MySQL8自动异地备份的需求。根据引用内容,我们可以总结出以下几个关键点:1.使用`mysqldump`命令在容器内执行备份(引用[1][3])。2.异地备份可以通过从A服务器的容器内备份B服务器数据库来实现(引用[3])。3.自动备份可以通过定时任务(如cron)实现(引用[4])。4.备份文件可以压缩保存(引用[3][4])。最佳实践方案应包含以下步骤:1.在容器内或宿主机设置定时任务(推荐在容器内使用cron,但需要注意容器内需安装cron运行)。2.编写备份脚本,使用`mysqldump`命令备份数据库,压缩保存到指定目录。3.异地备份可以通过在脚本中指定远程数据库的IP、端口、用户名和密码来实现。4.考虑备份文件的清理策略(如保留最近7天的备份)。然而,在Docker容器中运行cron服务需要注意:-由于容器通常只运行一个主进程,因此需要配置容器同时运行cron和MySQL(或者单独运行一个备份容器)。-更常见的做法是使用宿主机的cron来定期执行容器内的备份命令(通过`dockerexec`)。考虑到用户要求的是容器内的自动异地备份,我们可以提供两种方案:方案一:在MySQL容器内安装cron配置定时任务。方案二:使用宿主机的cron调度,通过`dockerexec`执行容器内的备份命令。由于用户可能希望备份过程与容器紧密集成(且避免宿主机依赖),我们采用方案一,但需要构建自定义的Docker镜像。详细步骤:1.创建Dockerfile,基于MySQL8官方镜像,安装cron和必要的工具(如gzip)。2.编写备份脚本复制到镜像中。3.设置cron任务,定期执行备份脚本。4.构建运行容器。注意:异地备份意味着备份目标在另一个服务器上,所以我们的备份脚本将使用mysqldump连接远程数据备份到本地(容器内),然后可以将备份文件传输到异地存储(如另一台服务器或云存储)。但用户问题中只要求了异地备份(即备份到另一台服务器),我们可以在备份脚本中直接将备份文件保存到挂载的宿主机目录,然后通过其他方式(如rsync)将宿主机上的备份文件同步到异地。或者,在脚本中使用scp或s3命令将备份文件上传到异地服务器。由于用户没有明确异地存储的具体方式,我们假设用户希望将备份文件直接保存在另一个服务器上(通过挂载NFS或者使用网络传输)。这里我们采用在脚本中通过scp将备份文件传输到异地服务器的方式。步骤分解:1.创建备份脚本(backup.sh):-使用mysqldump备份指定的远程数据库(或本地数据库,但用户要求异地备份,所以可能是备份另一个服务器上的数据库,如引用[3]所示)。-压缩备份文件。-将备份文件传输到异地服务器(使用scp,需要预先配置SSH免密登录)。-同时,可以在本地保留一份备份(可选,设置清理策略)。2.创建Dockerfile:-基于mysql:8-安装cron、openssh-client(用于scp)、gzip-复制备份脚本到镜像中-设置cron任务(使用crontab文件)3.创建crontab文件,设置定时任务(例如每天凌晨2点执行备份脚本)。4.构建镜像运行容器。但是,注意:如果用户是要备份容器本身所运行的MySQL数据库,那么备份脚本中应该备份本地数据库(即容器内的MySQL),然后再传输到异地。而引用[3]是备份一台服务器数据库。因此我们需要明确:用户需求:在Docker容器中实现MySQL8的自动异地备份。可以理解为两种情况:A.容器内运行MySQL,需要将容器内的数据备份到异地(另一台服务器)。B.容器作为备份工具,备份异地的MySQL数据库(即容器内没有运行MySQL,而是作为一个备份客户端)。根据引用[3]的例子,用户可能两种情况都需要。但用户的问题中,容器是运行MySQL8的,所以应该是情况A。因此,我们调整备份脚本:-备份容器内的MySQL(即本地数据库,所以mysqldump不需要指定-h,而是使用localhost,但注意在容器内,localhost就是当前容器内的MySQL服务)。然而,引用[1]和[4]都是备份容器内的本地数据库。所以,我们按照情况A来设计:备份容器内的MySQL数据库,然后将备份文件传输到异地服务器备份脚本(backup.sh)内容示例:```bash#!/bin/bash#设置数据库连接参数(备份本地数据库)DB_USER="root"DB_PASSWORD="your_password"#注意:安全地处理密码,建议使用配置文件或环境变量DB_HOST="localhost"#因为是容器内的本地数据库#设置备份目录(容器内路径)BACKUP_DIR="/backup"#设置备份文件名(包含日期)BACKUP_FILE="$BACKUP_DIR/backup-$(date+%Y%m%d%H%M%S).sql.gz"#异地服务器配置REMOTE_USER="remote_user"REMOTE_HOST="remote_host"REMOTE_DIR="/remote/backup/dir"#使用mysqldump备份数据库,压缩mysqldump-h$DB_HOST-u$DB_USER-p$DB_PASSWORD--all-databases|gzip>$BACKUP_FILE#检查备份是否成功if[$?-eq0];thenecho"Backupsuccessful:$BACKUP_FILE"elseecho"Backupfailed"exit1fi#将备份文件传输到异地服务器scp$BACKUP_FILE$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR#清理本地备份(可选,因为容器可能挂载了卷,所以也可以保留在挂载卷中)#或者可以保留最近几天的备份,这里我们保留1天内的备份,删除旧的find$BACKUP_DIR-typef-name"*.sql.gz"-mtime+0-execrm{}\;```注意:密码在脚本中明文显示不安全。我们可以使用MySQL的配置文件(如.my.cnf)来避免在命令行中暴露密码。或者使用环境变量,然后在脚本中读取环境变量。在Docker容器中,我们可以通过环境变量传入密码。在Dockerfile中,我们可以设置环境变量,或者在运行容器时传入。改进脚本,使用环境变量:```bash#!/bin/bash#从环境变量获取数据库密码DB_USER=$MYSQL_USERDB_PASSWORD=$MYSQL_PASSWORDDB_HOST="localhost"...其余部分相同...```然后在运行容器时设置环境变量:`dockerrun-eMYSQL_USER=root-eMYSQL_PASSWORD=your_password...`另外,scp需要配置免密登录。我们可以在容器内生成SSH密钥对,将公钥添加到异地服务器的authorized_keys中。但是,在构建镜像时,我们不希望包含私钥,因此可以在运行容器时挂载包含私钥的卷,或者在启动容器时配置。为了简化,我们假设用户已经配置了SSH免密登录(将容器的公钥添加到异地服务器),将私钥文件挂载到容器内。步骤:1.在宿主机上生成SSH密钥对(如果没有),然后将公钥复制到异地服务器。2.将私钥文件挂载到容器内(例如:`-v/path/to/private_key:/root/.ssh/id_rsa`)。在Dockerfile中,我们需要确保备份脚本有执行权限,且配置cron。Dockerfile示例:```DockerfileFROMmysql:8#安装cron、openssh-client、gzipRUNapt-getupdate&&apt-getinstall-ycronopenssh-clientgzip&&rm-rf/var/lib/apt/lists/*#创建备份目录RUNmkdir/backup#复制备份脚本COPYbackup.sh/backup.shRUNchmod+x/backup.sh#复制crontab文件COPYcrontab/etc/cron.d/mysql-backup-cronRUNchmod0644/etc/cron.d/mysql-backup-cron#应用cron任务RUNcrontab/etc/cron.d/mysql-backup-cron#启动cron服务(注意:官方镜像的入口点会启动mysql,我们需要同时启动cron)#我们需要自定义启动脚本,同时启动cron和mysql#复制启动脚本COPYentrypoint.sh/entrypoint.shRUNchmod+x/entrypoint.shENTRYPOINT["/entrypoint.sh"]```crontab文件内容(例如每天凌晨2点执行):```bash#注意:需要指定shell,且重定向输出到日志文件(可选)SHELL=/bin/bash#定时任务,每天2点执行备份02***root/backup.sh>>/var/log/backup.log2>&1```entrypoint.sh启动脚本(用于同时启动cron和mysql):```bash#!/bin/bash#启动cron服务servicecronstart#运行原始MySQL入口点命令exec/usr/local/bin/docker-entrypoint.sh"$@"```注意:MySQL官方镜像使用`docker-entrypoint.sh`来启动MySQL,我们需要在自定义入口点脚本中启动cron,然后调用原始入口点。构建镜像:```bashdockerbuild-tmysql-8-with-backup.```运行容器(需要挂载SSH私钥,设置环境变量):```bashdockerrun-d--namemysql-container\-eMYSQL_ROOT_PASSWORD=your_mysql_root_password\-eMYSQL_USER=root\#备份脚本使用root,也可以使用其他用户(需有备份权限)-eMYSQL_PASSWORD=your_mysql_root_password\-v/path/to/ssh/private_key:/root/.ssh/id_rsa\#挂载私钥-v/path/to/host/backup:/backup\#可选:将容器内备份目录挂载到宿主机,这样即使容器删除备份还在mysql-8-with-backup```注意:挂载宿主机目录到容器的/backup,这样备份文件在容器外也能访问(同时传输到异地服务器是另一层备份)。安全建议:-使用强密码。-使用非root用户进行备份(如果有权限问题,可以使用root,但注意安全)。-配置异地服务器的SSH访问限制。另外,如果用户不想构建自定义镜像,也可以使用宿主机的cron来执行备份命令,例如:在宿主机上设置cron任务:```bash02***dockerexecmysql_container/backup.sh```此时,备份脚本需要放在容器内(可以通过挂载卷的方式放入,或者在构建镜像时已经放入)。但这种方法需要宿主机上有cron,且容器在运行时已经将脚本放入。考虑到用户要求的是容器内的自动备份,我们采用构建自定义镜像的方式。最后,我们还需要考虑日志记录(备份成功或失败)和错误处理。综上所述,我们为用户提供一个完整的方案,包括Dockerfile、备份脚本、crontab和入口点脚本的示例。注意:由于用户要求自动异地备份,我们的备份脚本中包含了scp传输到异地服务器,因此需要确保容器内可以访问异地服务器(网络连通)且配置了SSH免密登录。用户可以根据实际情况修改备份脚本中的参数(如异地服务器信息)。相关问题:1.如何配置SSH免密登录?2.如何设置MySQL备份用户和权限?3.如何验证备份文件的完整性和可用性?4.除了scp,还有哪些方式可以将备份文件传输到异地?5.如何实现增量备份?</think>### Docker 容器中 MySQL 8 自动异地备份最佳实践 #### 核心方案概述 在 Docker 容器中实现 MySQL 8 自动异地备份需结合三个关键技术: 1. **容器内备份**:使用 `mysqldump` 在容器内生成数据库快照 2. **定时任务**:通过 `cron` 实现自动备份周期 3. **异地传输**:将备份文件传输到远程服务器 #### 完整实施步骤 ##### 1. 创建备份脚本 (`/mysql/backup.sh`) ```bash #!/bin/bash # 容器内备份路径 BACKUP_DIR="/backup" mkdir -p $BACKUP_DIR # 生成带时间戳的备份文件名 BACKUP_FILE="$BACKUP_DIR/backup-$(date +%Y%m%d%H%M%S).sql.gz" # 执行备份 (本地MySQL) mysqldump -h localhost -u $DB_USER -p$DB_PASSWORD --all-databases | gzip > $BACKUP_FILE # 传输到异地服务器 (示例IP: 192.168.1.100) scp -i /ssh/id_rsa $BACKUP_FILE remote_user@192.168.1.100:/remote/backup/ # 清理7天前的旧备份 find $BACKUP_DIR -type f -name "*.sql.gz" -mtime +7 -exec rm {} \; ``` ##### 2. 配置 Dockerfile ```Dockerfile FROM mysql:8 # 安装必要工具 RUN apt-get update && apt-get install -y cron openssh-client gzip # 设置备份环境 RUN mkdir -p /backup /ssh COPY backup.sh /backup.sh RUN chmod +x /backup.sh # 配置cron任务 RUN echo "0 2 * * * /backup.sh > /var/log/backup.log 2>&1" > /etc/cron.d/mysql-backup RUN chmod 0644 /etc/cron.d/mysql-backup # 启动时运行cron CMD ["sh", "-c", "cron && docker-entrypoint.sh mysqld"] ``` ##### 3. 构建运行容器 ```bash # 构建镜像 docker build -t mysql-8-with-backup . # 运行容器 (挂载SSH密钥和备份目录) docker run -d --name mysql8 \ -e MYSQL_ROOT_PASSWORD=your_password \ -e DB_USER=root -e DB_PASSWORD=your_password \ -v /host/backups:/backup \ -v /host/ssh:/ssh \ mysql-8-with-backup ``` #### 关键配置说明 1. **SSH密钥配置**: - 将宿主机的SSH私钥挂载到容器`/ssh`目录 - 在异地服务器添加公钥到`authorized_keys` - 测试连接:`docker exec mysql8 ssh -i /ssh/id_rsa remote_user@192.168.1.100` 2. **备份策略优化**: - 增量备份:启用MySQL二进制日志 ```sql SET GLOBAL log_bin = ON; ``` - 加密备份:使用`openssl`加密备份文件 ```bash mysqldump ... | openssl enc -aes-256-cbc -out $BACKUP_FILE.enc ``` 3. **监控与告警**: ```bash # 在backup.sh末尾添加 if [ $? -eq 0 ]; then echo "Backup success $(date)" >> /var/log/backup.log else echo "ALERT: Backup failed!" | mail -s "MySQL Backup Error" admin@example.com fi ``` #### 异地传输替代方案 | 方式 | 命令示例 | 适用场景 | |------------|-----------------------------------|----------------------| | **SCP** | `scp backup.sql user@remote:/dir` | 简单服务器间传输 | | **Rsync** | `rsync -avz -e ssh backup.sql user@remote:/dir` | 大文件增量同步 | | **S3存储** | `aws s3 cp backup.sql s3://bucket` | 云环境备份 | | **SFTP** | `sftp -i key user@remote <<< 'put backup.sql'` | 防火墙限制环境 | #### 验证与测试 1. 手动执行测试: ```bash docker exec mysql8 /backup.sh docker exec mysql8 ls -lh /backup ``` 2. 检查异地服务器: ```bash ssh remote_user@192.168.1.100 ls -lh /remote/backup ``` 3. 恢复测试: ```bash gunzip < backup-20230801.sql.gz | mysql -u root -p ``` #### 注意事项 1. **安全加固**: - 使用专用备份账户:`CREATE USER 'backup'@'localhost' IDENTIFIED BY 'strong_password';` - 最小化权限:`GRANT SELECT, SHOW VIEW, LOCK TABLES ON *.* TO 'backup'@'localhost';` - 加密敏感数据:`echo "DB_PASSWORD=$(openssl enc -base64 <<< 'raw_pass')" >> .env` 2. **性能影响**: - 避开高峰时段执行备份(示例设置为凌晨2点) - 使用`--single-transaction`参数避免锁表 - 大型数据库建议使用物理备份工具如`Percona XtraBackup` 3. **多地域备份**: ```bash # 在backup.sh中添加多个目标 scp $BACKUP_FILE user@backup-server1:/dir scp $BACKUP_FILE user@backup-server2:/dir ``` [^1]: 容器内备份基础命令参考 [^2]: 容器文件操作注意事项 [^3]: 异地备份实现方法 [^4]: 定时备份脚本配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值