libvirt kvm qemu 之间得关系图
相比于 QEMU,在 libvirt 的层面上,虚拟机迁移方式就更为多样灵活。libvirt 上的迁移有多种方式,每种都有自己的优点和缺点,为了最大程度地保证 hypervisor 集成和管理员部署的灵活性,libvirt 实现了多种迁移选择。
数据传输方式虚机迁移分类
从数据转发(通常指网络数据转发)的角度上来看,libvirt 提供了两种迁移方式,一种是利用 hypervisor 自身提供的转发机制,另一种是通过利用 libvirtd 的连接实现转发。
Hypervisor native transport
使用 hypervisor 原生的数据转发机制可能无法支持数据加密功能,这取决于 hypervisor 的具体实现,但是它减少了额外的数据拷贝(vm 和 libvirtd 之间的数据拷贝)开销。使用 hypervisor 原生的数据转发机制需要管理员在主机上进行额外的 hypervisor 相关的网络配置,对于某些 hypervisor 来说需要在防火墙上打开一堆 ports,来允许虚拟机通过这些 ports 进行迁移。
libvirt tunnelled transport
通过隧道的数据传输方式,可以使得迁移过程高度加密,因为它可以使用 libvirt RPC 协议中内置的功能。但是它的缺点是需要进行额外的数据拷贝,无论在 srcHost 上还是 destHost 上都需要将数据在 libvirtd 和 hypervisor 之间拷贝。另一方面,使用隧道数据传输方式不需要对主机网络进行额外的设置,因为它使用的是和 libvirtd remote access 相同的机制。只需要在防火墙上打开一个端口,就能够同时支持多个迁移操作。
从控制流看迁移分类
Managed direct migration
在managed direct migration
情况下,libvirt 客户端进程控制着迁移的各个阶段。客户端应用需要能够连接 srcHost 和 destHost,并且能够管理其上的 libvirtd 守护进程。两个 libvirtd 之间不需要交流。如果客户端应用崩溃,或者在迁移过程中失去了与 libvirtd 的连接,那么 libvirtd 将尝试终止迁移,并且在 srcHost 上重启 guest CPUs(libvirt 官方原文为重启 guest CPUs,非重启 guest)。在很多情景下迁移过程可能无法安全完成,这将导致 guest 在一台或者两台 Host 上挂起。
Managed peer to peer migration
在managed peer to peer migration
情况下,libvirt 客户端进程只与 srcHost 对话,srcHost 上的 libvirtd 守护进程通过直接连接 destHost 上的 libvirtd 控制整个迁移过程。如果客户端应用崩溃,或者在迁移过程中失去了与 libvirtd 的连接,迁移过程不会被中断。srcHost libvirtd 使用自身的凭证(通常是 root)连接到 destHost,而不是使用客户端连接到 srcHost 的凭证;如果这两个凭证不同,那么就可能出现客户端能够直接连接到 destHost 上,但是 srcHost 不能够创建 p2p 迁移连接的情况。
Unmanaged direct migration
在Unmanaged direct migration
情况下,既不是 libvirt 客户端控制迁移过程,也不是 libvirtd 守护进程控制迁移过程。控制权委托给 hypervisor 管理服务。libvirt 仅仅是通过 hypervisord 的管理层初始化虚拟机迁移操作。即便 libvirt 客户端或者 libvirtd 崩溃,都不会影响迁移过程。
Unmanaged direct migration
采用native transport
,数据不需要额外拷贝。
数据安全
由于迁移数据流包含了完整的 guest OS RAM 信息,窥探迁移数据流可能会危及敏感的客户信息。如果 Host 具有多个网络接口,或者如果网络交换机支持标记的 VLAN,则非常需要将 Guest 网络流量与迁移或管理流量分开。
在某些情况下,即便是分离迁移和管理网络流量也会承受一些风险。在这种情况下,需要加密迁移数据流。如果 hypervisor 本身不提供加密功能,那么就应该是用 libvirt tunnelled migration。
配置文件
libivrt 能够识别到两种类型的虚拟机(参考在 libvirt 中虚拟机状态),transient
类型的虚拟机只有在运行时才存在,磁盘中不会存储虚拟机配置文件信息。persistent
类型的虚拟机会在磁盘上保存一份虚拟机配置文件,无论是否在运行。
默认情况下,迁移操作不会修改虚拟机定义文件。管理虚拟机配置文件是管理员、管理系统的责任。注意:etc/libvirt
文件目录绝对不能够在 Host 之间共享。下面是一些典型的场景:
-
在 libvirt 之外的共享存储中集中管理虚拟机配置文件。支持集群的管理应用程序可以在集群文件系统中维护所有主要的 guest 配置文件。当想要启动一个 guest 时,就从集群文件系统中读取配置文件,创建一个
persistent
虚拟机。迁移的时候,需要将该配置文件从 srcHost 复制到 destHost 并删除原件。 -
在 libvirt 之外的数据库中集中管理虚拟机配置文件。数据中心管理应用可能完全不会存储虚拟机配置文件。只有当 guest 启动时,它才生成一个虚拟机定义文件。它一般使用
transient
虚拟机。因此在迁移过程中无需考虑虚拟机配置文件。 -
在 libvirt 中分发虚拟机配置文件。虚拟机配置文件在所有 Host 上都保存一个副本。在迁移时,现有的配置只需要更新到最新的更改。
-
在 libvirt 中进行专门的配置管理,每个 Guest 都被绑定到特定的 Host 上,并且很少迁移。当需要迁移的时候,需要将配置文件从一个 Host 移动到另一个 Host。
在默认情况下 libvirt 在迁移时不会修改配置文件。virsh
命令中有两个 flag 可以影响这个行为。--undefine-source
flag 将使 srcHost 上的虚拟机配置文件在迁移后被移除。--persist
flag 将使 destHost 上在迁移成功后创建一个虚拟机配置文件。
--undefined-source
和--persist
两个 flag 将使迁移后的虚拟机改变状态。下表总结了所有可能的状态与标志组合下的配置文件处理。
Before migration
Flags
After migration
Source type
Source config
Dest config
--undefinesource
--persistent
Dest type
Source config
Dest config
Transient
N
N
N
N
Transient
N
N
Transient
N
N
Y
N
Transient
N
N
Transient
N
N
N
Y
Persistent
N
Y
Transient
N
N
Y
Y
Persistent
N
Y
Transient
N
Y
N
N
Persistent
N
Y (unchanged dest config)
Transient
N
Y
Y
N
Persistent
N
Y (unchanged dest config)
Transient
N
Y
N
Y
Persistent
N
Y (replaced with source)
Transient
N
Y
Y
Y
Persistent
N
Y (replaced with source)
Persistent
Y
N
N
N
Transient
Y
N
Persistent
Y
N
Y
N
Transient
N
N
Persistent
Y
N
N
Y
Persistent
Y
Y
Persistent
Y
N
Y
Y
Persistent
N
Y
Persistent
Y
Y
N
N
Persistent
Y
Y (unchanged dest config)
Persistent
Y
Y
Y
N
Persistent
N
Y (unchanged dest config)
Persistent
Y
Y
N
Y
Persistent
Y
Y (replaced with source)
Persistent
Y
Y
Y
Y
Persistent
N
Y (replaced with source)