如何使用 Rsync 克隆或复制 Linux 服务器
克隆是通过使用强大的 rsync 命令行工具创建实时 Linux 服务器的精确副本的细致过程,rsync 是一种高效的文件同步和传输工具。
克隆需要使用两个服务器实例:源服务器(用作要克隆的服务器)和目标服务器(实际克隆过程在其中发生)。
通过使用rsync命令,可以完成从源服务器到目标服务器的所有文件和目录的复杂同步。
也可以用于Linux物理机迁移到虚拟机,linux物理机克隆到新的物理机。
适用于局域网不停机情况下的快速克隆。
注意:
1.迁移的过程中数据库需要停库同步(这个没办法啊,内存里会有数据刷不到数据文件上,任何一家工具在有数据库的情况下,都是建议最后一次同步要关库,如不停库,复制完库也起不来)
2.如果只是普通的应用服务器、中间件这种可以不用停,直接复制就行。
学习如何使用 Rsync 文件同步工具热克隆 Linux 服务器。
实验设置
这是我们在本指南中使用的实验室设置,您可以使用 rsync 命令克隆任何 Linux 发行版。
源服务器 – RHEL 9 – 192.168.2.100
目标服务器 – RHEL 9 – 192.168.2.200
源服务器是我们要克隆到目标服务器的服务器。
设置和要求
在继续之前,请确保您已满足以下先决条件:
两台服务器需要运行相同版本的操作系统,即 RHEL 9.x 或 RHEL 8.x 等。
此外,服务器应具有相同的文件系统和相同的硬盘配置,即无论是单磁盘还是 RAID 配置。
注意:在热克隆之前,请确保禁用所有涉及传输或写入数据的服务,例如:数据库、邮件服务等
在 Linux 中安装 Rsync
为了成功克隆,两台服务器上都需要存在rsync命令行工具,该工具将用于将源服务器镜像到目标服务器并同步两个系统之间的所有差异。
可以通过运行以下命令来检查安装的 rsync 版本:
XML/HTML代码
- rsync --version
如果要查看有关 rsync 的其他信息,请执行以下 rpm 命令或 dpkg-query 命令:
XML/HTML代码
- rpm -qi rsync [On RHEL/CentOS/Fedora and Rocky/AlmaLinux]
- dpkg-query --status rsync [On Debian, Ubuntu and Mint]
如果rsync丢失或者未安装,请使用默认的包管理器将其安装在您的系统上。
XML/HTML代码
- sudo apt install rsync [On Debian, Ubuntu and Mint]
- sudo yum install rsync [On RHEL/CentOS/Fedora and Rocky/AlmaLinux]
- sudo emerge -a sys-apps/rsync [On Gentoo Linux]
- sudo apk add rsync [On Alpine Linux]
- sudo pacman -S rsync [On Arch Linux]
- sudo zypper install rsync [On OpenSUSE]
配置源 Linux 服务器
您可能希望从克隆中排除某些目录和文件,因为它们要么已在目标服务器中可用,要么是自动生成的。其中包括 /boot、/tmp 和 /dev 目录。
因此,创建一个排除文件 /root/exclude-files.txt 并添加以下条目:
XML/HTML代码
- /boot
- /dev
- /tmp
- /sys
- /proc
- /backup
- /etc/fstab
- /etc/mtab
- /etc/mdadm.conf
- /etc/sysconfig/network*
保存并退出配置文件。
也可以用命令cat直接写入文件,注意不同系统的配置文件路径,或者需要排除的文件路径不一样,可以根据实际修改,例如Debian系统
XML/HTML代码
- cat >/root/exclude-files.txt<<EOF
- /boot
- /dev
- /tmp
- /sys
- /proc
- /etc/fstab
- /etc/network
- EOF
切记,根据实际进行修改,不可完全照抄,如果网络配置文件没有克隆,IP就会一样。克隆后系统密码完全一样。
克隆 Linux 服务器
一切设置完毕后,继续使用以下命令将您的服务器rsync到远程或目标服务器:
XML/HTML代码
- sudo rsync -vPa -e 'ssh -o StrictHostKeyChecking=no' --exclude-from=/root/exclude-files.txt / REMOTE-IP:/
命令详解:
XML/HTML代码
- sudo – 这是一个允许以管理权限执行命令的命令。
- rsync – rsync 命令本身用于文件同步和传输。
- -v:此选项启用详细输出,提供有关同步进度的详细信息。
- -P – 此选项相当于--progress,启用部分文件传输并在同步期间显示每个文件的进度。
- -a – 此选项代表“归档模式”,是保留重要文件属性(例如权限、所有权、时间戳等)的简写。
- -e – 此选项指定用于同步的远程 shell。
- -o StrictHostKeyChecking=no – 禁用严格的主机密钥检查,这意味着如果远程服务器的主机密钥未知,SSH 连接将不会提示确认。
- --exclude-from=/root/exclude-files.txt – 此选项允许您指定包含要从同步中排除的模式或路径列表的文件。
- / – 正斜杠表示将克隆的源目录或根目录。
- REMOTE-IP:/ – 指定目标服务器的 IP 地址或主机名,后跟冒号和正斜杠。它指示将复制克隆文件的远程目录。
同步完成后,重新启动目标系统以重新加载更改,然后使用源服务器的凭据启动到服务器即可完成同步。
也可以使用脚本,无人值守克隆。
创建同步脚本
XML/HTML代码
- cat rsync.sh
- rsync -vPa -e 'ssh -o StrictHostKeyChecking=no' --progress --exclude-from=/root/exclude-files.txt / 192.168.2.200:/
- chmod +x rsync.sh
后台启动同步进程
XML/HTML代码
- nohup ./rsync.sh &
想要查看输出可以
XML/HTML代码
- tail -f nohup.out
等待结束,可以查看nohup结果显示完成(会有部分复制不成功,不用担心)
克隆完重启目标端服务器。
rsync主要用于备份和镜像。具有速度快、避免复制相同内容和支持符号链接的优点。
rsync,从字面意思上可以理解为remote sync(远程同步)。rsync不仅可以远程同步数据(类似于scp),而且可以本地同步数据(类似于cp),但不同于cp或scp的一点是,它不会覆盖以前的数据(如果数据已经存在),而是先判断已经存在的数据和新数据的差异,只有数据不同时才会把不相同的部分覆盖。
rsync复制命令
若rsync服务端SSH为标准端口,此时rsync使用方式如下:
XML/HTML代码
- # 将本机(10.7.2.230)上/root目录及目录下的文件同步到服务器10.7.2.231上的/root/backup目录下
- # 在10.7.2.230上执行以下命令:
- rsync -avuz /root root@192.168.19.100:/root/backup
若rsync服务端SSH为非标准端口,可通过rsync的-e参数进行端口指定(如ssh端口号为10022),使用方式如下:
XML/HTML代码
- # 将本机(10.7.2.230)上/root目录及目录下的文件同步到服务器10.7.2.231上的/root/backup目录下
- # 在10.7.2.230上执行以下命令:
- rsync -avuz /root -e 'ssh -p10022' root@10.7.2.231:/root/backup
常用参数
XML/HTML代码
- -v, --verbose详细模式输出
- -a, --archive归档模式,表示以递归方式传输文件,并保持所有文件属性不变
- -u, --update 仅仅进行更新,也就是跳过已经存在的目标位置,并且文件时间要晚于要备份的文件,不覆盖新的文件
- -z,--compress对备份的文件在传输时进行压缩处理
- --delete:删除那些DST中存在而在SRC中没有的文件
- --exclude=PATTERN: 指定排除不需要传输的文件模式
由于ssh方式不需要进行配置文件配置,只需要像scp一样执行命令即可,因此本文主要介绍该方式的使用,rsync-daemon方式可参考其他教程。
例如需求为:将10.7.2.230上的/root目录文件同步到10.7.2.231上的/root/backup下,可通过以下两种方式来实现:
将本地文件推送(上传)到远端
# 在本地服务器上执行
# rsync 命令参数 源文件目录 目的目录
rsync [OPTION] SRC [USER@]HOST:DEST
# 示例:在10.7.2.230上执行rsync,将/root目录文件同步到远程主机(10.7.2.231的/root/backup)上
rsync -avuz /root root@10.7.2.231:/root/backup
将远端文件拉(下载)到本地
# rsync 命令参数 源文件目录 目的目录
# rsync [OPTION] [USER@]HOST:SRC [DEST]
# 示例:主机10.7.2.231上执行rsync,将10.7.2.230上/root下的目录文件下载到主机10.7.2.231的/root/backup上
rsync -auvz root@10.7.2.230:/root /root/backup
#注意:
源目录加了斜线,效果就是将该目录下的内容传输到目标目录下
源目录不加斜线,效果就是将该目录传输到目标目录下
目标目录如果不存在,会自动创建目标目录
简单本机文件或者目录的复制
#复制文件
rsync -av /etc/passwd /tmp/1.txt
#复制目录
rsync -av test1/ test2/
小知识:
XML/HTML代码
- 创建ssh互信(免密登录服务器)
- #创建SSH密钥(一路回车)
- ssh-keygen -t rsa
- #复制SSH公钥到远程主机(需要输入远程主机SSH密码)
- ssh-copy-id -i .ssh/id_rsa.pub root@192.168.2.200
- #直接免密运行远程主机密码或者免密登录
- ssh 192.168.2.200 date
其他应用,比如上传rsync到esxi的bin目录,就可以直接备份虚拟机,或者使用群晖abb直接备份虚拟机文件到nas,原汁原味,和scp复制的一样,并且支持增量备份,定时备份。更多有趣的玩法需要自己去挖掘。rsync使用的是ssh协议端口,在esxi中除了开启ssh服务,还需要在网络--防火墙中允许sshclient服务通过。
附批量设置ssh免密登录服务器的脚本和方法:
建立文件 ssh.sh 设置属性可写
XML/HTML代码
- #!/bin/bash
- # 检查 ssh-keygen 是否已经存在密钥对
- if [ ! -f ~/.ssh/id_rsa ]; then
- echo "SSH key pair not found. Generating one..."
- ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
- else
- echo "SSH key pair already exists. Skipping generation."
- fi
- # 定义 host.txt 文件路径
- HOSTS_FILE="host.txt"
- # 检查 host.txt 文件是否存在
- if [ ! -f "$HOSTS_FILE" ]; then
- echo "Error: $HOSTS_FILE not found!"
- exit 1
- fi
- # 检查 host.txt 文件是否为空
- if [ ! -s "$HOSTS_FILE" ]; then
- echo "Error: $HOSTS_FILE is empty!"
- exit 1
- fi
- # 读取 host.txt 文件
- while IFS= read -r line; do
- # 跳过空行
- if [ -z "$line" ]; then
- continue
- fi
- # 解析行中的IP、端口、用户名和密码
- IFS=' ' read -r -a fields <<< "$line"
- HOST_PORT_USER_PASS="${fields[0]}"
- USER="${fields[1]}"
- PASS="${fields[2]}"
- IFS=':' read -r IP PORT <<< "$HOST_PORT_USER_PASS"
- # 默认端口为22
- if [ -z "$PORT" ]; then
- PORT=22
- fi
- echo "Processing $USER@$IP:$PORT"
- # 使用sshpass和ssh-copy-id复制公钥
- sshpass -p $PASS ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no -p $PORT $USER@$IP
- if [ $? -ne 0 ]; then
- echo "Error: Failed to copy SSH key to $USER@$IP:$PORT"
- continue
- fi
- # 检查公钥是否成功上传
- sshpass -p $PASS ssh -o StrictHostKeyChecking=no -p $PORT $USER@$IP "grep -q '$(cat ~/.ssh/id_rsa.pub)' ~/.ssh/authorized_keys && echo 'Key successfully added to $USER@$IP' || echo 'Failed to add key to $USER@$IP'"
- if [ $? -ne 0 ]; then
- echo "Error: SSH connection to $USER@$IP:$PORT failed"
- fi
- done < "$HOSTS_FILE"
- echo "SSH key copied to all hosts."
XML/HTML代码
- 192.168.0.101:22 root password123
- 192.168.0.102 root password456
- 192.168.0.103:2222 user password789