documentation.suse.com / SUSE Linux Enterprise Server 文档 / 虚拟化指南 / 使用 libvirt 管理虚拟机 / 迁移 VM Guest
适用范围 SUSE Linux Enterprise Server 15 SP7

17 迁移 VM Guest

虚拟化的主要优势之一是 VM Guest 可移植。当 VM 主机服务器需要维护时,或者当该主机过载时,可以轻松将 Guest 迁移到另一台 VM 主机服务器。KVM 和 Xen 甚至支持实时迁移,在此期间,VM Guest 仍然可用。

17.1 迁移类型

根据所需场景,您可以通过三种方式迁移虚拟机 (VM)。

实时迁移

源 VM 在将配置和内存传输至目标主机期间持续运行。传输完成后,源 VM 会暂停,目标虚拟机恢复运行。

实时迁移适用于需要保持在线不停机的 VM。

注意
注意

I/O 负载较重或内存页写入频繁的 VM 很难进行实时迁移。此类情况建议采用非实时迁移或离线迁移。

非实时迁移

源 VM 将被暂停,其配置和内存将传输至目标主机。随后目标 VM 恢复运行。

非实时迁移相比实时迁移更为可靠,但会造成 VM 中断。如果能接受停机,对于难以实施实时迁移的 VM,可采用非实时迁移方案。

离线迁移

VM 定义会被传输至目标主机。源 VM 不会被停止,目标 VM 也不会恢复运行。

离线迁移适用于迁移处于非活动状态的 VM。

重要
重要

采用离线迁移时,必须使用 --persistent 选项。

17.2 迁移要求

要成功将 VM Guest 迁移到另一台 VM 主机服务器,需符合以下要求:

  • 源和目标系统必须采用相同的体系结构。

  • 两台计算机必须都能访问存储设备,例如通过 NFS 或 iSCSI。有关详细信息,请访问 第 13 章 “高级存储主题

    在迁移期间连接的 CD-ROM 或软盘映像也需要符合此要求。不过,您可以按照第 14.11 节 “使用虚拟机管理器弹出和更换软盘或 CD/DVD-ROM 媒体”中所述在迁移之前断开其连接。

  • 这两台 VM 主机服务器上都需要运行 libvirtd,并且您必须能够打开从目标主机到源主机(或反向)的远程 libvirt 连接。有关细节,请参见第 12.3 节 “配置远程连接”

  • 如果目标主机上在运行防火墙,则需要打开端口以允许迁移。如果您在迁移期间不指定端口,libvirt 将从 49152:49215 范围内选择一个端口。确保在目标主机上的防火墙中打开此端口范围(建议)或所选的专用端口。

  • 源计算机和目标计算机应位于网络上的同一子网中,否则迁移后网络功能无法正常工作。

  • 所有参与迁移的 VM 主机服务器所用 qemu 用户的 UID 必须相同,并且使用的 kvm、qemu 和 libvirt 组的 GID 必须相同。

  • 目标主机上不能存在正在运行或已暂停的同名 VM Guest。如果存在已关闭的同名计算机,其配置将被覆盖。

  • 迁移 VM Guest 时支持除主机 CPU 型号以外的所有 CPU 型号。

  • SATA 类型地磁盘设备无法迁移。

  • 文件系统直通功能不可迁移。

  • 需在 VM 主机服务器和 VM Guest 上安装适当的计时功能。请参见第 20 章 “VM Guest 时钟设置

  • 无法将物理设备从主机迁移到 Guest。目前,在使用具有 PCI 直通或 SR-IOV 功能的设备时,不支持实时迁移。如果需要支持实时迁移,请使用软件虚拟化(半虚拟化或全虚拟化)。

  • 缓存模式设置是重要的迁移设置。请参见第 19.6 节 “缓存模式和实时迁移”

  • 不支持向后迁移(例如,从 SLES 15 SP2 迁移到 15 SP1)。

  • SUSE 致力于支持将 VM Guest 从运行 LTSS 所涵盖的服务包的 VM 主机服务器,迁移到运行同一 SLES 主要版本中更新的服务包的 VM 主机服务器。例如,将 VM Guest 从 SLES 12 SP2 主机迁移到 SLES 12 SP5 主机。对于从 LTSS 迁移到更新的服务包的场景,SUSE 只会执行极简单的测试,建议在尝试迁移关键 VM Guest 之前执行全面的现场测试。

  • 在两台主机上,映像目录应位于同一路径。

  • 所有主机的微代码级别(尤其是 Spectre 微代码更新)应该相同。在所有主机上安装 SUSE Linux Enterprise Server 的最新更新即可实现此目的。

17.3 使用虚拟机管理器进行实时迁移

使用虚拟机管理器迁移 VM Guest 时,在哪台计算机上启动虚拟机管理器并不重要。您可以在源主机或目标主机上启动虚拟机管理器,甚至可以在这两台之外的主机上启动。对于后一种情况,您需要能够同时与目标主机和源主机建立远程连接。

  1. 启动虚拟机管理器,并与目标主机或源主机建立连接。如果虚拟机管理器不是在目标主机或源主机上启动的,则需要与这两台主机都建立连接。

  2. 右键单击要迁移的 VM Guest,然后选择迁移。确保该 Guest 正在运行或已暂停 — 关闭的 Guest 无法迁移。

    提示
    提示:提高迁移速度

    要提高迁移速度,请暂停 VM Guest。这相当于 第 17.1 节 “迁移类型” 中介绍的非实时迁移

  3. 为 VM Guest 选择一个新主机。如果所需的目标主机未显示,请确保您已连接到该主机。

    要更改用于连接到远程主机的默认选项,请在连接下设置模式,以及目标主机的地址(IP 地址或主机名)和端口。如果指定端口,还必须指定地址

    高级选项下,选择迁移是永久性的(默认设置)还是暂时性的(使用临时迁移)。

    此外我们还提供了一个选项允许不安全的迁移,它允许在不禁用 VM 主机服务器缓存的情况下进行迁移。这样可以加速迁移,但仅当当前配置能够在不使用 cache="none"/0_DIRECT 的情况下提供一致的 VM Guest 存储信息时,此选项才起作用。

    注意
    注意:带宽选项

    在最近的虚拟机管理器版本中,去除了用于设置迁移带宽的选项。要设置特定的带宽,请改用 virsh

  4. 要执行迁移,请单击迁移

    迁移完成后,迁移窗口将会关闭,该 VM Guest 随即列在新主机的虚拟机管理器窗口中。原始 VM Guest 仍可在源主机上使用(处于关机状态)。

17.4 使用 virsh 进行迁移

要使用 virsh migrate 迁移 VM Guest,您需要能够直接访问或者通过外壳远程访问 VM 主机服务器,因为命令需在主机上运行。迁移命令如下所示:

> virsh migrate [OPTIONS] VM_ID_or_NAME CONNECTION_URI [--migrateuri tcp://REMOTE_HOST:PORT]

下面列出了最重要的选项。有关完整列表,请参见 virsh help migrate

--live

执行实时迁移。如果未指定此选项,Guest 将会在迁移期间暂停(非实时迁移)。

--suspend

在实时或非实时迁移期间,暂停目标主机上的 VM。

--persistent

在目标主机上保留迁移后的 VM。如果不使用此选项,当该 VM 关闭时,它不会出现在 virsh list --all 报告的域列表中。

--undefinesource

如果指定此选项,成功迁移后,将删除源主机上的 VM Guest 定义,但不会删除挂接到此 Guest 的虚拟磁盘。

--parallel --parallel-connections NUM_OF_CONNECTIONS

当单个迁移线程无法使源主机与目标主机之间的网络链接饱和时,可以使用并行迁移来提高迁移数据吞吐量。在具备 40 GB 网络接口的主机上,可能需要四个迁移线程才能使链接饱和。使用并行迁移可以缩短迁移大内存 VM 所需的时间。

以下示例使用 mercury.example.com 作为源系统,使用 jupiter.example.com 作为目标系统;VM Guest 的名称为 opensuse131,ID 为 37

使用默认参数进行非实时迁移
> virsh migrate 37 qemu+ssh://tux@jupiter.example.com/system
使用默认参数进行瞬态实时迁移
> virsh migrate --live opensuse131 qemu+ssh://tux@jupiter.example.com/system
永久性实时迁移;删除源上的 VM 定义
> virsh migrate --live --persistent --undefinesource 37 \
qemu+tls://tux@jupiter.example.com/system
非实时迁移,使用端口 49152
> virsh migrate opensuse131 qemu+ssh://tux@jupiter.example.com/system \
--migrateuri tcp://@jupiter.example.com:49152
实时迁移,转移所有已使用的存储资源
> virsh migrate --live --persistent --copy-storage-all \
opensuse156 qemu+ssh://tux@jupiter.example.com/system
重要
重要

使用 --copy-storage-all 选项迁移 VM 的存储资源时,存储资源必须位于 libvirt 的存储池中。目标存储池必须与源存储池类型相同、名称一致。

要获取源存储池的 XML 表示,请使用以下命令:

> sudo virsh pool-dumpxml EXAMPLE_VM > EXAMPLE_POOL.xml

要在目标主机上创建并启动该存储池,请将其 XML 文件复制到目标主机,并执行以下命令:

> sudo virsh pool-define EXAMPLE_POOL.xml
> sudo virsh pool-start EXAMPLE_VM
注意
注意:瞬态迁移与永久性迁移的比较

默认情况下,virsh migrate 会为目标主机上的 VM Guest 创建临时(瞬态)副本。已关机版本的原始 Guest 说明将保留在源主机上。瞬态副本将会在 Guest 关机后从服务器中删除。

要为目标主机上的 Guest 创建永久副本,请使用开关 --persistent。已关机版本的原始 Guest 说明也会保留在源主机上。将选项 --undefinesource--persistent 一起使用可以实现真正的迁移,在此情况下,将在目标主机上创建永久副本,并删除源主机上的版本。

不建议只使用 --undefinesource 而不使用 --persistent 选项,因为这会导致两个 VM Guest 定义均会在目标主机上的 Guest 关闭后丢失。

17.5 分步操作示例

17.5.1 导出存储区

首先需要导出存储区,以便在主机之间共享 Guest 映像。可以通过一台 NFS 服务器完成此操作。在以下示例中,我们想要共享网络 10.0.1.0/24 中所有计算机的 /volume1/VM 目录。我们使用了一个 SUSE Linux Enterprise NFS 服务器。以 root 用户身份编辑 /etc/exports 文件,在其中添加以下内容:

/volume1/VM 10.0.1.0/24  (rw,sync,no_root_squash)

您需要重启动该 NFS 服务器:

> sudo systemctl restart nfsserver
> sudo exportfs
/volume1/VM      10.0.1.0/24

17.5.2 在目标主机上定义池

在您要迁移 VM Guest 的每台主机上,必须定义池才能访问卷(其中包含 Guest 映像)。我们的 NFS 服务器 IP 地址为 10.0.1.99,它的共享是 /volume1/VM 目录,而我们想要将此共享挂载到 /var/lib/libvirt/images/VM 目录中。池名称为 VM。要定义此池,请创建包含以下内容的 VM.xml 文件:

<pool type='netfs'>
  <name>VM</name>
  <source>
    <host name='10.0.1.99'/>
    <dir path='/volume1/VM'/>
    <format type='auto'/>
  </source>
  <target>
    <path>/var/lib/libvirt/images/VM</path>
    <permissions>
      <mode>0755</mode>
      <owner>-1</owner>
      <group>-1</group>
    </permissions>
  </target>
  </pool>

然后使用 pool-define 命令将其加载到 libvirt

# virsh pool-define VM.xml

另一种定义此池的方法是使用 virsh 命令:

# virsh pool-define-as VM --type netfs --source-host 10.0.1.99 \
     --source-path /volume1/VM --target /var/lib/libvirt/images/VM
Pool VM created

以下命令假设您在 virsh 的交互式外壳中操作,使用不带任何参数的 virsh 命令也可以访问该外壳。然后,可将池设置为在主机引导时自动启动(autostart 选项):

virsh # pool-autostart VM
Pool VM marked as autostarted

要禁用自动启动,请运行以下命令:

virsh # pool-autostart VM --disable
Pool VM unmarked as autostarted

检查该池是否存在:

virsh # pool-list --all
 Name                 State      Autostart
-------------------------------------------
 default              active     yes
 VM                   active     yes

virsh # pool-info VM
Name:           VM
UUID:           42efe1b3-7eaa-4e24-a06a-ba7c9ee29741
State:          running
Persistent:     yes
Autostart:      yes
Capacity:       2,68 TiB
Allocation:     2,38 TiB
Available:      306,05 GiB
警告
警告:池需要在所有目标主机上存在

记住:必须在您要迁移 VM Guest 的每台主机上定义此池。

17.5.3 创建卷

池已定义,现在我们需要一个包含磁盘映像的卷:

virsh # vol-create-as VM sled12.qcow2 8G --format qcow2
Vol sled12.qcow2 created

稍后将会通过 virt-install 使用所示的卷名称安装 Guest。

17.5.4 创建 VM Guest

让我们使用 virt-install 命令创建一个 SUSE Linux Enterprise Server VM Guest。使用 --disk 选项指定 VM 池;如果您不希望在执行迁移时使用 --unsafe 选项,建议您设置 cache=none

# virt-install --connect qemu:///system --virt-type kvm --name \
   sles15 --memory 1024 --disk vol=VM/sled12.qcow2,cache=none --cdrom \
   /mnt/install/ISO/SLE-15-Server-DVD-x86_64-Build0327-Media1.iso --graphics \
   vnc --os-variant sled15
Starting install...
Creating domain...

17.5.5 迁移 VM Guest

一切准备就绪,现在可以执行迁移。在当前托管 VM Guest 的 VM 主机服务器上运行 migrate 命令,并选择目标。

virsh # migrate --live sled12 --verbose qemu+ssh://IP/Hostname/system
Password:
Migration: [ 12 %]
Documentation survey