通过 LAN 迁移原始磁盘映像

通过 LAN 迁移原始磁盘映像

我的情况如下:

  • 同一数据中心内的两台专用服务器,它们之间有千兆以太网。
  • 两台专用服务器都启动到基于 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

  1. 将旧服务器上的文件系统缩小到其尽可能的最小大小。

    oldserver # resize2fs -M /dev/sda3
    
  2. /boot使用相同大小、交换空间和新/分区(以及您需要的任何其他内容)对新服务器的磁盘进行分区。

    newserver # parted /dev/sda
    
  3. 复制//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 中缩小了文件系统,因此这并不重要。

  4. 将新服务器上的文件系统大小调整为分区的大小。

    newserver # resize2fs /dev/sda3
    
  5. 在新磁盘上安装 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
    
  6. 完成其余的修复(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 开销),

相关内容