OpenStack之虚机热迁移的代码详细解析

论坛 期权论坛 脚本     
niminba   2021-5-23 05:02   1343   0

话说虚机迁移分为冷迁移以及热迁移,所谓热迁移用度娘的话说即是:热迁移(Live Migration,又叫动态迁移、实时迁移),即虚机保存/恢复(Save/Restore):将整个虚拟机的运行状态完整保存下来,同时可以快速的恢复到原有硬件平台甚至是不同硬件平台上。恢复以后,虚机仍旧平滑运行,用户不会察觉到任何差异。OpenStack的虚机迁移是基于Libvirt实现的,下面来看看Openstack虚机热迁移的具体代码实现。

首先,由API入口进入到nova/api/openstack/compute/contrib/admin_actions.py

@wsgi.action('os-migrateLive')
  def _migrate_live(self, req, id, body):
    """Permit admins to (live) migrate a server to a new host."""
    context = req.environ["nova.context"]
    authorize(context, 'migrateLive')

    try:
      block_migration = body["os-migrateLive"]["block_migration"]
      disk_over_commit = body["os-migrateLive"]["disk_over_commit"]
      host = body["os-migrateLive"]["host"]
    except (TypeError, KeyError):
      msg = _("host, block_migration and disk_over_commit must "
          "be specified for live migration.")
      raise exc.HTTPBadRequest(explanation=msg)

    try:
      block_migration = strutils.bool_from_string(block_migration,
                            strict=True)
      disk_over_commit = strutils.bool_from_string(disk_over_commit,
                             strict=True)
    except ValueError as err:
      raise exc.HTTPBadRequest(explanation=str(err))

    try:
      instance = self.compute_api.get(context, id, want_objects=True)
      self.compute_api.live_migrate(context, instance, block_migration,
                     disk_over_commit, host)
    except (exception.ComputeServiceUnavailable,
        exception.InvalidHypervisorType,
        exception.UnableToMigrateToSelf,
        exception.DestinationHypervisorTooOld,
        exception.NoValidHost,
        exception.InvalidLocalStorage,
        exception.InvalidSharedStorage,
        exception.MigrationPreCheckError) as ex:
      raise exc.HTTPBadRequest(explanation=ex.format_message())
    except exception.InstanceNotFound as e:
      raise exc.HTTPNotFound(explanation=e.format_message())
    except exception.InstanceInvalidState as state_error:
      common.raise_http_conflict_for_instance_invalid_state(state_error,
          'os-migrateLive')
    except Exception:
      if host is None:
        msg = _("Live migration of instance %s to another host "
            "failed") % id
      else:
        msg = _("Live migration of instance %(id)s to host %(host)s "
            "failed") % {'id': id, 'host': host}
      LOG.exception(msg)
      # Return messages from scheduler
      raise exc.HTTPBadRequest(explanation=msg)

    return webob.Response(status_int=202)

   这里第一行可以看到是与API文档的第二行照应的:
  

 {
  "os-migrateLive": {
    "host": "0443e9a1254044d8b99f35eace132080",
    "block_migration": false,
    "disk_over_commit": false
  }
}

好了,源码中其实执行迁移工作的就是第26、27行的一条语句:

self.compute_api.live_migrate(context, instance, block_migration,
                 disk_over_commit, host)

由这句进入到nova/compute/api.py中,源码如下:

@check_instance_cell
  @check_instance_state(vm_state=[vm_states.ACTIVE])
  def live_migrate(self, context, instance, block_migration,
           disk_over_commit, host_name):
    """Migrate a server lively to a new host."""
    LOG.debug(_("Going to try to live migrate instance to %s"),
         host_name or "another host", instance=instance)

    instance.task_state = task_states.MIGRATING
    instance.save(expected_task_state=[None])

    self.compute_task_api.live_migrate_instance(context, instance,
        host_name, block_migration=block_migration,
        disk_over_commit=disk_over_commit)

第2行是一个装饰器,用于在进入API方法之前,检测虚拟机和/或任务的状态, 如果实例处于错误的状态,将会引发异常;接下来实时迁移虚机到新的主机,并将虚机状态置于“migrating”,然后由12行进入nova/conductor/api.py

def live_migrate_instance(self, context, instance, host_name,
                block_migration, disk_over_commit):
     scheduler_hint = {'host': host_name}
     self._manager.migrate_server(
       context, instance, scheduler_hint, True, False, None,
       block_migration, disk_over_commit, None)

将主机名存入字典scheduler_hint中,然后调用nova/conductor/manager.py方法migrate_server,

def migrate_server(self, context, instance, scheduler_hint, live, rebuild,
      flavor, block_migration, disk_over_commit, reservations=None):
    if instance and not isinstance(instance, instance_obj.Instance):
      # NOTE(danms): Until v2 of the RPC API, we need to tolerate
      # old-world instance objects here
      attrs = ['metadata', 'system_metadata', 'info_cache',
           'security_groups']
      inst[B\[HX\]BX\HY][[H^[B^XYK\]KX[YX\]WY][B\[HZY][YYKZY][B\[HZY]W]N[\[Y[][XX\[\BBBY[XY]]WY][^[[\B]X\]ZY][BZY]W]JCBBOB]B/*y+yn 9.*"liz/c9y]WY][iyi&..+*X\]ycy\Z[ZY]U{iyk.d.Z[khyb,9k!.B]n 9.*"liz/c9y'[\
\x'{/,y+c9y]WY][B]WY][i&..+*X\]ycy\Z[ZY]U{iyk.d.Z[khyb,9k!.Byg*9"l.+z, ]WY][y&BB]\HHBH\H\NBY]WY][^[[\]BX\]ZY][Q[BZY]W]OSJNB]HZY][BB\[H^]H^B\[H[[BK[[^K[[[[XB[[X]\ZY]YB\[H\\[][B\[H]B\][Y]B^XYK\]KX[Y]WY][B\[HX\]BX\HY][[H^[B^XYK\]KX[YX\]WY][B\[HZY][YYKZY][B\[HZY]W]N[\[Y[][XX\[\BB]HZY][BNBYZY][BY\HX\ZY][Y]
	B[BY\HX\]WY][Y]
	BY[H]]X\\

JH[Y\CBX[HHYX[XHNKY[BBHW[YJ[[[YHJCBZY]UJX\]WY][H	H\BX[KBKBX\]WY][[
CBB^^[\NB^[W\Z\[
NB\]HZY][Z[\N	\KKB[[Z[[CBX\]^[[\ZY][CBB][\][]WY][B[Y\H[[^Y[\[[[
SJCBOB]B]\HHBH\H\NBYZY][BY\HX\ZY][Y]
	OB]B/*#e!%#ZY][Y*cl9k.by...ge/! B]\HHBH\H\NB[BY\HX\]WY][Y]
	BY[H]]X\\

JH[Y\CBX[HHYX[XHNKY[BOB]B/!#!%#]WY][Y*cl9k.by.k:/! B]\HHBH\H\NBHW[YJ[[[YHJOOB]B.ykkk/(X\9ghxB]\HHBH\H\NB[Y\H[[^Y[\[[[
SJOOB]B#byoyk9$9k9 B/ z`!!i9gB."l,y+j:`yk{n#9&)9ki.h9"y`9n+b{.g&i&i&+/c.
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP