执行方式
通过client执行迁移任务
nova live-migration bwb-test xzto03n010027244144.sncloud.com --force --switch-store ceph
通过api执行
POST http://10.243.134.21:8774/v2.1/servers/85f2f979-94c8-4021-920e-a074ce3a4271/action
BODY
{
"os-migrateLive": {
"host": "01c0cadef72d47e28a672a76060d492c",
"block_migration": "auto",
"force": false
"switch_store":"ceph"
}
}
处理流程
第一步——任务处理 组件服务: nova-api 组件模块: api/openstack/compute/migrate_server.py 功能: 参数的解析;添加实例的任务状态 接口
def _migrate_live(self, req, id, body)
第二步——生成迁移任务 组件服务: nova-conductor 组件模块: /nova/conductor/manager.py 功能: 生成迁移任务;执行迁移任务(包含实例状态检查,host检查,目标结点检查) 接口:
def live_migrate_instance(self, context, instance, host_name,
block_migration, disk_over_commit,
request_spec=None, async=False, switch_store=None, bandwidth=None)
第三步——执行迁移任务 组件服务: nova-compute 组件模块: /nova/compute/manager.py 功能: 实现实例的迁移任务 接口
def live_migration(self, context, dest, instance, block_migration, migration, migrate_data)
迁移任务流程
实例状态置为queued状态,等待迁移队列释放资源,开始执行迁移 def live_migration(self, context, dest, instance, block_migration,
migration, migrate_data):
"""Executing live migration.
:param context: security context
:param dest: destination host
:param instance: a nova.objects.instance.Instance object
:param block_migration: if true, prepare for block migration
:param migration: an nova.objects.Migration object
:param migrate_data: implementation specific params
"""
#等待队列释放资源
self._set_migration_status(migration, 'queued')
LOG.info(_LI('Migrating instance[%(uuid)s] to %(dest)s queued.'),
{'uuid': instance.uuid, 'dest': dest},
instance=instance)
def dispatch_live_migration(*args, **kwargs):
with self._live_migration_semaphore:
self._do_live_migration(*args, **kwargs)
# NOTE(danms): We spawn here to return the RPC worker thread back to
# the pool. Since what follows could take a really long time, we don't
# want to tie up RPC workers.
utils.spawn_n(dispatch_live_migration,
context, dest, instance,
block_migration, migration,
migrate_data)
实例状态置为preparing状态,进行迁移前准备工作
当为跨结点迁移时,发送pre_live_migration请求到目标结点,完成目标结点迁移前的准备工作,此阶段目标结点将接受rpc请求,并创建实例目录,拷贝disk,disk.info,backfileimage,创建端口,创建目标结点后端存储,并返回元数据信息 核心逻辑如下: self._set_migration_status(migration, 'preparing')
LOG.info(_LI('Migrating instance[%(uuid)s] to %(dest)s preparing.'),
{'uuid': instance.uuid, 'dest': dest},
instance=instance)
got_migrate_data_object = isinstance(migrate_data,
migrate_data_obj.LiveMigrateData)
if not got_migrate_data_object:
migrate_data = \
migrate_data_obj.LiveMigrateData.detect_implementation(
migrate_data)
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(context, instance.uuid)
if migration.source_compute != migration.dest_compute:
#对跨结点迁移的实例发送pre_live_migration请求,同结点不做处理
# migration local store
try:
self.__rehosted__(context, bdms, dest)
block_device_info = self._get_instance_block_device_info(context, instance)
disk = self.driver.get_instance_disk_info(instance, block_device_info=block_device_info)
migrate_data = self.compute_rpcapi.pre_live_migration(
context, instance, block_migration, disk, dest, migrate_data)
except Exception:
with excutils.save_and_reraise_exception():
LOG.exception(_LE('Pre live migration failed at %s'),
dest, instance=instance)
self._set_migration_status(migration, 'error')
self._rollback_live_migration(context, instance, dest,
migrate_data)
self.__rehosted__(context, bdms, self.host)
当同结点迁移时,无操作 迁移实例为running状态,开始迁移实例
当为跨结点迁移时,执行self.driver.live_migration完成实例的迁移,执行成功实现_post_live_migration逻辑,失败实现_rollback_live_migration逻辑_post_live_migration完成清理源卷的连接、迁移网口、删除源结点网口、删除disk、通知目标结点完成迁移、更新实例状态 核心逻辑 try:
live_migrate_flag = self.driver.live_migrate_flags(bdms, migration.switch_store)
#完成实例的迁移,回滚,迁移后资源回收的接口
self.driver.live_migration(context, instance, dest, live_migrate_flag,
self._post_live_migration,
self._rollback_live_migration,
block_migration, migrate_data, migration.switch_store)
except Exception:
LOG.exception(_LE('Live migration failed.'), instance=instance)
with excutils.save_and_reraise_exception():
# Put instance and migration into error state,
# as its almost certainly too late to rollback
self._set_migration_status(migration, 'error')
# first refresh instance as it may have got updated by
# post_live_migration_at_destination
instance.refresh()
self._set_instance_obj_error_state(context, instance,
clean_task_state=True)
当为同结点迁移时,执行_block_update_type实现卷的迁移,完成后端存储的切换 # finish migrate action to delete or rollback bdm infos
if migration.switch_store is not None and
migration.source_compute == migration.dest_compute:
#完成本地后端存储的切换
self._block_update_type(context, instance, migration, self._disk_live_migration_rollback)
self._finish_live_migration(context, dest, instance, migration)
return
迁移状态为completed,完成实例的迁移