通过LAN迁移原始磁盘映像

这是我的情况:

  • 两个专用服务器位于同一个数据中心,其间有千兆以太网。
  • 两台专用服务器都启动到基于Debian Squeeze的救援环境中,并增加了额外的工具和实用程序。 还有足够的tmp空间(两个盒子上有32GB的RAM)用于下载软件,安装软件包和/或根据需要进行编译。
  • 两个专用服务器都有大约 3TB的可用空间。
  • “源”服务器在具有Adaptec 4端口控制器的硬件RAID-10中具有4个1.5TB磁盘。
  • “目标”服务器在硬件RAID-1中具有2个3TB磁盘,带有一个Adaptec 2端口控制器 – 与另一个端口相同,但端口数量不同。
  • /dev/sda上可用块的数量相差不到10 MB,但目标服务器的数组由于某种原因而缩小了几个兆。
  • 两个RAIDarrays都configuration为使用所有组成磁盘的整个磁盘表面来创build一个单个RAID卷。
  • 操作系统以MBR模式启动; 不使用UEFI引导。

我想要做什么:

  • 在块层将整个操作系统镜像(这只包含GPT分区表中的GRUB2引导加载程序,/ boot分区和/分区)从“源”服务器复制到“目标”服务器。
  • 如果可能的话 ,副本应该是“live”:这意味着我没有足够的空间在目标端存储适当的磁盘映像文件,除非我将磁盘映像作为副本解包到硬盘上正在发生 。 服务器之间的千兆位以太网连接足够可靠,我对此感到满意,当然,我将在两端(源和目标)上运行fsck ,以在传输之前和之后validation文件系统是否正常。
  • 如果可能的话 ,不要通过networking传输块,每个分区中的组成文件系统不使用这些块(所有分区的格式都是ext4)。 这是因为超过50%的“源”磁盘是/分区中的可用空间。
  • 调整/分区的大小,以便在复制时resize,使其大小适合目标磁盘的大小。
  • 复制成功后,装入每个卷并修复对静态IP的引用,以反映新服务器的IP。 (没有任何进一步的帮助可以做到这一点)

我的问题:

  • 我应该首先计算每台服务器上/dev/sda大小之间的差异(以字节为单位),然后使用e2resize非破坏性地减小源端 /分区的大小,以便它适合目的地方?
  • 我应该在原始块设备上运行dd/dev/sda从源到目标(通过ssh ), 还是应该在目标上创build一个等效的分区布局,并在每个分区上运行dd ? 请注意,一次处理分区会导致引导加载程序的问题,但是如果我不一次一个分区,那么dd需要知道一旦写入了足够多的字节数就可以停止传输数据保持(希望能够“closures”最后一个块的/分区的最后一个,这在逻辑上是在源的分区布局中的所有其他分区的右边)。

一些杂项。 细节:

  • 源盒上的主机操作系统是运行多个OpenVZ客户的Ubuntu Server 12.04
  • 由于两个盒子都被引导进入救援,所以直接磁盘访问是可能的,而不需要由正在运行的操作系统改变底层数据。

这是混乱的,但可行的。

我在这里假定//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末尾收到虚假的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地址等)。

你也许可以find避免复制分区空闲空间的方法,但是可能需要更长的时间才能完成复制。

我会在新的服务器上创build新的文件系统,然后从旧的服务器进行rsync 。 这是可重新启动的,一致的,每个文件都可以单独validation。 在丢弃文件系统中未使用的部分(而不是法医副本)的地方,我没有看到任何不使用此方法的理由。 你将不得不重新运行GRUB,但这不应该是一个挑战。

解释一个文件系统感知的原始副本将花费我一段时间,所以除非你对为什么我的rsync解决scheme不起作用发表评论,否则我会让自己打字。

如果你真的想要在块设备级别传输数据,我可以想到一个非常有用的技巧,我用来以最小的停机时间来迁移服务器。

问题是,你可以在源服务器上创build一个降级镜像,数据分区是镜像的唯一活动部分,然后通过AOE (我假设你的服务器都在同一个广播域中)从第二个服务器导出目标分区。 在源服务器,然后将networking块设备连接到降级镜像,以便开始重build。 等到重build完成,停止镜像,删除AOE导出的设备,你没事。

稍后详细一点(我会尽量保持简短)。

组件:

  • mdadm及其构build模式(不带元数据的临时镜像);
  • 用于导出块设备的vblade作为AOEnetworking设备;
  • 用于导入AOEnetworking块设备的aoe-tools

您必须在目标服务器上创build分区表,然后缩小源分区以适应目标。 您可以轻松地将GRUB安装到新的MBR; 只是在新创build的分区表上同步分区是不太容易出错的。

在接收端,你必须用vblade工具导出你的分区,在源服务器上,你可以在安装aoe-tools (运行aoe-discover然后查看/dev/ether/ for devices)之后看到导出的设备。

那么你应该在你的驱动器上的源服务器上构buildraid1设备:

 mdadm --build /dev/md0 -n2 -l1 --force /dev/sda 

之后你可以检查新build的镜子:

 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地址等。

实际上,有了这个技巧,就有可能在几乎活动的服务器之间移动服务器,而停机只是为了重启同步盒子。


出于性能原因,我还build议您增加链路的MTU(如果可能的话,build立一个单独的带有巨型帧的VLAN)。

注意,你也可以使用像nbd-server / nbd-client (甚至是iSCSI,如果你想粗略的)作为AOE的替代品,但是AOE( vblade + aoe-tools )具有非常简单的界面和很好的性能(没有TCP / IP开销),