Chinaunix首页 | 论坛 | 博客
  • 博客访问: 419263
  • 博文数量: 83
  • 博客积分: 2622
  • 博客等级: 少校
  • 技术积分: 1345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 08:59
个人简介

一直在努力

文章分类

全部博文(83)

文章存档

2014年(3)

2013年(9)

2012年(46)

2010年(25)

分类: 云计算

2014-09-23 19:29:03

openstack live migration相当复杂的流程,足以展现openstack compute project的复杂度,所以,从代码走读开始,先来一张代码走读的流程。more details to be continue. 没有rollback 部分,没地方画了。
图中没有从nova-api 的代码走读,直接就从live migration的source compute node处理live migration开始了。
从api request发起的话,基本流程
1. nova-api处理Resetful 请求,各种权限验证。
2. nova-api  ===rpc:conductor:migrate_server===>>  nova-conductor call migrate_server method, 最终的调用的是conductor/tasks/live_migrate.py:class LiveMigrationTask:execute

execute处理过程:
_check_instance_is_running
_check_host_is_up(source host)
如果没有指定target host 则调用_find_destination 选取 target host. _find_destination, 其实就是通过nova-scheduler选取target host
得到target host就监测target host是否有足够的resource 用来migration instance。
_check_compatible_with_source_hypervisor #兼容性检查要求 hypervisor_type 必须一样, 且hypervisor version是兼容的
_call_livem_checks_on_host 

点击(此处)折叠或打开

  1. def _call_livem_checks_on_host(self, destination):
  2.         self.migrate_data = self.compute_rpcapi.\
  3.             check_can_live_migrate_destination(self.context, self.instance,
  4.                 destination, self.block_migration, self.disk_over_commit)
这个函数式需要destination host 也就是target host 做一些migration的监测。这个函数显然是通过message 发送给target host ,并有nova-compute 进程调用method. check_can_live_migrate_destination如命名用途就是监测live-migration 是否能够进行。 
下面这段代码存在于compute/manager.py : 由代码可见,最终还是有virt driver 执行具体的check步骤,且需要主要的是,直接也用rpc Message通信的方式需要source host也进行监测。
compute/manager.py :check_can_live_migrate_destination

点击(此处)折叠或打开

  1. def check_can_live_migrate_destination(self, ctxt, instance,
  2.                                            block_migration, disk_over_commit):
  3.         src_compute_info = self._get_compute_info(ctxt, instance.host)
  4.         dst_compute_info = self._get_compute_info(ctxt, CONF.host)
  5.         dest_check_data = self.driver.check_can_live_migrate_destination(ctxt,
  6.             instance, src_compute_info, dst_compute_info,
  7.             block_migration, disk_over_commit)
  8.         migrate_data = {}
  9.         try:
  10.             migrate_data = self.compute_rpcapi.\
  11.                                 check_can_live_migrate_source(ctxt, instance,
  12.                                                               dest_check_data)
  13.         finally:
  14.             self.driver.check_can_live_migrate_destination_cleanup(ctxt,
  15.                     dest_check_data)
  16.         if 'migrate_data' in dest_check_data:
  17.             migrate_data.update(dest_check_data['migrate_data'])
  18.         return migrate_data

kvm中的处理方法virt/libvirt/driver.py:check_can_live_migrate_destination

点击(此处)折叠或打开

  1. def check_can_live_migrate_destination(self, context, instance,
  2.                                            src_compute_info, dst_compute_info,
  3.                                            block_migration=False,
  4.                                            disk_over_commit=False):

  5.         disk_available_mb = None
  6.         if block_migration:
  7.             disk_available_gb = dst_compute_info['disk_available_least']
  8.             disk_available_mb = \
  9.                     (disk_available_gb * units.Ki) - CONF.reserved_host_disk_mb

  10.         # Compare CPU
  11.         source_cpu_info = src_compute_info['cpu_info']
  12.         self._compare_cpu(source_cpu_info)

  13.         # Create file on storage, to be checked on source host
  14.         filename = self._create_shared_storage_test_file()

  15.         return {"filename": filename,
  16.                 "block_migration": block_migration,
  17.                 "disk_over_commit": disk_over_commit,
  18.                 "disk_available_mb": disk_available_mb}
source host compute/manager.py

点击(此处)折叠或打开

  1. def check_can_live_migrate_source(self, ctxt, instance, dest_check_data):
  2.         is_volume_backed = self.compute_api.is_volume_backed_instance(ctxt,
  3.                                                                       instance)
  4.         dest_check_data['is_volume_backed'] = is_volume_backed
  5.         return self.driver.check_can_live_migrate_source(ctxt, instance,
  6.                                                          dest_check_data)
source host virt/libvirt/driver.py

点击(此处)折叠或打开

  1. def check_can_live_migrate_source(self, context, instance,
  2.                                       dest_check_data):
  3.         source = CONF.host
  4.         filename = dest_check_data["filename"]
  5.         block_migration = dest_check_data["block_migration"]
  6.         is_volume_backed = dest_check_data.get('is_volume_backed', False)
  7.         has_local_disks = bool(
  8.                 jsonutils.loads(self.get_instance_disk_info(instance['name'])))

  9.         shared = self._check_shared_storage_test_file(filename)

  10.         if block_migration:
  11.             if shared:
  12.                 reason = _("Block migration can not be used "
  13.                            "with shared storage.")
  14.                 raise exception.InvalidLocalStorage(reason=reason, path=source)
  15.             self._assert_dest_node_has_enough_disk(context, instance,
  16.                                     dest_check_data['disk_available_mb'],
  17.                                     dest_check_data['disk_over_commit'])

  18.         elif not shared and (not is_volume_backed or has_local_disks):
  19.             reason = _("Live migration can not be used "
  20.                        "without shared storage.")
  21.             raise exception.InvalidSharedStorage(reason=reason, path=source)
  22.         dest_check_data.update({"is_shared_storage": shared})

  23.         # NOTE(mikal): include the instance directory name here because it
  24.         # doesn't yet exist on the destination but we want to force that
  25.         # same name to be used
  26.         instance_path = libvirt_utils.get_instance_path(instance,
  27.                                                         relative=True)
  28.         dest_check_data['instance_relative_path] = instance_path


            return dest_check_data


其实简言之,就是判断是否有足够的空间用于migration instance,并通过创建一个test文件判断source 和target host之间是否是共享存储。
如果是共享存储,那么live migration,就不要拷贝instance disk file,也就是不需要block migration的方式。
如果不是共享存储那么就必须采用 block migration的方式进行live migration。    

最后一步就是发送 rpc message 给source host 通知开始live migrate instance. 然后就是下图的处理了。



阅读(3793) | 评论(1) | 转发(0) |
0

上一篇:openstack nova-api servie 服务框架

下一篇:没有了

给主人留下些什么吧!~~

BEND2014-10-16 11:29:08

文章够细致的