我的情况如下:
- 同一数据中心内的两台专用服务器,它们之间有千兆以太网。
- 两台专用服务器都启动到基于 Debian Squeeze 的救援环境,并添加了额外的工具和实用程序。还有充足的 tmp 空间(两台机器都有 32GB 的 RAM)用于下载软件、安装软件包和/或根据需要进行编译。
- 两个专用服务器均大约3TB的可用空间。
- “源”服务器在硬件 RAID-10 中有 4 x 1.5TB 磁盘,并带有 Adaptec 4 端口控制器。
- “目标”服务器拥有 2 个 3TB 磁盘,采用硬件 RAID-1 结构,配备 Adaptec 2 端口控制器 - 与其他服务器属于同一代,但端口数量不同。
- 可用块的数量
/dev/sda
相差不到 10 MB,但是目标服务器的阵列由于某种原因小了几兆。 - 两个 RAID 阵列都配置为使用所有组成磁盘的整个磁盘表面来创建一个单一 RAID 卷。
- 操作系统以 MBR 模式启动;不使用 UEFI 启动。
我想做的事:
- 在块层,将整个操作系统映像(仅包含 GPT 分区表、/boot 分区和 / 分区中的 GRUB2 引导加载程序)从“源”服务器复制到“目标”服务器。
- 如果可能的话,复制应“实时”进行:这意味着我没有足够的空间在目标端存储磁盘映像的正确文件,除非我将磁盘映像解压到硬盘上复制正在进行。服务器之间的千兆以太网连接足够可靠,我对此感到满意,当然,我会
fsck
在两端(源和目标)运行以验证传输前后文件系统是否正常。 - 如果可能的话,不通过网络传输每个分区中的组成文件系统未使用的块(所有分区都格式化为 ext4)。这是因为“源”磁盘的 50% 以上是分区中的可用空间
/
。 - 调整分区的大小
/
,以便在复制时,其大小能够调整到与目标磁盘略小一点的尺寸相适应。 - 复制成功后,安装每个卷并修复对静态 IP 的引用以反映新服务器的 IP。(无需任何进一步帮助即可完成此操作)
我的问题:
- 我是不是该第一的计算每个服务器上的大小差异(以字节为单位)
/dev/sda
,然后使用非破坏性地减小分区e2resize
的大小/
在源端以便它能适合目的地的空间? - 我应该
dd
在原始块设备上运行,/dev/sda
从源到目标(通过ssh
),或者我应该在目标上创建一个等效的分区布局并dd
在每个分区上运行分割? 请注意,一次处理一个分区会给我带来引导加载程序的问题,但如果我不一次处理一个分区,则dd
需要知道在写入目标可以容纳的字节数后停止传输数据(希望这将“关闭”最后一个块上分区的最末端/
,该块在逻辑上位于源分区布局中所有其他分区的“右侧”)。
一些杂项细节:
- 源箱上的主机操作系统是 Ubuntu Server 12.04,运行多个 OpenVZ 客户机
- 由于两个盒子都启动到了救援系统中,因此可以直接访问磁盘,而无需期望正在运行的操作系统对底层数据进行任何更改。
答案1
这虽然有些混乱,但是却可行。
我在此假设/
是开启/dev/sda3
并且/boot
是开启/dev/sda1
。
将旧服务器上的文件系统缩小到其尽可能的最小大小。
oldserver # resize2fs -M /dev/sda3
/boot
使用相同大小、交换空间和新/
分区(以及您需要的任何其他内容)对新服务器的磁盘进行分区。newserver # parted /dev/sda
复制
/
和/boot
文件系统。oldserver # dd if=/dev/sda1 | ssh root@newserver "dd of=/dev/sda1" oldserver # dd if=/dev/sda3 | ssh root@newserver "dd of=/dev/sda3"
由于新服务器上的分区会比旧服务器上的分区略小,因此您将
No space left on device
在最后收到一条虚假消息。但是,由于您在步骤 1 中缩小了文件系统,因此这并不重要。将新服务器上的文件系统大小调整为分区的大小。
newserver # resize2fs /dev/sda3
在新磁盘上安装 GRUB。
newserver # mount /dev/sda3 /mnt newserver # mount /dev/sda1 /mnt/boot newserver # mount -o bind /dev /mnt/dev newserver # mount -o proc proc /mnt/proc newserver # chroot /mnt /bin/bash newserver(chroot) # grub-install /dev/sda newserver(chroot) # exit
完成其余的修复(IP 地址等)。
您也许可以找到一种方法来避免复制分区的可用空间,但这可能需要比复制所有内容更长的时间来研究......
答案2
我mkfs
在新服务器上重新创建文件系统,然后rsync
从旧服务器上重新创建文件系统。这种方法可重新启动、一致,并且每个文件都易于单独验证。如果您要丢弃文件系统中未使用的部分(而不是法医副本),我认为没有理由不使用此方法。您必须重新运行 GRUB,但这应该不是什么难事。
解释文件系统感知的原始副本需要花费我一些时间,因此,除非您评论为什么我的 rsync 解决方案不起作用,否则我就不打字了。
答案3
如果您真的想在块设备级别传输数据,我可以想到一个非常有用的技巧,我用它来迁移服务器,同时最大限度地减少停机时间。
事实是,您可以在源服务器上创建一个降级镜像,其中数据分区是镜像中唯一活动的一半,然后通过第二台服务器导出目标分区群攻(我假设您的两台服务器都在同一个广播域中)。然后在源服务器上,您将网络块设备连接到降级镜像,以便它开始重建。等到重建完成,停止镜像,删除 AOE 导出的设备,您就没问题了。
接下来是更多细节(我会尽量简短)。
成分:
mdadm
以及其建造模式(没有元数据的临时镜像);vblade
用于将块设备导出为AOE网络设备;aoe-tools
用于导入 AOE 网络块设备。
您必须在目标服务器上创建分区表,然后缩小源分区以使其适合目标。您可以轻松地将 GRUB 安装到新的 MBR;在新建的分区表上同步分区不太容易出错。
在接收端,您必须使用vblade
工具导出您的分区,在源服务器上,安装后您就可以看到导出的设备aoe-tools
(运行aoe-discover
然后查看/dev/ether/
设备)。
然后你应该在源服务器上建立 raid1 设备来源驾驶:
mdadm --build /dev/md0 -n2 -l1 --force /dev/sda
此后您可以检查新建的镜像:
mdadm --detail /dev/md0
cat /proc/mdstat
此时您可以安全地将导出的目标分区附加到此镜像:
mdadm /dev/md0 --add /dev/ether/eX.Y
然后只需观察同步进度:
watch -n5 cat /proc/mdstat
同步完成后,只需停止镜像:mdadm --stop /dev/md0
在源服务器上,终止vblade
目标服务器上的进程,在第二台服务器上安装 GRUB,更改 IP 地址等。
实际上,使用此技巧可以几乎实时地在机器之间移动服务器,只需停机即可重新启动同步的机器。
出于性能原因,我还建议您增加链路的 MTU(或者,如果可能,设置启用巨型帧的单独 VLAN)。
请注意,你也可以使用类似nbd-server
/ nbd-client
(或者甚至是 iSCSI,如果你想要更粗暴的话)作为 AOE 的替代方案,但是 AOE(vblade
+ aoe-tools
)有一个非常界面简单,性能出色(无 TCP/IP 开销),