本文详细介绍了如何在CentOS上使用virt-v2v开源工具将在VMware ESX软件上的Linux虚拟机迁移到基于KVM的虚拟机。
virt-v2v 迁移 VMware/Xen/KVM虚拟机示意图如下所示:
┌────────────┐ ┌─────────▶ -o null
-i disk ────────────┐ │ │ ─┘┌───────▶ -o local
-i ova ──────────┐ └──▶ │ virt-v2v │ ──┘┌───────▶ -o qemu
└────▶ │ conversion │ ───┘┌────────────┐
VMware─▶┌────────────┐ │ server │ ────▶ -o libvirt │─▶ KVM
Xen ───▶│ -i libvirt ──▶ │ │ │ (default) │
... ───▶│ (default) │ │ │ ──┐ └────────────┘
└────────────┘ │ │ ─┐└──────▶ -o glance
-i libvirtxml ─────────▶ │ │ ┐└─────────▶ -o rhev
└────────────┘ └──────────▶ -o vdsm
在迁移前的环境设置如下:我们采用的KVM主机安装CentOS6u5操作系统。这样,最基本的支持KVM虚拟机的软件qemu-kvm、libvirt、和virt-v2v工具都在发行版中安装了,若没有,通过yuminstall安装之。
[root@centos6u5 ~]# rpm -qa qemu-kvm
qemu-kvm-0.12.1.2-2.479.el6.x86_64
[root@centos6u5 ~]# rpm -qa libvirt
libvirt-0.10.2-54.el6.x86_64
[root@centos6u5 ~]# rpm -qa virt-v2v
virt-v2v-0.9.1-5.el6_5.x86_64
下面直接上步骤:
1. 由于一般物理机磁盘都很大,我们需要专门规划一个地方储存它们,可以使用NFS挂载的方式:配置NFSserver,并挂在到KVM主机上
# showmount -e $NFS_SERVER_IP
Export list for $NFS_SERVER_IP:
/root/p2v *
# mount -t nfs $NFS_SERVER_IP:/root/p2v /mnt/p2v
# mount
$NFS_SERVER_IP:/root/p2v on /mnt/p2v type nfs(rw,v3,addr=$NFS_SERVER_IP)
2. 创建 KVM主机存储域
virt-v2v在迁移虚拟机的过程中,需要拷贝被迁移虚拟机到KVM主机预先定义的存储池中。存储池可以用libvirt工具virsh创建。
# virsh pool-define-as p2v dir --target /mnt/p2v/
# virsh pool-autostart p2v
# virsh pool-start p2v
# virsh pool-dumpxml p2v
3. 为自动登录 VMwareESX 服务器创建.netrc文件。VMwareESX服务器的连接需要授权,virt-v2v支持密码方式的授权连接,可以从$HOME/.netrc文件中读取密码并自动登录。如果主机系统没有这个文件,就手动创建它。并且.netrc文件需要0600权限,使virt-v2v工具可以正确读取它。
.netrc文件的格式设置如下:
machine esx.example.com login root password xxxxxx
4. 创建配置文件virt-v2v.conf
在virt-v2v.conf文件中设置virt-v2v迁移的规则,包括网络接口迁移后的映射,迁移的方式,存储的位置,输出的格式等等。这些规则也能以命令行参数的方式输入,如- - network,-o,-os,-of等,我们使用默认的配置即可。
5. 在 VMwareESX 上停止等待迁移的虚拟机,因为virt-v2v只支持静态迁移
6. 使用 virt-v2v命令进行迁移,由于VMwareESX服务器采用HTTPS连接方式,连接时需要配置SSL证书,本文通过添加'?no_verify=1';到VMware服务器的URI连接中,来关闭证书检查。
virt-v2v迁移命令及参数
# virt-v2v -ic esx://esx.example.com/?no_verify=1 -os p2v --network default esxvm-name
注:esx.example.com–是ESX服务器主机名或IPAddress
p2v –本地主机存储池,用来保存镜像
default –本地主机网络名字,用来连接迁移后的虚拟机网络
esxvm-name – ESX上等待迁移的虚拟机名字
此迁移时间长度视ESX虚拟机磁盘的大小而定,280G大约需要10小时;
7. 迁移成功后,虚拟机出现在libvirt管理的虚拟机列表中,通过virsh工具启动虚拟机。
检查迁移后的磁盘:
# ll /path/to/pool/dir/
-rw-r--r--. 1 root root 526385152 Mar 26 07:49 p2v-rhel-sda
-rw-r--r--. 1 root root 298917560320 Mar 26 08:13 p2v-rhel-sdb
# qemu-img info p2v-rhel-sda
image: p2v-rhel-sda
file format: raw
virtual size: 502M (526385152 bytes)
disk size: 93M
检查迁移后的虚拟机(virt-v2v会在libvirt管理的虚拟机中新建一个名字与原虚拟机一样的VM)
# virsh list --all
Id Name State
----------------------------------------------------
- p2v-rhel shut off
通过virsh start p2v-rhel你可能会遇到两个问题:
(1)p2v-rhel的xml中定义了,此bridge在主机中不存在,解决方法如下:
通过virsh editp2v-rhel将'VM Network'换成'virbr0';
(2)volume permission denied的问题,原因是被centos中selinux相关的策略挡住了,解决方法如下:
a.在qemu.conf中将security的driver设置为none,修改/etc/libvirt/qemu.conf,添加
security_driver = "none"
并重启libvirtd服务:service libvirtd restart
b.将image所在路径的所有父目录(即从根目录至当前目录)权限全部改成755:
chmod -R 755 /path/to/pool/dir/images
c.将image文件的context改成unconfined_u:object_r:virt_image_t:s0:
chcon -Rv --type=virt_image_t /path/to/pool/dir/images
# ll -Z
-rw-r--r--. root root unconfined_u:object_r:virt_image_t:s0 p2v-rhel-sda
-rw-r--r--. root root unconfined_u:object_r:virt_image_t:s0 p2v-rhel-sdb
注意:若使用nfs mount的路径创建的pool,你还可能需要设置selinux允许virt使用nfs:
# getsebool virt_use_nfs
virt_use_nfs --> off
# setsebool virt_use_nfs on
# getsebool virt_use_nfs
virt_use_nfs --> on
8. 虚拟机成功开机后,检查迁移后的虚拟机的设备驱动,如果需要,重新安装虚拟设备驱动。
9. 验证迁移后的虚拟机的配置和系统是否和迁移之前一致。
注:在CentOS7u2上迁移ESX上的虚拟机至KVM与CentOS6u5有所不同,因为经过大版本修改,virt-v2v的实现有较大的改动,必须使用vCenter管理ESX,ESX上的虚拟机才能被迁移:
#rpm -qa virt-v2v
virt-v2v-1.28.1-1.55.el7.centos.x86_64
命令行变化如下:
# virt-v2v -ic vpx://vsphere.local%5cadministrator@$vCenter_IP/$DATACENTER_NAME/$ESX_IP/?no_verify=1-os p2v --network default esxvm-name
然后输入两次vCenter的登陆密码即可。
注意:vsphere.local%5cadministrator是vCenter服务器的登录名,%5c是'\'的转义字符,这是唯一正确的输入方式,否则你会一直遇到用户名或密码错误;另外需要export libguestfs的环境变量:export LIBGUESTFS_BACKEND=direct。
打印输出log以便调试的方法:
# LIBGUESTFS_TRACE=1 LIBGUESTFS_DEBUG=1 virt-v2v -i libvirtxml -os pool --bridge bridge_name guest_name.xml ... 2>&1 | tee virt-v2v.log
此外,感谢Tony、klyang、blue的共同探索与努力,我们一起填坑才使得CentOS7上的virt-v2v命令行最终输入正确。
参考文档:
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html-single/V2V_Guide/index.html
http://libguestfs.org/virt-v2v.1.html