rsync搭建全网备份
- 1. 总体概述
- 1.1 目标
- 1.2 简易指导图
- 1.3 涉及工具或命令
- 1.4 环境
- 2. 实施
- 2.1 配置备份服务器
- 2.2 备份文件准备
- 2.3 整合命令
- 2.4 扩展功能
1. 总体概述
1.1 目标
本次搭建目标:
- 每天定时把服务器数据备份到备份服务器
- 备份完成后进行校验
- 把过期数据删除(普通服务器数据保留7天,备份服务器数据保留1年)
- 完成后邮件通知
1.2 简易指导图
1.3 涉及工具或命令
rsysnc
:备份工具,守护进程模式cron
:定时任务md5sum
:MD5校验工具mailx
:邮件tar
、find
、date
等等
1.4 环境
服务器 | ip | 系统版本 | 说明 |
---|---|---|---|
backup-svr-01 | 192.168.202.128 | CentOS Linux release 7.9.2009 (Core) | 备份服务器 |
data-svr-01 | 192.168.202.129 | CentOS Linux release 7.9.2009 (Core) | 数据服务器 |
2. 实施
在每个步骤中,会把具体的需求细化分解
2.1 配置备份服务器
- 创建备份目录
[root@backup-svr-01 ~]# chown rsync.rsync /backup/
[root@backup-svr-01 ~]# ll /backup/ -d
drwxr-xr-x 2 rsync rsync 6 Aug 29 16:39 /backup/
- 创建rsync进程使用的用户
[root@backup-svr-01 ~]# useradd -s /sbin/nologin -M rsync
[root@backup-svr-01 ~]# id rsync
uid=1003(rsync) gid=1004(rsync) groups=1004(rsync)
客户端连到备份服务器用rsync用户访问权限访问数据,这个用户只提供访问权限,所以不需要登录shell
- 创建客户端访问备份服务器的账户
[root@backup-svr-01 ~]# echo "rsync_bak_01:rsync" > /etc/rsync.passwd
[root@backup-svr-01 ~]# cat /etc/rsync.passwd
rsync_bak_01:rsync
[root@backup-svr-01 ~]# chmod 400 /etc/rsync.passwd
[root@backup-svr-01 ~]# ll /etc/rsync.passwd
-r-------- 1 root root 19 Aug 29 16:51 /etc/rsync.passwd
- 编译rsync的配置文件
没有安装
rsync
可以通过yum install -y rsync
安装
[root@backup-svr-01 ~]# cat /etc/rsyncd.conf
# /etc/rsyncd: configuration file for rsync daemon mode
uid = rsync
gid = rsync
use chroot = no
max connections = 4
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
# exclude = lost+found/
# transfer logging = yes
timeout = 900
# ignore nonreadable = yes
# dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
fake super = yes
[backup]
path = /backup/ #备份到服务器的目录
ignore errors
read only = false
list = false
hosts allow = 192.168.202.0/24 #允许的IP范围
hosts deny = 0.0.0.0/32 #其他IP都禁止
auth users = rsync_bak_01
secrets file = /etc/rsync.passwd
配置完成后重启rsyncd
服务
[root@backup-svr-01 ~]# systemctl restart rsyncd
- 测试
rsync
首先在客户端配置密码文件
[root@data-svr-01 ~]# cat /etc/rsync.passwd
rsync
传输测试
[root@data-svr-01 ~]# rsync -avz /etc/hosts rsync_bak_01@192.168.202.128::backup --password-file=/etc/rsync.passwd
sending incremental file list
hosts
sent 187 bytes received 43 bytes 153.33 bytes/sec
total size is 254 speedup is 1.10
[root@backup-svr-01 ~]# ll /backup/
total 4
-rw-r--r-- 1 rsync rsync 254 May 9 2023 hosts
2.2 备份文件准备
这里我们在普通服务器(客户端),把一些常用文件,重要数据等内容进行备份,视具体情况而定
本次示例中以/etc
目录为例
- 创建备份数据存放目录
[root@data-svr-01 ~]# mkdir /data
这里我们把备份数据存放在/data/ip
目录中
mkdir -p /data/`ip a s ens33|sed -rn '3 s#^[^[:digit:]]+(.*)/.*#\1#gp'`
取IP可以有多种方式,例如:
[root@data-svr-01 ~]# hostname -I|awk '{print $1}'
192.168.202.129
[root@data-svr-01 ~]# ip a s ens33|awk 'BEGIN{FS="inet |/24"} NR==3{print $2}'
192.168.202.129
- 打包数据,并以时间进行区分
打包数据
[root@data-svr-01 ~]# tar zcf /data/`ip a s ens33|sed -rn '3 s#^[^[:digit:]]+(.*)/.*#\1#gp'`/etc.`date +%F`.tar.gz /etc/
tar: Removing leading `/' from member names
查看
[root@data-svr-01 ~]# tree /data/
/data/
└── 192.168.202.129
└── etc.2024-08-29.tar.gz
1 directory, 1 file
后面我们会把这些命令整理到脚本中,目前只是测试
2.3 整合命令
我们把前面用到的命令整合到脚本中,并进行测试
- 编写脚本
[root@data-svr-01 scripts]# cat etc_bak2svr.sh
#!/bin/bash
#author yurq
#set -e
. /etc/profile
ip=`ip a s ens33|sed -rn '3 s#^[^[:digit:]]+(.*)/.*#\1#gp'`
time=`date +%F`
svr=192.168.202.128
if [ ! -d /data/$ip ];then
mkdir -p /data/$ip
fi
tar zcf /data/$ip/etc.$time.tar.gz /etc/
if [ $? -ne 0 ];then
echo "tar etc failed"
fi
ls /data/$ip/etc.$time.tar.gz
if [ $? -ne 0 ];then
echo "etc.$time.tar.gz lost found."
fi
rsync -avz /data/$ip/etc.$time.tar.gz rsync_bak_01@$svr::backup --password-file=/etc/rsync.passwd
if [ $? -ne 0 ];then
echo "rsync failed"
fi
- 测试脚本
客户端
[root@data-svr-01 scripts]# rm -rf /data/*
[root@data-svr-01 scripts]# sh etc_bak2svr.sh
tar: Removing leading `/' from member names
/data/192.168.202.129/etc.2024-08-29.tar.gz
sending incremental file list
etc.2024-08-29.tar.gz
sent 10,207,860 bytes received 43 bytes 4,083,161.20 bytes/sec
total size is 10,411,198 speedup is 1.02
服务器
[root@backup-svr-01 ~]# ll /backup/
total 10168
-rw-r--r-- 1 rsync rsync 10411198 Aug 29 19:42 etc.2024-08-29.tar.gz
这并不是我们想要的,rsync
我们在使用的时候,应该把ip
构建的目录也带上一起传过去
- 修改脚本
rsync -avz /data/$ip rsync_bak_01@$svr::backup --password-file=/etc/rsync.passwd
把这行给了就可以了,注意ip
后不要加/
- 清理环境,重新上传
[root@data-svr-01 scripts]# sh etc_bak2svr.sh
tar: Removing leading `/' from member names
/data/192.168.202.129/etc.2024-08-29.tar.gz
sending incremental file list
192.168.202.129/
192.168.202.129/etc.2024-08-29.tar.gz
sent 10,207,905 bytes received 47 bytes 6,805,301.33 bytes/sec
total size is 10,411,198 speedup is 1.02
[root@backup-svr-01 ~]# tree /backup/
/backup/
└── 192.168.202.129
└── etc.2024-08-29.tar.gz
1 directory, 1 file
- 校验文件
写到这笔者想起来还应该带上MD5校验文件,修改脚本
[root@data-svr-01 data]# cat /scripts/etc_bak2svr.sh
#!/bin/bash
#author yurq
#set -e
. /etc/profile
ip=`ip a s ens33|sed -rn '3 s#^[^[:digit:]]+(.*)/.*#\1#gp'`
time=`date +%F`
svr=192.168.202.128
if [ ! -d /data/$ip ];then
mkdir -p /data/$ip
fi
tar zcf /data/$ip/etc.$time.tar.gz /etc/
if [ $? -ne 0 ];then
echo "tar etc failed"
fi
ls /data/$ip/etc.$time.tar.gz
if [ $? -ne 0 ];then
echo "etc.$time.tar.gz lost found."
fi
rsync -avz /data/$ip rsync_bak_01@$svr::backup --password-file=/etc/rsync.passwd
if [ $? -ne 0 ];then
echo "rsync failed"
fi
cd /data/
md5sum $ip/etc.$time.tar.gz > $ip/etc.md5
if [ $? -ne 0 ];then
echo "make md5 failed"
fi
验证
[root@data-svr-01 data]# sh /scripts/etc_bak2svr.sh
tar: Removing leading `/' from member names
/data/192.168.202.129/etc.2024-08-29.tar.gz
sending incremental file list
192.168.202.129/
192.168.202.129/etc.2024-08-29.tar.gz
192.168.202.129/etc.md5
sent 3,513 bytes received 19,446 bytes 4,174.36 bytes/sec
total size is 10,411,270 speedup is 453.47
[root@data-svr-01 data]# cat 192.168.202.129/etc.md5
f9a218d7b059fa412fdecef06d27f469 192.168.202.129/etc.2024-08-29.tar.gz
[root@backup-svr-01 ~]# tree /backup/
/backup/
└── 192.168.202.129
├── etc.2024-08-29.tar.gz
└── etc.md5
1 directory, 2 files
- 下面编辑定时任务,每天晚上2点备份
首先,编辑一个任务每分钟的任务进行测试,毕竟不能等到晚上2点再验证
[root@data-svr-01 data]# cat /var/spool/cron/root
* * * * * sh /scripts/etc_bak2svr.sh &>/dev/null
[root@data-svr-01 data]# tail -f /var/log/cron
...
Aug 30 03:26:01 data-svr-01 CROND[65599]: (root) CMD (sh /scripts/etc_bak2svr.sh &>/dev/null)
...
[root@backup-svr-01 ~]# tree /backup/
/backup/
└── 192.168.202.129
├── etc.2024-08-29.tar.gz
├── etc.2024-08-30.tar.gz
└── etc.md5
1 directory, 3 files
任务正常完成了,不过发现一个问题,md5文件把之前的冲掉了,所以需要修改脚本
md5sum $ip/etc.$time.tar.gz > $ip/etc.$time.md5
制作md5的时候加上日期
- 清除环境,再次验证。另外发现,md5在上传之后增加的,实际是不对的,调整执行顺序。
[root@data-svr-01 scripts]# cat etc_bak2svr.sh
#!/bin/bash
#author yurq
#set -e
. /etc/profile
ip=`ip a s ens33|sed -rn '3 s#^[^[:digit:]]+(.*)/.*#\1#gp'`
time=`date +%F`
svr=192.168.202.128
if [ ! -d /data/$ip ];then
mkdir -p /data/$ip
fi
tar zcf /data/$ip/etc.$time.tar.gz /etc/
if [ $? -ne 0 ];then
echo "tar etc failed"
fi
ls /data/$ip/etc.$time.tar.gz
if [ $? -ne 0 ];then
echo "etc.$time.tar.gz lost found."
fi
cd /data/
md5sum $ip/etc.$time.tar.gz > $ip/etc.$time.md5
if [ $? -ne 0 ];then
echo "make md5 failed"
fi
rsync -avz /data/$ip rsync_bak_01@$svr::backup --password-file=/etc/rsync.passwd
if [ $? -ne 0 ];then
echo "rsync failed"
fi
[root@backup-svr-01 ~]# tree /backup/
/backup/
└── 192.168.202.129
├── etc.2024-08-30.md5
└── etc.2024-08-30.tar.gz
1 directory, 2 files
2.4 扩展功能
- 添加清除过期备份,客户端备份保留7天
[root@data-svr-01 scripts]# mkdir /tmp/etc_backup
[root@data-svr-01 scripts]# ll /home/
total 0
[root@data-svr-01 scripts]# mkdir /home/yurq
[root@data-svr-01 scripts]# cp -r /etc/* /home/yurq/
[root@data-svr-01 scripts]# find /etc/ -type f -mtime +7|xargs -I file mv file /tmp/etc_backup/
[root@data-svr-01 scripts]# ll /tmp/etc_backup/
total 22300
-rwxr-xr-x. 1 0 0 8702 Jul 28 2020 00_header
-rw-r--r--. 1 0 0 232 May 9 2023 00-keyboard.conf
-rwxr-xr-x. 1 0 0 175 May 22 2020 00-netreport
-rwxr-xr-x. 1 0 0 1043 Mar 21 2019 00_tuned
-rwxr-xr-x. 1 0 0 232 Jul 28 2020 01_users
-rwxr-xr-x. 1 0 0 392 Aug 8 2019 0anacron
...
创建目录,并拷贝/etc/
内容进行测试,完成后把查找目录改为备份数据目录
find /data/ -type f -mtime +7|xargs -I file mv file /tmp/etc_backup/
把命令添加到脚本中
- 添加邮件通知
echo "test" |mailx -s "test" xxx@163.com
这里最好申请企业邮箱,发送太多条邮件到个人邮箱,可能被邮箱系统拦截