虚拟机的迁移在实际环境中经常用到,例如将虚拟机从A主机迁移到B上,然后对A进行维护后,再将虚拟机从B迁回A。因此,我就在实验室的环境下,进行这个实验。这里对迁移方式做一个简单的记录。
虚拟机迁移的种类有:冷迁移和热迁移。冷迁移顾名思义,就是在虚拟机迁移的时候,需要将虚拟机暂停一段时间,而热迁移则不需要。
热迁移的方式有:1.基于共享存储的迁移;2.基于块的迁移;3.基于volumes存储的迁移;
这里首先记录一下使用基于共享存储和kvm-libvirt的虚拟机热迁移方式。
文中描述的迁移方式没有涉及安全方面的考虑;在迁移过程中,仅对虚拟机做简单的操作;有错误的地方还请指出和见谅。
因为虚拟机迁移需要在controller节点上提供cinder-*的服务,所以需要先安装Block Storage service。之前配置openstack时,没有添加这项服务,就在这里添加并记录。安装过该服务的,可跳过此步骤,第三步也如此。
1.使用如下命令,安装必须的程序包。
apt-get install cinder-api cinder-scheduler
2.编辑/etc/cinder/cinder.conf文件,在该文件中添加如下的信息,[database]段需要自己添加,123456是cinder数据库的密码,视自己的情况而定。
[database]
connection = mysql://cinder:123456@controller/cinder
3.使用如下的命令,登入mysql,建立一个cinder数据库,并设置权限。
mysql -uroot -p123456
CREATE DATABASE cinder;
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY '123456';
4.使用如下的命令在cinder数据库中建表。
sudo su -s /bin/sh -c "cinder-manage db sync" cinder
5.创建cinder用户
source admin-openrc.sh
keystone user-create --name=cinder --pass=123456 [email protected]
keystone user-role-add --user=cinder --tenant=service --role=admin
6.修改/etc/cinder/cinder.conf文件,添加如下的内容,其中123456是密码
[keystone_authtoken]
auth_uri = http://controller:5000
auth_host = controller
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = cinder
admin_password = 123456
在[default]部分,添加如下的内容
[DEFAULT]
rpc_backend = rabbit
rabbit_host = controller
rabbit_port = 5672
rabbit_userid = guest
rabbit_password = RABBIT_PASS
7.使用如下的命令,来注册块存储的服务,以使别的Openstack服务能够定位到它。执行完的效果如下图所示。
keystone service-create --name=cinder --type=volume --description="OpenStack Block Storage"
keystone endpoint-create \
--service-id=$(keystone service-list | awk '/ volume / {print $2}') \
--publicurl=http://controller:8776/v1/%\(tenant_id\)s \
--internalurl=http://controller:8776/v1/%\(tenant_id\)s \
--adminurl=http://controller:8776/v1/%\(tenant_id\)s
8.使用如下的命令,给Block Storage的第二个版本注册服务和endpoint。
keystone service-create --name=cinderv2 --type=volumev2 --description="OpenStack Block Storage v2"
keystone endpoint-create \
--service-id=$(keystone service-list | awk '/ volumev2 / {print $2}') \
--publicurl=http://controller:8776/v2/%\(tenant_id\)s \
--internalurl=http://controller:8776/v2/%\(tenant_id\)s \
--adminurl=http://controller:8776/v2/%\(tenant_id\)s
9.使用如下命令,重启各项服务。
sudo service cinder-scheduler restart
sudo service cinder-api restart
由于虚拟机的迁移并不需要在其它节点上包含此服务,所以这里就不配置了。
使用如下的命令就可以了。
sudo apt-get install nova-objectstore
2.controller节点是nfs服务器,在其它节点上是nfs客户端,nfs客户端需要mount到服务端。
sudo apt-get install nfs-kernel-server
sudo chmod o+x /export/nova_instances/
/var/lib/nova/instances/ /export/nova_instances none bind 0 0
/var/lib/nova/instances/ 10.0.0.1/255.255.255.0(insecure,rw,sync,fsid=0,no_root_squash)
编辑好的配置文件应如下图所示:
sudo /etc/init.d/nfs-kernel-server restart
注:可使用如下的命令查看是否已经将/var/lib/nova/instances目录共享出来,当看到如下图所示的情况时,说明export成功了。
showmount -e
sudo exportfs -r
3.在其它compute节点上,配置nfs。
apt-get install nfs-common
sudo chmod o+x /var/lib/nova/instances
controller:/ /var/lib/nova/instances nfs4 defaults 0 0
mount -a -v
挂载后,可用如下的命令来查看是否mount上了,若挂载上了,则如下图所示。
df -k
listen_tls = 0
listen_tcp = 1
auth_tcp = "none"
#exec /usr/sbin/libvirtd $libvirtd_opts 将这行修改为下一行
exec /usr/sbin/libvirtd -d -l
libvirtd_opts="-d -l"
stop libvirt-bin && start libvirt-bin
ps -ef | grep libvirt
4. 修改nova与libvirt-qemu的uid和gid,使他们和controller节点一致,这样共享目录才能互相访问。(如果不做这步操作,则无法查看原来建好的虚拟机,即无法查看共享目录下原来有的文件)
id nova
id libvirt-qemu
我这里的执行结果如下图所示。
usermod -u 123 nova
usermod -u 126 libvirt-qemu
groupmod -g 132 nova
groupmod -g 135 kvm
service nova-api-metadata stop
service nova-compute stop
service nova-network stop
service libvirt-bin stop
find / -uid 106 -exec chown nova {} \;
find / -uid 104 -exec chown libvirt-qemu {} \;
find / -gid 107 -exec chgrp nova {} \;
find / -gid 104 -exec chgrp libvirt-qemu {} \;
service nova-api-metadata start
service nova-compute start
service nova-network start
service libvirt-bin start
live_migration_flag=VIR_MIGRATE_UNDEFINE_SOURCE,VIR_MIGRATE_PEER2PEER,VIR_MIGRATE_LIVE
nova list
nova-manage vm list
nova live-migration 45cb1fde-c98e-49ca-8b0c-a3e30d2309b1 openstack-1-0
执行结果如下图所示,没出错的话,在这里不会返回信息。
在Dashboard上,可以看出来,我们的虚拟机已经迁移到opensack-1-0主机上了。
5.在迁移的过程中,仅对虚拟机做简单的命令操作,迁移完成后,发现虚拟机并未重启,仍然保持原样。
ERROR: Live migration of instance 23469945-a0c0-4157-8618-f9c80eb4a6e7 to host openstack-MS-7673 failed (HTTP 400) (Request-ID: req-d66e598c-5e88-4f93-b882-a2ca26916ee9)
于是查看/var/lib/nova/nova-api.log日志,发现错误是:InvalidCPUInfo: Unacceptable CPU info: CPU doesn't have compatibility.
nova hypervisor-show openstack-MS-7673
nova hypervisor-show openstack-1-0
得到的CPU信息如下所示,可看到,两个节点的cpu模型是不同的,一个是Westmere而另一个是Nehalem。
根据错误日志,定位到openstack的源代码位置:/usr/lib/python2.7/dist-packages/nova/virt/libvirt/driver.py
这里,我修改了该文件的代码,把self._compare_cpu(source_cpu_info)注释掉,并将ret=self._conn.compareCPU(cpu.to_xml(), 0)注释了,但发现,其它地方还要抛出异常,这边代码嵌套很多,以后有时间再看。
ERROR nova.virt.libvirt.driver [-] [instance: feca0225-a9b8-4516-85a5-8c74a5106ffa] Live Migration failure: operation failed: Failed to connect to remote libvirt URI qemu+tcp://openstack-MS-7673/system: Unable to resolve address 'openstack-MS-7673' service '16509': Name or service not known
这个就是要在/etc/hosts文件中添加你要迁移的主机的名称。
2014-10-29 15:28:07.977 1650 ERROR nova.virt.libvirt.driver [-] [instance: feca0225-a9b8-4516-85a5-8c74a5106ffa] Live Migration failure: 'module' object has no attribute 'VIR_MIGRATE_MIGRATE_LIVE'
这里,我由于疏忽配置错了一个选项live_migration_flag造成的,修改后就可以了。
2014-10-29 16:26:33.201 3440 ERROR oslo.messaging.rpc.dispatcher [-] Exception during message handling: [Errno 13] Permission denied: '/var/lib/nova/instances/df6f147c-6c7c-4f5e-a4e4-e53b0afa3791/libvirt.xml'
这里,要保证/var/lib/nova/instances中相关文件都属于nova用户和组,如果属于其它,则就无法对它们进行获取和操作了。