Nova虚拟机状态简介
每个虚拟机都有vm_states, task_states, and power_states这三个状态。他们用起来比较复杂。有些状态很费解,有时也很难理解。增加一个新的状态时缺少指导文件。为了简化一些事情,我们需要明确的定义他们是什么意思,我们为什么需要他们。一个新的删除虚拟机的操作也正在讨论中。
总结:
a) power_state是hypervisor的状态,是从计算节点来的。
b) vm_state是基于api的一种稳定状态,和用户体验有关。
c) tast_state是api调用过程中的过度状态。
d) 数据库可用时,硬删除虚拟机是可以的。
e) power_state和vm_state会有冲突,这需要按照实际情况来解决。
power_state
power_state是我们从虚拟机驱动(hypervisor)上获取的一个虚拟机的状态。hypervisor上虚拟机的状态时权威的,power_state在数据库中的状态应该被视为之前状态的一个快照。可以周期性的改变状态,如果一个任务会影响到power_state,那么在任务结束的时候应该更新powe_state的值。
1. 怎么更新?
由计算节点产生,覆盖数据库中的值。更新动作可能会触发和vm_state的一致性过程。
2. 名字约定
和libvirt中得到状态有关。废弃的状态:BLOCKED,现在是RUNNING; SHUTOFF,现在是SHUTDOWN;FAILED,现在是NOSTATE。
vm_state
vm_state描述了虚拟机的稳定状态,而不是过度状态。这就表示,如果正在调用计算API(running tasks),vm_state会变成用户期望得到的一种状态。举个例子:ACTIVE,意味着虚拟机运行良好;SUSPENDING,是一个过度状态,表示虚拟机正在暂停,几秒钟后会完成变成暂停状态(suspended)。过度状态属于tast_state。
1. 怎么更新?
vm_state只有在任务成功完成时才会更新,并且会设置task_state为None。如果没有api调用,vm_state永远不会更新。如果任务失败,但是适当的清除了(e.g. 动态迁移失败,通过回滚,虚拟机在原来的节点上运行得很好),虚拟机状态不会改变,如果任务失败,并且没有成功回滚,vm_state会变成ERROR。
2. 名字约定:vm_state的形容词。
3. vm_state和power_state的关系?
这里没有一对一的关系,他们展现的是不同的信息。不能从其中任何一个区判断另外一个。
例如:当你救援一台虚拟机的时候,虚拟机应该从一个rescue镜像启动。power_state会变成RUNNING,或者是BLOCKED。但是vm_state仅仅是RESCUED。仅仅通过power_state,你无法知道vm_state是ACTIVE或者是RESCUED。
4. 当power_state和vm_state不一致时,如何保证一致性。
首先,如过有一个任务正在进行,power_state和vm_state可能会不一样。这是因为vm_state表示的是一个稳定的状态。在任务执行过程中,状态时过度的,很快会成为过去式。如果没有正在执行的任务,那么power_state and vm_state应该是一致的,除非发生错误。出现这样的情况,需要按照实际情况解决。例如:
a) power_state为SHUTOFF,但是vm_state是ACTIVE,如果在虚拟机内部使用shutdow就会出现这种情况。所以power_state这种状态时正确的。这相当于调用stop()的时候,vm_state会变成STOPPED。
b) power_state为BLOCKED,但是vm_state是PAUSED,这表示拥护已经调用了删除虚拟机的api,但是失败了,这时你需要再次删除。
c) power_state为BLOCKED,但是vm_state是HARD_DELETED,这意味着在调用pause()之前,发生了不可预料的错误。FIXME:在这个案例中,设置成什么状态更娇友好?设置为ERROR?(_sync_power_states不会影响正在进行的任务,也可能会导致奇怪动作)
5. 从vm_state中,如何获取EC2相关的状态?
ec2状态包含了稳定(e.g. running)和过度状态(e.g. pending,shutting-down)。你需要结合vm_state和task_state来推导ec2 state。
vm_state的状态:
INITIALIZED:虚拟机仅仅数据库中创建,还没正在开始创建。
ACTIVE:虚拟机正在运行,使用特定的镜像。
RESCUED:虚拟机正在运行,使用rescue 镜像。
PAUSED:虚拟机暂停,依然占用计算和内存资源。
SUSPEND:虚拟机暂停,但是不占用计算和内存资源。
STOPPED:虚拟机停止了,镜像依然在磁盘上。
SOFT_DELETED:虚拟机不在运行,磁盘镜像依然保存,可以恢复。
HARD_DELETED:从配额和计费的角度看,虚拟机不再存在了,包括磁盘镜像。
RESIZED(迁移):虚拟机在源节点上停止,在目的节点上运行。虚拟机的镜像在两个地方存在。用户可能会选择调整或恢复虚拟机(和老的task_state,RESIZE_VERIFY的功能一样)。
ERROR:发生了一些无法恢复的错误,只可以删除虚拟机。
一些老的状态:REBUILDING, MIGRATING, RESIZING存在于task_state中。SHUTOFF已经没有了。这是个比较费解的状态,应该和STOPPED or DELETED有关。
tast_state
tast_state是一种过渡状态,和计算API紧密相关,表示虚拟机正在运行什么任务。处于vm_state的虚拟机是不会有task_state,只有正在运行的进程有task_state。
1) 特殊任务:force_delete (or hard delete)
永远可以删除虚拟机。用户可以释放更多的资源,以免收费。不幸的是,这可能导致之前的任务卡住,所以task_state就不会变为None。虚拟机驱动也可能在删除虚拟机的时候卡住。因为网络或是硬件原因,计算节点也可能无法执行删除虚拟机的任务。所以,我们需要等待force_delete()任务,直到vm_state的状态变为HARD_DELETED。相反,vm_state的状态会立即更新,不会等待计算节点完成。换句话说,force_delete()任务仅仅是完成数据库的操作。真正的清除操作会在他之后,这个和power_state和vm_state之间的一致性操作是没有区别的,他们会定期的被触发。
2) 怎么更新?
正在对虚拟机执行特定任务时,就可以设置task_state。为了自动更新,任务开始的时候会产生一个task_id(uuid格式),这个id和虚拟机id相关联。如果虚拟机已经有了task_id,那么说明有另外一个任务正在执行。在任务执行过程中,task_id是通过RequestContext数据结构来传递的。为了在任务过程中更新task_state,必须保证虚拟机的task_id和当前task_id一致。否则当前任务会被取代(现在只可能会发生在force_delete的时候)。任务结束时,task_state和task_id都会设置为None。
因为hard delete是唯一一个可能取代其他任务的,所以我们没必要立即设置task_id。但是我们需要确认vm_state不为HARD_DELETED,而不是检查task_id。
3)我们需要将vm_state和task_state分开吗?
技术上,vm_state(稳定状态)和task_state(过度状态)是分开的,但是你可以把他们呢结合起来。分开最大的好处就是,状态转移图比较简单——你只要考虑vm_state之间的DFA。
空间也很小。如果需要增加一个新的task_state,状态转移图不需要改变。
4) 名字变化
动词+”ing”用来描述task_state,动词是计算api的方法。在任务执行过程中,task_state从未改变。为了描述任务的过程,会使用一个单独的域来简化状态机制。
None: no task is currently in progress BUILDING IMAGE_SNAPSHOTTING IMAGE_BACKINGUP UPDATING_PASSWORD PAUSING UNPAUSING SUSPENDING RESUMING DELETING STOPPING STARTING RESCUING UNRESCUING REBOOTING REBUILDING POWERING_ON POWERING_OFF RESIZING RESIZE_REVERTING RESIZE_CONFIRMING SCHEDULING BLOCK_DEVICE_MAPPING NETWORKING SPAWNING RESIZE_PREP RESIZE_MIGRATING RESIZE_MIGRATED RESIZE_FINISH
废弃的:RESIZE_VERIFY不是一个过渡状态,而是一个稳定状态。现在由RESIZED代替。
真实的状态机制图解:
work in progress……
URL: http://cloudops.sinaapp.com/?p=345
注:
在nova.compute.task_state 定义多种状态的性质,请参考
所有评论(0)