阿铭linux近16年的IT从业经验,6年+鹅厂运维经验,6年+创业公司经验,熟悉大厂运维体系,有从零搭建运维体系的实战经验。关注我,学习主流运维技能,让你比别人提升更快,涨薪更多!
作为一个系统管理员,数据备份是非常重要的。阿铭有一次没有做好备份策略,结果磁盘坏了,数据全部丢失。所以在以后的系统维护工作中,你一定要时刻牢记给数据做备份。
在Linux系统下数据备份的工具很多,但阿铭只用一种,那就是rsync,从字面意思上可以理解为remote sync(远程同步)。rsync不仅可以远程同步数据(类似于scp),而且可以本地同步数据(类似于cp),但不同于cp或scp的一点是,它不会覆盖以前的数据(如果数据已经存在),而是先判断已经存在的数据和新数据的差异,只有数据不同时才会把不相同的部分覆盖。如果你的Linux没有rsync命令,请使用命令yum install -y rsync安装。
下面阿铭先举一个例子,然后再详细讲解rsync的用法。
# rsync -av /etc/passwd /tmp/1.txtsending incremental file listpasswdsent 1,205 bytes received 35 bytes 2,480.00 bytes/sectotal size is 1,113 speedup is 0.90
上例将会把/etc/passwd同步到/tmp/目录下,并改名为1.txt。如果是远程复制,数据备份就是这样的形式——IP:path,比如192.168.72.128:/root/。具体用法如下:
# rsync -av /etc/passwd 192.168.72.128:/tmp/1.txtThe authenticity of host '192.168.72.128 (192.168.72.128)' can't be established.ECDSA key fingerprint is SHA256:gFHUJnoZAjOcnG95pt7Zg9iaPZGDiOrbZyssZtRoQhA.Are you sure you want to continue connecting (yes/no/[fingerprint])? yesWarning: Permanently added '192.168.72.128' (ECDSA) to the list of known hosts.root@192.168.72.128's password:sending incremental file listsent 45 bytes received 12 bytes 8.77 bytes/sectotal size is 1,113 speedup is 19.53
首次连接时会提示是否要继续连接,我们输入yes继续。当建立连接后,需要输入密码。如果手动执行这些操作比较简单,但若是写在脚本中该怎么办呢?这就涉及添加信任关系了,该部分内容稍后会详细介绍。
14.7.1rsync的命令格式
rsync [OPTION]... SRC DESTrsync [OPTION]... SRC [USER@]HOST:DESTrsync [OPTION]... [USER@]HOST:SRC DESTrsync [OPTION]... [USER@]HOST::SRC DESTrsync [OPTION]... SRC [USER@]HOST::DEST
在阿铭前面举的两个例子中,第一个例子为第一种格式,第二个例子为第二种格式。但不同的是,阿铭并没有加user@host,如果不加默认指的是root。第三种格式是从远程目录同步数据到本地。第四种和第五种格式使用了两个冒号,这种格式和其他格式的验证方式不同。
14.7.2rsync常用选项
rsync命令各选项的含义如下。
选项虽然多,但阿铭常用的选项也就-a、-v、-z、--delete和--exclude这几个,请牢记它们!下面阿铭将会针对这些选项做一系列小试验。
1. 建立目录和文件
过程如下所示:
# mkdir rsync# cd rsync# mkdir test1# cd test1# touch 1 2 3/root/123.txt# ln -s/root/123.txt ./123.txt# ls -l总用量 0-rw-r--r-- 1 rootroot 0 6月 26 17:30 1lrwxrwxrwx 1 rootroot 13 6月 26 17:30 123.txt ->/root/123.txt-rw-r--r-- 1 rootroot 0 6月 26 17:30 2-rw-r--r-- 1 rootroot 0 6月 26 17:30 3# cd ..
阿铭建立这些文件的目的就是为后续试验做一些准备工作。
2. 使用-a选项
首先来看看-a选项的用法,如下所示:
# rsync -a test1 test2# ls test2test1# ls test2/test1/1 123.txt 2 3
这里有一个问题,就是本来想把test1目录直接复制成test2目录,可结果rsync却新建了test2目录,然后把test1放到test2当中。为了避免这样的情况发生,可以这样做:
# rm -rf test2# rsync -a test1/ test2/# ls -l test2/总用量 0-rw-r--r-- 1 rootroot 0 6月 26 17:30 1lrwxrwxrwx 1 rootroot 13 6月 26 17:30 123.txt -> /root/123.txt-rw-r--r-- 1 root root 0 6月 26 17:30 2-rw-r--r-- 1 root root 0 6月 26 17:30 3
这里加一个斜杠就好了,所以阿铭建议你在使用rsync备份目录时,要养成加斜杠的习惯。前面已经讲了-a选项等同于-rlptgoD,且-a还可以和--no-OPTIN一并使用。下面再来看看-l选项的作用,如下所示:
# rm -rf test2# rsync -av --no-l test1/ test2/sending incremental file listcreated directory test2skIPping non-regular file "123.txt"123sent 234 bytes received 144 bytes 756.00 bytes/sectotal size is 13 speedup is 0.03
上例中使用了-v选项,跳过了非普通文件123.txt。其实123.txt是一个软连接文件,如果不使用-l选项,系统则不理会软连接文件。虽然加-l选项能复制软连接文件,但软连接的目标文件却没有复制。有时我们需要复制软连接文件所指向的目标文件,这又该怎么办呢?
3. 使用-L选项
具体用法如下:
# rm -rf test2# rsync -avL test1/ test2/sending incremental file listcreated directory test21123.txt23sent 265 bytes received 123 bytes 776.00 bytes/sectotal size is 0 speedup is 0.00# ls -l test2/总用量 0-rw-r--r-- 1 root root 0 6月 26 17:30 1-rw-r--r-- 1 root root 0 6月 26 17:30 123.txt-rw-r--r-- 1 root root 0 6月 26 17:30 2-rw-r--r-- 1 root root 0 6月 26 17:30 3
上例加上-L选项就可以把SRC中软连接的目标文件复制到DST。
4. 使用-u选项
首先查看一下test1/1和test2/1的创建时间(肯定是一样的),然后使用touch修改一下test2/1的创建时间(此时test2/1要比test1/1的创建时间晚一些)。如果不加-u选项,会把test2/1的创建时间变成和test1/1一样,如下所示:
# ll test1/1 test2/1-rw-r--r-- 1 root root 0 6月 26 17:30 test1/1-rw-r--r-- 1 root root 0 6月 26 17:30 test2/1
从上例可以看出二者的创建时间是一样的。下面修改test2/1的创建时间,然后不加-u同步,如下所示:
# echo "1111" > test2/1# ll test2/1- rw-r--r-- 1 root root 5 6月 26 17:33 test2/1# rsync -a test1/1 test2/# ll test2/1-rw-r--r-- 1 root root 0 6月 26 17:30 test2/1
这里test2/1的创建时间还是和test1/1一样。下面加上-u选项,如下所示:
# echo "1111" > test2/1# ll test2/1-rw-r--r-- 1 root root 5 6月 26 17:34 test2/1# rsync -avu test1/ test2/sending incremental file list123.txt -> /root/123.txtsent 134 bytes received 22 bytes 312.00 bytes/sectotal size is 13 speedup is 0.08# ll test1/1 test2/1-rw-r--r-- 1 root root 0 6月 26 17:30 test1/1-rw-r--r-- 1 root root 5 6月 26 17:34 test2/1
加上-u选项后,不会再把test1/1同步为test2/1了。
5. 使用--delete选项
首先删除test1/123.txt,如下所示:
# rm -f test1/123.txt# ls test1/1 2 3
然后把test1/目录同步到test2/目录下,如下所示:
# rsync -av test1/ test2/sending incremental file list1sent 130 bytes received 38 bytes 336.00 bytes/sectotal size is 0 speedup is 0.00# ls test2/1 123.txt 2 3
上例中,test2/目录并没有删除123.txt。下面加上--delete选项,示例如下:
# rsync -av --delete test1/ test2/sending incremental file listdeleting 123.txtsent 84 bytes received 23 bytes 214.00 bytes/sectotal size is 0 speedup is 0.00# ls test2/1 2 3
这里test2/目录下的123.txt也被删除了。
另外还有一种情况,就是如果在DST中增加文件了,而SRC当中没有这些文件,同步时加上--delete选项后同样会删除新增的文件。如下所示:
# touch test2/4# ls test1/1 2 3# ls test2/1 2 3 4# rsync -a --delete test1/ test2/# ls test1/1 2 3# ls test2/1 2 3
6. 使用--exclude选项
具体用法如下:
# touch test1/4# rsync -a --exclude="4" test1/ test2/# ls test1/1 2 3 4# ls test2/1 2 3
该选项还可以与匹配字符*一起使用,如下所示:
# touch test1/1.txt test1/2.txt# ls test1/1 1.txt 2 2.txt 3 4# rsync -a --progress --exclude="*.txt" test1/ test2/sending incremental file list40 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=0/5)# ls test2/1 2 3 4
上例中,阿铭也使用了--progress选项,它主要是用来观察rsync同步过程状态的。
总而言之,平时你使用rsync同步数据时,使用-a选项基本上就可以达到想要的效果了。当有个别需求时,也会用到--no-OPTION、-u、 -L、--delete、--exclude以及--progress等选项。其他选项阿铭都没有介绍,如果在以后的工作中遇到特殊需求,可以查一下rsync的man文档。
14.7.3rsync应用实例
上面列举了许多小案例,都是为了让大家熟悉rsync各个选项的基本用法。本节正式介绍rsync的实际应用,请大家认真学习。在正式试验前,你需要准备两台Linux机器,因为下面的小案例都是从一台机器复制文件到另一台机器。前面阿铭也带着大家克隆过一台虚拟机,所以把那台克隆的虚拟机打开即可,阿铭的两台机器IP地址分别为192.168.72.128和192.168.72.129。
1. 通过ssh的方式
在之前介绍的rsync的5种命令格式中,第二种和第三种(一个冒号)就属于通过ssh的方式备份数据。这种方式其实就是让用户登录到远程机器,然后执行rsync的任务:
# rsync -avL test1/ 192.168.72.129:/tmp/test2/The authenticity of host '192.168.72.129 (192.168.72.129)' can't be established.ECDSA key fingerprint is SHA256:gFHUJnoZAjOcnG95pt7Zg9iaPZGDiOrbZyssZtRoQhA.Are you sure you want to continue connecting (yes/no/[fingerprint])? yesWarning:Permanently added '192.168.72.129' (ECDSA) to the list of known hosts.root@192.168.72.129's password:sending incremental file listcreated directory /tmp/test211.txt22.txt34sent 377 bytes received 166 bytes 98.73 bytes/sectotal size is 0speedup is 0.00
这种方式就是前面介绍的第二种方式了,是通过ssh复制的数据,需要输入192.168.72.129那台机器root账户的密码。
当然也可以使用第三种方式复制,如下所示:
# rsync -avL 192.168.72.129:/tmp/test2/ ./test3/root@192.168.72.129's password:receiving incremental file listcreated directory./test311.txt22.txt34sent 141 bytes received 389 bytes 117.78 bytes/sectotal size is 0speedup is 0.00
以上两种方式如果写入脚本,做备份麻烦,要输入密码,但我们可以通过密钥(不设立密码)验证。下面阿铭具体介绍一下通过密钥登录远程主机的方法。
你可以根据3.33节,把128机器上的公钥内容放到129机器下的authorized_keys里面,这样128机器登录129机器时不再输入密码,如下所示:
# ssh 192.168.72.129Last login: Fri Jun 26 15:46:33 2020 from 192.168.72.1
现在不用输入密码也可以登录主机129了。下面先从129主机退出来,再从主机128上执行一下rsync命令试试吧:
# rsync -avL test1/ 192.168.72.129:/tmp/test4/sending incremental file listcreated directory /tmp/test411.txt22.txt34sent 377 bytes received 166 bytes 362.00 bytes/sectotal size is 0 speedup is 0.00
2. 通过后台服务的方式
这种方式可以理解为:在远程主机上建立一个rsync的服务器,在服务器上配置好rsync的各种应用,然后将本机作为rsync的一个客户端连接远程的rsync服务器。下面阿铭就介绍一下如何配置一台rsync服务器。
在128主机上建立并配置rsync的配置文件/etc/rsyncd.conf,如下所示(请把你的rsyncd.conf编辑成如下内容):
# vim /etc/rsyncd.confport=873log file=/var/log/rsync.logpid file=/var/run/rsyncd.pidaddress=192.168.72.128[test]path=/root/rsyncuse chroot=truemax connections=4read only=nolist=trueuid=rootgid=rootauth users=testsecrets file=/etc/rsyncd.passwdhosts allow=192.168.72.0/24
其中配置文件分为两部分:全局配置部分和模块配置部分。全局部分就是几个参数,比如阿铭的rsyncd.conf中的port、log file、pid file和address都属于全局配置;而[test]以下部分就是模块配置部分了。一个配置文件中可以有多个模块,模块名可自定义,格式就像阿铭的rsyncd.conf中的这样。其实模块中的一些参数(如use chroot、max connections、udi、gid、auth users、secrets file以及hosts allow都可以配置成全局参数。当然阿铭并未给出所有的参数,你可以通过命令man rsyncd.conf获得更多信息。
下面就简单解释一下这些参数的作用。
编辑secrets file并保存后要赋予600权限,如果权限不对,则不能完成同步,如下所示:
# vi /etc/rsyncd.passwd //写入如下内容test:test123# chmod 600 /etc/rsyncd.passwd
启动rsyncd服务,如下所示:
# rsync --daemon --config=/etc/rsyncd.conf
启动后可以查看一下日志,并查看端口是否启动,如下所示:
# cat /var/log/rsync.log2020/06/26 17:43:11 [4680] rsyncd version 3.1.3 starting, listening on port 873#.NETstat -lnp |grep rsynctcp 0 0 192.168.72.128:873 0.0.0.0:* LISTEN 4680/rsync
如果想开机启动rsyncd服务,请把/usr/bin/rsync --daemon --confg=/etc/rsyncd.conf写入/etc/rc.d/rc.local文件。
为了不影响实验过程,还需要把两台机器的firewalld服务关闭,并设置为不开机启动,操作过程如下所示:
# systemctl stop firewalld ; systemctl disable firewalld //两台机器都执行Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.# rsync -avL test@192.168.72.128::test/test1/ /tmp/test5/Password:receiving incremental file listcreated directory /tmp/test511.txt22.txt34sent 141 bytes received 377 bytes 8.56 bytes/sectotal size is 0 speedup is 0.00
阿铭刚刚提到了选项use chroot,默认为true。首先在主机128的/root/rsync/test1/目录下创建一个软连接文件,如下所示:
# ln -s /etc/passwd /root/rsync/test1/test.txt# ls -l /root/rsync/test1/test.txtlrwxrwxrwx 1 root root 11 6月 26 17:47 /root/rsync/test1/test.txt -> /etc/passwd
然后再到主机129上执行同步,如下所示:
# rsync -avLtest@192.168.72.128::test/test1/ /tmp/test6/Password:receiving incremental file listsymlink has no referent: "/test1/test.txt" (in test)created directory /tmp/test611.txt22.txt34sent 141 bytes received 436 bytes 42.74 bytes/sectotal size is 0 speedup is 0.00rsync error: some files/attrs were not transferred (see previous errors) (code 23) atmAIn.c(1659) [generator=3.1.3]
从上例可以看出,如果设置use chroot为true,则同步软连接文件会有问题。下面阿铭把主机128的rsync配置文件修改一下,把true改为false,如下所示:
# sed -i 's/use chroot=true/use chroot=false/'/etc/rsyncd.conf# grep 'use chroot' /etc/rsyncd.confuse chroot=false
然后再到主机129上再次执行同步,如下所示:
# rsync -avL test@192.168.72.128::test/test1/ /tmp/test7/Password:receiving incremental file listcreated directory/tmp/test711.txt22.txt34test.txtsent 160 bytes received 1,556 bytes 137.28 bytes/sectotal size is 1,113 speedup is 0.65
这样问题就解决了。另外,修改完rsyncd.conf配置文件后不需要重启rsyncd服务,这是rsync的一个特定机制,配置文件是即时生效的。
上面的例子中,阿铭都有输入密码,这意味着我们还是不能写入脚本中自动执行。其实这种方式可以不用手动输入密码,它有两种实现方式。
(1) 指定密码文件
在客户端(即主机129)上编辑一个密码文件:/etc/pass,加入test用户的密码:
# vim /etc/pass //写入如下内容test123
修改密码文件的权限:
# chmod 600 /etc/pass
在同步时指定密码文件,就可以省去输入密码的步骤,如下所示:
# rsync -avL test@192.168.72.128::test/test1/ /tmp/test8/ --password-file=/etc/passreceiving incremental file listcreated directory /tmp/test811.txt22.txt34test.txtsent 160 bytes received 1,556 bytes 149.22 bytes/sectotal size is 1,113 speedup is 0.65
(2) 在rsync服务端不指定用户
在服务端(即主机128)上修改配置文件rsyncd.conf,删除关于认证账户的配置项(auth user和secrets file这两行),如下所示:
# sed -i 's/auth users/#auth users/;s/secrets file/#secrets file/' /etc/rsyncd.conf
上例是在auth users和secrets file这两行的最前面加一个#,这表示将这两行作为注释,使其失去意义。在前面阿铭未曾讲过sed的这种用法,它是用分号把两个替换的子命令块替换了。
然后我们再到客户端主机129上进行测试,如下所示:
# rsync -avL test@192.168.72.128::test/test1/ /tmp/test9/receiving incremental file listcreated directory /tmp/test911.txt22.txt34test.txtsent 160 bytes received 1,556 bytes 163.43 bytes/sectotal size is 1,113 speedup is 0.65
注意,这里不用再加test这个用户了,默认是以root的身份复制的。现在登录时已经不需要输入密码了。