什么是离线迁移?
离线迁移传输不活动的域定义 —— 是的,它只传输域的定义(就是 XML 文件),而不会传输虚拟磁盘文件!
当迁移成功完成后,两端域的状态如下:
* 在「原始主机」上的「域」将保持其当前状态 * 在「目标主机」上定义「域」,但出于不活动状态
「离线迁移」比”先在「原始主机」上进行virsh dumpxml,后在「目标主机」上进行virsh define“的做法更精巧。因为「离线迁移」将运行「预迁移钩子」,以更新「目标主机上的域XML」。
当前,在「离线迁移」期间,不支持复制「非共享存储」或其他「基于文件的存储」(例如 UEFI 可变存储)。
迁移环境
原始主机:ThinkPad T540p, 172.31.253.2
目的主机:Microserver Gen10, 172.31.253.238
没有共享存储;两台设备网卡直连;
迁移流程
第一步、网络迁移
网络迁移并不复杂,分为两步:1)导出原有的网络配置。2)向目的主机导入网络配置。
我的环境并不复杂,只有一个「默认网络」和一个「隔离网络」。「默认网络」不用处理,只需导出「隔离网络」:
#!/bin/sh # 导出隔离网络配置(在笔记本上执行) virsh net-dumpxml --network isolated > /tmp/isolated.xml # 复制到远程主机中(在笔记本上执行) scp /tmp/isolated.xml 172.31.253.238:/tmp/isolated.xml # 在远程主机中导入网络定义(在Microserver Gen10上执行) virsh net-define /tmp/isolated.xml # 导入网络定义 virsh net-list --all # 查看所有网络,以确定导入成功 virsh net-autostart isolated # 设置自动启动 virsh net-start isolated # 启动网络
第二步、迁移域定义
迁移虚拟机,准确的说是“迁移Guest定义文件”,因为libvirt只能迁移「域定义」:
#!/bin/sh ################################################################################ # 示例一、迁移单台虚拟机 ################################################################################ migrate --offline --persistent 'dns-server' 'qemu+ssh://172.31.253.238/system' ################################################################################ # 示例二、迁移所有的虚拟机 ################################################################################ # !!!先复制SSH密钥到远程主机,否则需要输入密码!!! # 执行命令迁移虚拟机 for i in $(virsh list --all --name) do virsh migrate --offline --persistent "$i" "qemu+ssh://172.31.253.239/system" done # 不会那么顺利的,可能会出现错误提示,根据自己的提示处理就好 # 在处理过程中,如果出现手动修改域定义文件的情况,记得重启libvirt服务。
第三步、迁移虚拟磁盘文件
用virt-sparsify命令。在Debian中,该命令属于libguestfs-tools软件包。
#!/bin/sh virt-sparsify '/var/lib/libvirt/images/windows7sp1.qcow2' '/mnt/nfs/windows7sp1.qcow2' # !!!也可以直接复制,虽然qcow2可以动态增加,但是它是Sparefile类型,所以直接复制即可。 # !!!一开始我一直以为它是稀疏文件,不能简单的复制。后来才了解到,它类似于稀疏文件,但是可以直接 # !!!复制。
如果要复制到远程主机,可以把远程主机目录挂载到本地。例如,通过NFS、SSHFS等等。
参考文献
libvirt/Guest migration/Offline migration
Correct way to move kvm vm
Offline migrating KVM guests using virsh?
What is fastest way to copy a sparse file? What method results in the smallest file?