基于libvirt的虚拟化迁移

 

为什么要迁移呢?当一台主机的负载过高时,我们希望把虚拟机迁移到一台系统更好的主机上。当主机发生硬件故障需要停机维护时,我们需要迁移虚拟机,如果主机就只跑了一台虚拟机我们可以把它迁移到其他主机,提高资源的利用率,等等。

迁移命令:
# virsh migrate --live GuestName DestinationURI   (--live :迁移过程中虚拟机一直保持运行状态)
GuestName指虚拟机名称,DestinationURI:目的主机的URI。
举例:# virsh  migrate --live vm0 qemu+tcp://192.168.0.200/system
迁移的要求是:需要目的主机和源主机有相同的环境,包括hypervisor。

注意点:
笔者在做迁移的时候,所有前置条件都一配置好,执行迁移命令:
sudo virsh migrate --live vm0 qemu+tcp://192.168.1.200/system
却出现的如下错误:
error: Unable to resolve address 'ubuntu1204' service '49152': No address associated with hostname
笔者的系统环境是Ubuntu,错误中‘ubuntu1204’是192.168.1.200的主机名,对此错误很是不解,说是‘ubuntu1204’无法解析,查得资料: http://wiki.libvirt.org/page/Migration_fails_with_%22Unable_to_resolve_address%22_error
在迁移的过程中,运行在目的主机中的libvirtd进程要根据address和port创建一个URI,URI是目的主机用来接收数据和发回数据到源主机的libvirtd进程的。上面的错误的原因是libvirtd没法解析主机名到IP地址。可以看下图:
目的主机libvirtd在发回数据的时候,把hostname发回去了,而源主机就用直接请求hostname而非IP,恰巧在源主机没有做DNS配置,因此才出现次错误。
如果是在REHEL系列的Linux中出现的错误如所示:Migration fails with "Unable to resolve address" error

解决方案一:
配置source源主机的 /etc/hosts文件:加入"192.168.1.200 ubnuntu1204"  参考: http://bbs.openzj.com/thread-7200-1-1.html

解决方案二:
# virsh migrate vm0 qemu+tcp://192.168.1.200/system tcp://192.168.1.200
这时目的主机libvirtd进程将使用“tcp://192.168.1.200“作为迁移连接,libvirt会自动生成的端口追加到此URI后面,(这里相当于开启另外一个连接来迁移数据,可以和方案三对比之)当然也可以手动指定端口号如:
# virsh migrate vm0 qemu+tcp://192.168.1.200/system tcp://192.168.1.200 12345

解决方案三:使用隧道(tunnelled) 迁移,该方式不会为迁移创建单独的连接,而是通过与目的libvirtd通信的这个连接来传输数据。(例如连接:qemu+tcp://192.168.1.200/system)
# virsh migrate vm0 qemu+tcp://192.168.1.200/system  --p2p --tunnelled

问题解决了,顺便学习下libvirt migrate的概念:

说到虚拟机的迁移,其实就是数据的转移,数据的转移就涉及数据的传输,数据的传输需要通过网络。libvirt提供了两种方案。

hypervisor native transport:
“本地”数据传输,相当于一种手动方式做的迁移。数据是否可以加密取决于hypervisor自身是否已实现。

libvirt tunnelled transport
隧道化的(tunnelled)数据传输支持很强的加密功能,这要归结于libvirt的RPC协议。不好的一方面是数据会在hypervisor和libvirtd之间的传输。
迁移时的通信控制:(此景会有一个第三方的管理程序来管理,上面所说单纯是从两个主机直接的角度来说的)

虚拟机的迁移需要两个主机之间的密切协调,同时应用程序(虚拟机管理平台)也将参与进来,此应用可以是在源主机、目的主机、甚至是第三台主机。

受管理的直接迁移(Managed direct migration):
直接管理迁移,libvirt客户端进程控制迁移的不同阶段。客户端应用程序必须连接以及获得在源主机和目的主机的libvirtd进程的认证。无需两个libvirtd进程间相互通信。如果客户端应用崩溃了,或者在迁移过程中失去了链接,一种办法就是强制终止迁移,重启源主机的guest CPU。
管理的点对点迁移:(Managed peer to peer migrate)
对于点对点,libvirt客户端程序只是与在源主机的libvirtd进程通信,源主机libvirtd进程自己控制整个迁移的过程,直接连接到目的主机的libvirtd。如果客户端应用崩溃了或者与libvirtd失去连接,迁移过程无需中断直至迁移完成。需要注意的是源主机认证(通常是root)链接到目的主机,而不是通过客户端应用链接到源主机。

不受管理的直接迁移:(Unmanaged direct migrate)
此迁移方式既不受libvirt客户端控制,也不受libvirtd控制,迁移的控制过程委托给基于hypervisor之上的管理服务来处理。libvirt 客户只需要通过hypervisor的管理层做一下初始化。不管是libvirt 客户端还是libvirtd崩溃了,迁移还是会照样进行直至完成。


迁移URI:
虚拟机迁移时,客户端应用程序需要准备的URI可达三个,具体取决于控制流如何选择或者API如何调用。第一个URI就是应用程序到运行着虚拟机的源主机的连接,第二个URI就是目的主机到应用程序之间的连接(在点对点的迁移中,这个连接是来自源主机,而不是客户端应用程序)。第三个URI就是hypervisor指定的用来控制以何种方式迁移的连接。在任何一种受管理的迁移中,前两个URI是必不可少的,第三个是可选的。而在不受管理的直接迁移中,第一个和第三个是必须的,第二个并不会使用。


通常管理应用程序只需关心前两个URI。二者都是普通的libvirt 连接URI格式。libvirt会通过查找目的主机的配置文件中的hostname自动确定hypervisor指定的URI(第三个URI)。

应用程序获取第三个URI时可能会出现的如下几种情况:
1、hostname的配置不正确,或者DNS不正确,如果主机的hostname不能正确的解析到IP地址的化就会生成一个错误的URI,这刚好时文章开头出现的问题。此时需要明确指定IP地址或者使用正确的hostname。
2、主机有多个网络接口,此时需要用IP明确指定来关联某个具体的网卡。
3、防火墙限制端口的使用,当libvirt自动生扯功能的端口需要防火墙对其端口是开放的。



参考:
http://libvirt.org/migration.html
http://www.ibm.com/developerworks/cn/linux/l-cn-mgrtvm2/index.html
http://wiki.libvirt.org/page/TodoPreMigrationChecks



















 

你可能感兴趣的:(libvirt)