Nova resize过程中虚拟机vm_state与task_state变化与消息发送顺序

Resize简介

Nova resize的主要作用,是替换Openstack虚拟机的规格,其中包含了磁盘大小、vcpu、内存、额外规格设置(如az的调度选择等)。

Resize准备阶段

resize 开始时,进入 nova.compute.api.py 的 resize 函数:

1
2
3
4
instance = self.update(context, instance,
task_state=task_states.RESIZE_PREP,
expected_task_state=None,
progress=0, kwargs)

发送一个消息:

1
compute.instance.update (由 nova-api 发送)

此时:

1
2
vm_state 不变("active")
task_state=task_states.RESIZE_PREP ("resize_prep")

由 resize 函数中进入 nova.compute.manager.py 的 prep_resize 函数, prep_resize 的 start 阶段:

1
2
3
4
compute_utils.notify_usage_exists(
context, instance, current_period=True)
self._notify_about_instance_usage(
context, instance, "resize.prep.start")

发送两个消息:

1
2
compute.instance.exists (由 nova-compute 发送)
compute.instance.resize.prep.start (由 nova-compute 发送)

此时:

1
2
vm_state 不变("active")
task_state=task_states.RESIZE_PREP ("resize_prep")

prep_resize 函数通过 rpc 调用 resize_instance 函数,调用请求发送之后,进入 prep_resize 的 end 阶段:

1
2
3
self._notify_about_instance_usage(
context, instance, "resize.prep.end",
extra_usage_info=extra_usage_info)

发送一个消息:

1
compute.instance.resize.prep.end (由 nova-compute 发送)

此时:

1
2
vm_state  不变(" active ")
task_state=task_states.RESIZE_PREP ("resize_prep")

Resize正式开始

prep_resize 结束之后进入 nova.compute.manager.py 的 resize_instance 函数,也就是 resize start 阶段:

1
2
3
4
5
6
self._instance_update(context, instance['uuid'],
task_state=task_states.RESIZE_MIGRATING,
expected_task_state=task_states.RESIZE_PREP)

self._notify_about_instance_usage(
context, instance, "resize.start", network_info=network_info)

发送两个消息:

1
2
compute.instance.update (由 nova-compute 发送)
compute.instance.resize.start (由 nova-compute 发送)

此时:

1
2
vm_state 不变("active")
task_state=task_states.RESIZE_MIGRATING ("resize_migrating")

Resize完成阶段

resize_instance 函数通过 rpc 调用 finish_resize ,调用请求发送之后,进入 resize end 阶段:

1
2
3
4
5
6
7
8
self._instance_update(context, instance['uuid'],
host=migration_ref['dest_compute'],
task_state=task_states.RESIZE_MIGRATED,
expected_task_state=task_states.
RESIZE_MIGRATING)

self._notify_about_instance_usage(context, instance, "resize.end",
network_info=network_info)

发送两个消息:

1
2
compute.instance.update (由 nova-compute 发送)
compute.instance.resize.end (由 nova-compute 发送)

此时:

1
2
vm_state 不变("active")
task_state=task_states.RESIZE_MIGRATED ("resize_migrated")

进入 nova.compute.manager.py 的 finish_resize 函数,实际执行者是_ finish_resize 函数, finish_resize start 阶段:

1
2
3
4
5
6
7
self._instance_update(context, instance['uuid'],
task_state=task_states.RESIZE_FINISH,
expected_task_state=task_states.RESIZE_MIGRATED)

self._notify_about_instance_usage(
context, instance, "finish_resize.start",
network_info=network_info)

finish_migration 之前:

1
2
compute.instance.update (由 nova-compute 发送)
compute.instance.finish_resize.start (由 nova-compute 发送)

此时:

1
2
vm_state 不变("active")
task_state=task_states.RESIZE_FINISH ("resize_finish")

当调用 libvirt driver 的 finish_migration 之后:

1
2
3
4
5
6
7
8
9
10
11
instance = self._instance_update(context,
instance['uuid'],
vm_state=vm_states.RESIZED,
launched_at=timeutils.utcnow(),
task_state=None,
expected_task_state=task_states.
RESIZE_FINISH)

self._notify_about_instance_usage(
context, instance, "finish_resize.end",
network_info=network_info)

发送两个消息:

1
2
compute.instance.update (由 nova-compute 发送)
compute.instance.finish_resize.end (由 nova-compute 发送)

此时:

1
2
vm_state  = resized 
task_state = None

Resize确认阶段

这个时候进入 confirm 阶段,由周期任务查询虚拟机,如果发现虚拟机的状态为 resized ,则调用 nova.compute.manager.py 的 confirm_resize 函数:

以下为 nova.compute.manager.py 的 _poll_unconfirmed_resizes 函数,即用于检查 confirm 的周期任务:

1
2
3
4
5
6
7
8
9
10
11
12
if vm_state != vm_states.RESIZED or task_state is not None:
reason = _("In states %(vm_state)s/%(task_state)s, not"
"RESIZED/None")
_set_migration_to_error(migration_id, reason % locals(),
instance=instance)
continue
try:
self.compute_api.confirm_resize(context, instance)
except Exception, e:
msg = _("Error auto-confirming resize: %(e)s. "
"Will retry later.")
LOG.error(msg % locals(), instance=instance)

从 nova.compute.api.py 的 confirm_resize 进入 confirm start 阶段:

1
2
3
4
5
6
7
8
instance = self.update(context, instance, vm_state=vm_states.ACTIVE,
task_state=None,
expected_task_state=None)

self.compute_rpcapi.confirm_resize(context,
instance=instance, migration_id=migration_ref['id'],
host=migration_ref['source_compute'],
reservations=reservations)

发出一个消息:

1
compute.instance.update (由 nova-api 发送)

此时:

1
2
vm_state = active
task_state = None

并进入 nova.compute.manager.py 的 confirm_resize 函数:

1
2
3
4
5
self._notify_about_instance_usage(context, instance,
"resize.confirm.start")
self._notify_about_instance_usage(
context, instance, "resize.confirm.end",
network_info=network_info)

发出两个消息:

1
2
compute.instance.resize.confirm.start (由 nova-compute 发送)
compute.instance.resize.confirm.end (由 nova-compute 发送)

此时:

1
2
vm_state 不变("active")
task_state = None