使用最少停机时间虚拟化服务器
在科技新闻中,您不必看得太远就能发现虚拟化已成为一件大事。毕竟,计算机不断变得更快更强大,随着它们的发展,运行在其上的服务通常使用更少的总体资源。最重要的是,现代服务器通常只需要其前辈一小部分的电力和冷却。通过虚拟化,您可以节省电力并更有效地利用服务器资源,并且您可以快速创建服务器,而无需等待部件到达。
尽管有些人从头开始,从零开始创建全新的虚拟服务器来取代旧的物理机器,但您可能根本没有额外的时间来投资,以便彻底转向新版本的 Linux 以及全新的软件包。在许多情况下,创建物理服务器的虚拟克隆并保持所有文件和服务相同更有意义。如果您想走这条路,如果您可以处理无限的停机时间,您可以使用许多不同的方法,但是如果您想将停机时间和总体中断降至最低(谁不想呢?),我使用了一个相当简单的流程,将大量服务器迁移到虚拟机,平均停机时间约为 30 分钟——完全在大多数可接受的维护窗口内。
在我深入实际步骤之前,我应该提到这种方法的一些限制。首先,此方法的设计和测试旨在与 VMware 虚拟化一起使用,特别是与其企业服务器产品一起使用(尽管它也可以与他们的免费服务器产品一起正常工作)。VMware 非常适合此过程,因为它不需要我修改当前的 Linux 内核来虚拟化它——当您想要虚拟化旧服务器时,这并非总是可能的。话虽如此,这些步骤也适用于可以使用未修改的 Linux 内核的其他虚拟机技术。其次,此过程已经过测试,并且针对类似 Red Hat 的发行版(Red Hat、CentOS 等),但稍作调整,我稍后会讨论,它也适用于其他发行版。最后,您此过程所需的实际停机时间可能会与我的结果有所不同,尤其是在您首次测试每个步骤时。具有大型或慢速磁盘的服务器,尤其是那些频繁更改大量数据的服务器,可能需要更长的时间来同步。
除了这些免责声明之外,公平地说,还应指出此方法的一些好处
您可以对实时服务器执行大部分迁移工作。
标准 Linux 工具用于同步和其他更改。
该过程可保护您的网络免受两台服务器同时出现的影响。
您可以安全地将旧服务器留在网络上并访问其文件,同时用户使用新的虚拟机。
现在免责声明已经说完,让我用几个一般步骤总结一下这个过程。首先,创建一个新的虚拟机来替换物理主机。然后,使用救援 CD 启动到虚拟机中并对磁盘进行分区。接下来,执行从实时物理服务器到新虚拟机的文件主同步。关闭您的物理机器并使用救援 CD 重新启动,并执行来自离线服务器的最终同步。之后,更改虚拟机上的启动设置以适应其新环境,然后重新启动到您的新虚拟机中。
要开始使用,首先您必须创建一个虚拟机容器来替换您的物理机器。如果您使用 VMware Server 与 Virtual Infrastructure 3,则具体步骤会有所不同,但最终,您想要做的是创建一个主要匹配您的物理机器规格的机器。规格不必完全匹配,实际上有很多充分的理由让您想要稍微调整设置。例如,如果您的服务器有 2GB 的 RAM,但您注意到它实际上只需要 1GB,那么现在将是一个很好的机会来更改它。如果您的服务器开始耗尽存储空间,那么现在是增加它的好时机。但是,如果您的物理服务器具有 32 位或 64 位处理器,请确保虚拟机与之匹配。此外,如果可能,请确保您向 VMware 报告的操作系统版本与您的实际操作系统相匹配。例如,如果您的服务器运行 RHEL 3,请不要告诉 VMware 它运行 RHEL 4。您要确保操作系统将具有 VMware 提供的虚拟设备的驱动程序,特别是磁盘子系统的驱动程序。例如,由于 RHEL 4 从基本操作系统中删除了 BusLogic SCSI 模块(VMware 常用的虚拟 SCSI 设备以及 LSI Logic 虚拟 SCSI 设备),我遇到了许多麻烦。
在您设置虚拟机的规格后,编辑 CD-ROM 设备,使其指向 VMware 服务器中的实际救援 CD 或 ISO。我更喜欢 Knoppix 用于此过程,但任何 Live CD 都应该可以工作,只要它具有 rsync 和 chroot 工具、SSH 服务器以及足够的模块支持来访问物理机和虚拟机上的磁盘。现在,将虚拟机启动到救援 CD 中。您需要做的所有事情都通过命令行完成,因此在 Knoppix 下,键入knoppix 2在 boot: 提示符下,绕过 GUI 并直接进入命令行。
在 Knoppix 启动后,您需要为此虚拟机分区、格式化和挂载新分区。使用命令行中的 fdisk 或 cfdisk 创建分区以匹配您的物理服务器。同样,您不必完全匹配分区大小,只要有足够的空间来存储物理服务器中的所有文件即可。对于此示例,我将有一个物理服务器,它具有一个 SCSI 驱动器 (/dev/sda),其中包含三个分区:/dev/sda1 用于根目录,/dev/sda2 用于交换分区,/dev/sda3 用于 /home。在虚拟机上创建相同的分区后,使用与物理机上相同的文件系统格式化它们,为它们创建挂载点,然后挂载它们
$ sudo mkfs -t ext3 /dev/sda1 $ sudo mkfs -t ext3 /dev/sda3 $ sudo mkswap /dev/sda2 $ sudo mkdir -p /mnt/sda1 /mnt/sda3 $ sudo mount /dev/sda1 /mnt/sda1 $ sudo mount /dev/sda3 /mnt/sda3
现在您已经创建并挂载了分区,您就可以进行首次同步了。为了使其工作,您的虚拟机必须具有网络访问权限,特别是,它需要能够访问物理机上的 SSH。默认情况下,如果可用,Knoppix 将尝试获取 DHCP 租约,但否则,如果您的救援光盘无法连接到网络,则您需要进行必要的更改以使其能够连接。此虚拟化过程通过同步文件两次来减少停机时间——一次在物理服务器运行时,一次在物理服务器离线后。这里的想法是,大多数服务器上的大多数文件都保持不变,至少在一两天内是这样。如果您在服务器在线时执行大部分文件同步,那么当您将其离线时,最终同步可以更快地发生。
我使用 rsync 进行同步,为了使其工作,您需要允许(至少暂时)在物理机上发生 root SSH 登录。如果它被禁用,请编辑 /etc/ssh/sshd_config 并更改PermitRootLogin no为PermitRootLogin yes,然后重新启动 sshd。否则,rsync 将很难复制系统上的所有文件。您将为物理服务器上的每个分区运行一个 rsync 命令,因此在本例中,这将生成两个 rsync 命令
$ sudo rsync -avx --numeric-ids ↪--progress physicalhost:/ /mnt/sda1/ $ sudo rsync -avx --numeric-ids ↪--progress physicalhost:/home/ /mnt/sda3/
我在此处使用的 rsync 选项是经过非常慎重选择的,因此值得了解它们各自的作用。-a 选项设置“存档模式”,这实际上打开了许多 rsync 选项,这些选项保留文件所有权和权限以及其他设置。-v 选项使 rsync 提供更多关于其正在执行的操作的输出,而 --progress 参数显示进度条,以便您可以了解 rsync 将花费多长时间。另外两个参数相当重要,如果您不经常使用 rsync,您可能不会经常遇到它们。-x 参数告诉 rsync 坚持一个文件系统。这非常重要,尤其是在您备份 / 分区时;否则,rsync 会愉快地遍历到 /home 或您拥有的任何其他分区,并将它们全部复制到您的本地 /mnt/sda1 挂载点中,这可能没有足够的空间来容纳所有内容。--numeric-ids 参数根据目标文件上的数字 ID 而不是匹配的用户或组名来设置文件权限。这很重要,因为 Knoppix CD 很可能具有与您的服务器不同的用户和组 ID 映射。
在这些 rsync 命令完成后,您就可以将物理服务器离线了。如果您确实需要为物理服务器安排维护窗口,只需让虚拟机在其当前状态下运行,然后在您准备好将物理机器离线时继续执行下一步。如果距离您的维护窗口还有几天的时间,您可能需要在您接近维护窗口时再次运行上述 rsync 命令,只是为了使最终的离线 rsync 发生得更快。
在物理服务器上
最后一次同步发生在物理服务器完全离线时,因此您可以确保没有其他文件更改您。为此,只需将 Knoppix CD(或您首选的救援 CD)带到物理机并从中启动。您运行的所有命令都将来自命令行,因此您也可以在此处启动到 Knoppix 的仅终端模式。当 Knoppix 启动时,它应该会自动检测您的分区并在 /mnt 下为它们创建挂载点,但如果它没有这样做,只需使用 mkdir 命令手动创建它们即可。Knoppix 不会在启动时自动挂载分区,因此您需要手动执行此操作。在本例中,我的物理服务器有两个分区要挂载
$ sudo mount /dev/sda1 /mnt/sda1 $ sudo mount /dev/sda3 /mnt/sda3
现在我需要为 root Knoppix 用户设置密码,然后在该机器上启动 SSH 服务器,以便我可以运行 rsync
$ sudo passwd $ sudo /etc/init.d/ssh start
请记住,因为我将此机器启动到 Knoppix 中,所以它很可能通过 DHCP 获取了不同的 IP 地址。键入/sbin/ifconfig以检查机器当前具有哪个 IP 地址,因为您将在最终 rsync 中需要它。
在虚拟机服务器上
您现在可以从虚拟机服务器启动最终同步。这些命令与您之前使用的命令非常相似,除了这次,我添加了 --delete 选项,以便 rsync 将删除自上次同步以来从物理机删除的虚拟机上的任何文件。另请注意,由于物理服务器现在已启动到 Knoppix 中,因此我必须更改目录路径和远程主机的 IP 地址,因为自从我启动到 Knoppix 以来,它们已更改
$ sudo rsync -avx --numeric-ids --progress ↪--delete 192.168.1.150:/mnt/sda1/ /mnt/sda1/ $ sudo rsync -avx --numeric-ids --progress ↪--delete 192.168.1.150:/mnt/sda3/ /mnt/sda3/
这些命令可能需要很长时间或很短的时间,具体取决于自上次运行 rsync 以来有多少文件发生了更改。一旦完成,您就可以在将虚拟机投入使用之前对其执行最后的润色。
您需要在 chroot 环境中进行的第一个更改是恢复您的引导加载程序。如果您使用 GRUB,请查看 /boot/grub/menu.lst 或 /boot/grub/grub.conf。如果您使用 LILO,请查看 /etc/lilo.conf。检查任何可能已更改的设备。特别是,如果您从 IDE 切换到 SCSI 设备,从 RAID 切换到非 RAID 或更改了根分区顺序,请务必在此处进行更改以反映这一点。接下来,如果您使用 GRUB,请键入
# grub-install /dev/sda
将 /dev/sda 更改为与您将从中启动的主磁盘设备匹配。如果您使用 LILO,请键入
# /sbin/lilo
在安装引导加载程序后,检查 /etc/fstab 并确认您在引导加载程序配置文件中所做的任何驱动器、分区或设备更改也已在此处更改。
现在许多服务器都使用 initrd 文件来加载对于启动过程至关重要但并不一定适合内核映像的模块。通常,此 initrd 文件仅包含适合您硬件的模块,因此当您切换到新硬件时,例如 VMware 的虚拟 SCSI 控制器的情况,您需要创建一个新的 initrd,其中包含这些新模块。
在 Red Hat 系统上,编辑 /etc/modules.conf 或 /etc/modprobe.conf(对于 RHEL 4),并删除您在那里找到的对 scsi_hostadapter 的任何引用。如果您将虚拟机配置为使用 VMware 的虚拟 BusLogic SCSI 控制器,请将这些引用替换为以下内容
alias scsi_hostadapter BusLogic
如果您选择了 VMware 的 LSI Logic SCSI 控制器,请改为添加以下行
alias scsi_hostadapter mptbase alias scsi_hostadapter1 mptscsih
显然,这些模块特定于 VMware 虚拟化,因此如果您想尝试将其用于其他虚拟化技术,您将需要查找它使用的 SCSI 模块,并确保在此处引用它们。
现在,您可以创建一个新的 initrd。从您的 /boot/grub/menu.lst、/boot/grub/grub.conf 或 /etc/lilo.conf 文件中找到您的服务器上次使用的 initrd 的位置,然后将其移开,以便您可以安全地创建一个新的 initrd。然后,使用要创建的 initrd 文件的路径和当前内核的名称运行 mkinitrd。对于我的示例服务器,我正在使用 Red Hat 2.4.21-32.0.1.ELsmp 内核,因此我将键入
# mv /boot/initrd-2.4.21-32.0.1.ELsmp.img ↪/boot/initrd-2.4.21-32.0.1.ELsmp.img.bak # mkinitrd /boot/initrd-2.4.21-32-0.1.ELsmp ↪2.4.21-32-0.1.ELsmp
正如我之前所说,这是 Red Hat 用于创建 initrd 文件的方法。不幸的是,不同的发行版使用不同的方法。例如,Debian 的 mkinitrd 将配置文件存储在 /etc/mkinitrd 下,并且 mkinitrd 命令使用略有不同的选项,因此您可能需要做一些额外的研究来为您的服务器发行版创建一个新的 initrd。
此时,您可以重新启动虚拟机。确认您的物理机不再具有其原始 IP 地址,或者,为了安全起见,只需将其关闭即可。如果您的服务器运行硬件配置服务(如 kudzu),则很可能在启动时会提示您,因为它检测到服务器硬件发生了更改。请务必为它提到的任何旧 SCSI 或网络硬件选择“保留配置”,并为您提到的任何新 SCSI 或网络硬件选择“忽略”;但是,如果提示您,您可以安全地删除旧的视频、声音、USB 和类似硬件。
一旦机器完全启动,请确认所有系统服务都已启动,并且您已连接到网络。我注意到在某些 Red Hat 系统上,网卡的 MAC 地址已硬编码到配置文件中,并且由于它在新虚拟硬件上已更改,因此网络将不会恢复。在这种情况下,只需编辑 /etc/sysconfig/network-scripts/ 下的网卡配置文件(通常为 ifcfg-eth0),然后删除对 MAC 地址的引用或将其更改为反映新的 MAC 地址。然后,重新启动网络服务。
在尝试在实际生产机器上执行此操作之前,请在几台测试机器上练习此过程,以确保您已掌握特定网络的所有步骤。没有什么比在物理服务器关闭且您的维护窗口正在流逝时,争先恐后地修复虚拟机上奇怪的 initrd 问题更糟糕的了。您会发现,您执行这些迁移的次数越多,您就可以越快地完成它们——您甚至可能能够错开它们并同时完成几个。
Kyle Rankin 是旧金山湾区的高级系统管理员,也是多本书的作者,包括 O'Reilly Media 的 Knoppix Hacks 和 Ubuntu Hacks。他目前是 North Bay Linux 用户组的主席。