今天聊一聊如何做好一个网站的备份工作,我会循序渐进的聊透这个问题。
本文以我的博客网站备份为案例讲解。先从手动备份聊起,在循序渐进优化和补充细节,编写脚本,使用定时任务,使用rsync增量备份,md5变更校验,发送邮件通知等。除了讲demo,还会深入讲解命令的配置项,原理等
网站备份是一样安全防御措施,是未雨绸缪的工作,以应对一些极端场景下的灾难,把损失降到最低。无论是个人网站还是企业网站,备份的作用都是不言而喻的。
补充知识点:关于备份所需linux基础命令如
cp
、scp
、tar
、grep
可以读一下我的另一篇文章《超全的linux基础总结》
备份目标:vanblog的数据库、图床、nginx配置和服务器配置/etc
目录
vanblog是一款开源软件,我的博客就是使用这款开源软件搭建的,目前服务器是在腾讯云上买的,考虑到以后有服务器迁移的计划以及保证数据不被丢失,所以需要定期备份。但是关于vanblog大家不用了解太多,我是采用docker的方式启动的,通过docker容器卷映射,我会告知备份哪些目录即可。
只要知道我要备份的目录如下即可
/home/ubuntu/myDockerFiles/vanblog/data/mongo/vanBlog
vanBlog数据库备份/home/ubuntu/myDockerFiles/vanblog/data/static
vanBlog 静态资源备份/etc/
服务器配置备份/home/ubuntu/myDockerFiles/nginx2
备份nginx我在/tmp
文件夹下创建backup文件夹存放着三个目录的压缩文件 执行的脚本如下
shmkdir -p /tmp/backup/
tar zcf /tmp/backup/$(date +%F_%H:%M)_mongo_vanblog.tar.gz /home/ubuntu/myDockerFiles/vanblog/data/mongo/vanBlog
tar zcf /tmp/backup/$(date +%F_%H:%M)_vanblog.tar.gz /home/ubuntu/myDockerFiles/vanblog/data/static
tar zcf /tmp/backup/$(date +%F_%H:%M)_etc.tar.gz /etc
tar zcf /tmp/backup/$(date +%F_%H:%M)_nginx2.tar.gz /home/ubuntu/myDockerFiles/nginx2
# 本地电脑执行scp下载文件夹
scp -P myport ubuntu@my-ip:/tmp/backup ./
上述手动备份的缺点是 要手动执行脚本,要自己记得定期备份,由于是全量备份耗时长。
这种方式个人网站备份或许还行,但对于企业来说不现实。
好在linux有一个工具rsync
, 它和scp
命令一样好用,但它是增量备份,
示例命令:rsync -avz /etc/ root@backup_ip:/tmp/
第一次执行全量下载/etc
目录, 第二次执行,下载/etc
目录新增和有变更的内容
下面了解下rsync
rsync
的应用场景
使用示例:把 /etc/
目录传输到备份服务器的/tmp
目录。
scp -r /etc/ root@backup_ip:/tmp/
rsync -avz /etc/ root@backup_ip:/tmp/
与scp
功能类似rsync
可以将当前机器的文件资源上传到备份机上(推
)
也可以从备份机下载文件资源到当前机器(拉
)
rsync使用 | ||
---|---|---|
rsync -a | 源文件 | 目标 |
推送:rsync | /etc/hostname | root@10.0.0.31:/tmp |
拉取:rsync | root@/10.0.0.31:/etc/hosts | /opt/ |
前面备份执行的命令我们可以写个在脚本里,这样一键执行,但是rsync的远程模式是需要交互的,输入命令后还需要手动输入ssh密码才可以执行。
我们希望跳过输入密码的阶段, rsync有个选项--password-file
,然而折腾下来无法实现预期效果。
原因是rsync对于自动脚本执行有严格的安全控制,一般企业都有专门的备份服务器,在备份服务器上搭建rsync服务端,在网站服务器上配置定时任务执行脚本来把数据增量备份到备份服务器上。
其实rsync
有三种使用模式
rsync
守护进程模式这里就是使用rsync
的守护进程模式
以Ubuntu为例,我参考按照油管视频Ubuntu 18配置rsync,当然也有坑的,我用红色文字描述。
rsync
,这一步跳过sudo vi /etc/default/rsync
RSYNC_ENABLE=inetd
/etc/rsyncd.conf
,从/usr/share/doc/rsync/examples/rsyncd.conf
模版复制一份,按照视频是先配置不开启账号密码效验的版本,我偷个懒跳过,直接上完整版本sh[ftp] # 模块名字 用户客户访问服务端的时候指定
comment = www by guoguo # 注释署名名
path = /home/backup # 模块对应的路径,建议和模块名一致
use chroot = yes
lock file = /var/lock/rsyncd # 进程/服务的锁文件 防止重复运行
read only = no # no表示可以进行读写
list = yes
uid = root
gid = root
auth users =rsync # rsync服务端进行验证用户:用户名
secrets file = /etc/rsyncd.secrets # rsync 服务端进行验证:密码文件
strict modes = yes
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 600
refuse options = checksum dry-run
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz
注这里跳过了注释
cat /etc/rsyncd.conf |grep -v "^#"
这里看一下 /home/test
目录和/etc/rsyncd.secrets
文件的权限
/home/test
目录和/etc/rsyncd.secrets
文件 的所有者都是root
对应配置文件的uid
和 gid
配置项, 你可以使用chown
修改文件的所有者/home/test
目录的权限是755,/etc/rsyncd.secrets
文件的权限是600,可使用 chmod
修改文件权限/etc/rsyncd.secrets
文件内容为rsync:pwd
测试 在另一台机器也就是rsync客户端,创建文件/etc/rsync.client
内容为pwd
,与服务端/etc/rsyncd.secrets
文件内容对应上,文件所有者和权限如下
/etc/init.d/rsync restart
或者 systemctl start rsync
,lsof -i:873
或者 systemctl status rsync
systemctl enable rsync
因为后面要配置定时任务,定时任务一般都是root账户执行,所以这里使用root账户,执行命令也是root账户,具体命令rsync -vzrtopg --progress --password-file=/etc/rsync.client rsync@yourip::ftp .
rsync@yourip::ftp
这段内容
rsync
与服务端配置文件的auth users
字段对应上::
固定格式ftp
与服务端配置文件[]
中的内容对应上,表示一个模块如果前面的操作无误,这个命令可以将服务器 当前目录 增量同步到 备份服务器的/home/backup
目录。
下面来看一下实际案例,我用要备份4个文件夹
/home/ubuntu/myDockerFiles/vanblog/data/mongo/vanBlog
/home/ubuntu/myDockerFiles/vanblog/data/static
/etc
/home/ubuntu/myDockerFiles/nginx2
完整/etc/rsyncd.conf
的配置如下
sh[etc]
comment = public archive
path = /home/backup/etc
use chroot = yes
lock file = /var/lock/rsyncd
read only = no
list = yes
uid = root
gid = root
auth users =rsync
secrets file = /etc/rsyncd.secrets
strict modes = yes
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 600
refuse options = checksum dry-run
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz
[mongo_vanblog]
comment = www by guoguo
path = /home/backup/mongo_vanblog
use chroot = yes
lock file = /var/lock/rsyncd
read only = no
list = yes
uid = root
gid = root
auth users =rsync
secrets file = /etc/rsyncd.secrets
strict modes = yes
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 600
[vanblog]
comment = www by guoguo
path = /home/backup/vanblog
use chroot = yes
lock file = /var/lock/rsyncd
read only = no
list = yes
uid = root
gid = root
auth users =rsync
secrets file = /etc/rsyncd.secrets
strict modes = yes
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 600
[nginx2]
comment = www by guoguo
path = /home/backup/nginx2
use chroot = yes
lock file = /var/lock/rsyncd
read only = no
list = yes
uid = root
gid = root
auth users =rsync
secrets file = /etc/rsyncd.secrets
strict modes = yes
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 600
/etc/backup.sh
网站服务器rsync -vzrtopg --progress --password-file=/etc/rsync.client /etc/ rsync@backup-ip::etc rsync -vzrtopg --progress --password-file=/etc/rsync.client /home/ubuntu/myDockerFiles/vanblog/data/mongo/vanBlog/ rsync@backup-ip::mongo_vanblog rsync -vzrtopg --progress --password-file=/etc/rsync.client /home/ubuntu/myDockerFiles/vanblog/data/static/ rsync@backup-ip::vanblog rsync -vzrtopg --progress --password-file=/etc/rsync.client /home/ubuntu/myDockerFiles/nginx2/ rsync@backup-ip::nginx2
crontab -e
增加内容sh00 02 * * * bash /etc/script/backup.sh &> /dev/null
每天凌晨2点自动增量备份
温馨提示: rsync同步文件是只改只增,不删,如果你要考虑同步删除,可以使用NFS,但是NFS 是实时同步的。
业务需求总是千变万化的,补充在写rsync的知识点备用
rsync 的选项
-e 'ssh -p port'
-a
是 -rlptgoD
的简写
-r
递归复制-l
复制软连接-p
保持权限不变-m
保持修改时间不变-o
用户组不变-D --deices --specials
设备于特殊文件-v
展示过程 通过这个可以观察到rsync是增量更新-z
传输数据的时候进行压缩(推荐公网用)-P
断电续传--bwlimit
限速--exclude
--exclude-from
排除注意
rsync对于目录/etc/
和 /etc
是有区别的
/etc
/etc
目录+目录下的内容/etc/
/etc/
目录下的内容rsync 还有一个选项--delete
,保持源与目标数据一致,比较危险,一般实时同步才会使用,使用前慎重
rsync 还有两个选项用于安全控制的
hosts allow = 10.0.0.0/24
# 只允许哪些ip或网段访问的白名单,多个网段用“,”拼接hosts deny = 0.0.0.0/32
# 黑名单由于rsync的加密机制比较弱,建议在不要在公网使用,而是在局域网内使用,密码也要设计复杂一点
最初我是看的老男孩的教程,那个课程是基于Centos的,昙花一现的好过,后来又不行了,这里粘贴一下笔记
yum install -y rsync
/etc/rsyncd.conf
,内容如下sh# 全局配置
fake super =yes # centos7 hack 如果不开启则传输报错(伪装成root用户)
uid = rsync
gid = rsync
use chroot = no
max connections = 100
timeout = 600
lock file = /var/log/rsyncd.lock # 进程/服务的锁文件 防止重复运行
pid file = /var/run/rsyncd.pid #存放服务的pid号
log file = /var/log/rsyncd.log # 服务端日志
ignore errors #忽略错误
# hosts allow = 10.0.0.0/24 # 只允许哪些ip或网段访问 白名单
# hosts deny = 0.0.0.0/32
#############
[data_rsync] # 模块名字 用户客户访问服务端的时候指定
comment = www by guoguo # 注释署名名
path = /data_rsync # 模块对应的路径
read only = no # no #可以进行读写
list = no # 关闭rsync服务端列表功能
auth users = rsync_backup # rsync 服务端进行验证用户:用户名
secrets file = /etc/rsync.password # rsync 服务端进行验证:密码文件
别着急启动,要创建 用户、目录、密码文件
shuseradd -s /sbin/nologin -M rsync # 添加rsync虚拟用户
echo 'rsync_back:1' > /etc/rsync.password # rsync_back是用户名 密码是1
chmod 600 /etc/rsync.password # 权限一定要改,不然rsync服务认为是故障
mkdir -p /data_rsync/
chown -R rsync.rsync /data_rsync/
启动服务并配置开启自启动
systemctl start rsyncd
systemctl enable rsyncd
我的服务器是Ubuntu系统,运行结果是失败的
通过搜索引擎和chatGPT找到的解决方案是
/etc/default/rsync
文件/etc/systemd/system/rsyncd.service
内容如下sh[Unit]
Description=fast remote file copy program daemon
After=network.target
[Service]
ExecStart=/usr/bin/rsync --daemon --no-detach
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
User=rsync
Group=rsync
[Install]
WantedBy=multi-user.target
另外rsync服务使用的是873端口,记得去防火墙放行873端口。
再次尝试启动服务和配置开启自启动OK了。
完整的备份流程还记录下哪些变更,然后发送邮件。
检测变更可以使用命令md5sum
md5sum
用于计算一个文件的hash值
shroot@myServer:/tmp# echo bbb > bb.txt
root@myServer:/tmp# md5sum bb.txt
b8694d827c0f13f22ed3bc610c19ec15 bb.txt
root@myServer:/tmp# md5sum bb.txt > comp.txt
root@myServer:/tmp# cat comp.txt
b8694d827c0f13f22ed3bc610c19ec15 bb.txt
root@myServer:/tmp# md5sum -c comp.txt
bb.txt: OK
root@myServer:/tmp# echo ccc > bb.txt
root@myServer:/tmp# md5sum -c comp.txt
bb.txt: FAILED
md5sum: WARNING: 1 computed checksum did NOT match
root@myServer:/tmp#
一般情况下都是打个压缩包 比较文件,这样能检测出来有没有配置变更。
如果一定要检测文件夹变更,可参考下面的示例
shroot@myServer:/tmp# md5sum `find /etc -maxdepth 1 -type f` > md5sums.txt
root@myServer:/tmp# md5sum -c md5sums.txt | grep -v "OK$"
root@myServer:/tmp# echo aa >> /etc/test.txt
root@myServer:/tmp# md5sum -c md5sums.txt | grep -v "OK$"
/etc/test.txt: FAILED
md5sum: WARNING: 1 computed checksum did NOT match
root@myServer:/tmp# md5sum -c md5sums.txt | grep "FAILED$"
md5sum: WARNING: 1 computed checksum did NOT match
/etc/test.txt: FAILED
root@myServer:/tmp#
这个命令可以检查文件夹下面的修改的配置,无法检测新增的配置, 如果想要检测新增的配置有以下几个方案
diff
或 vimdiff
shmd5sum `find /etc -maxdepth 1 -type f` > md5sums2.txt
diff md5sums2.txt md5sums.txt
思路是这样,在脚本中 把输出结果写入到一个文件中,示例
shmd5sum -c md5sums.txt | grep "FAILED$" &> /tmp/result.txt`
通过mail命令发送邮件
shcat /tmp/result.txt | mail -s "`date +%F__%H:%M` 备份日志" 2315162186@qq.com
但是这种无邮箱地址的邮件会被送到垃圾箱
需要配置邮件发送人,可以参考 我之前写的文章 发送邮件
至此,这算是较为完整的网站备份流程了。
本文作者:郭郭同学
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!