标签:ec2 计算 api 通过 加载 虚拟 pow 释放 confirm
OpenStack创建一个虚拟机,涉及到三种状态,vm_state,task_state和power_state。
先总结几点:
Power_state是我们调用虚拟机中驱动获得的一个状态,事实上hypervisor的状态才是权威的。数据库中power_state只是之前状态的一个快照,
会被周期性更新,并且在有任务改变了power_state后要更新数据库。
1、怎样更新?
通常是”自下而上“,由计算节点产生,重写数据库。这个更新过程可能引起和vm_state的一致性冲突,如下。
2、power_state命名惯例
取决于ibvirt返回的状态。
废弃的状态:
BLOCKED,本质上应该是RUNNING;
SHUTOFF,现在是SHUTDOWN;
FAILED,现在是NOSTATE。
vm_sate描述虚拟机当前稳定状态,而非过渡状态。如果没有running_tasks,虚拟机就应该是用户期待的状态,比如active。ACTIVE是一个vm_state,因为它代表虚拟机正常运行;而SUSPENDING是一个过渡状态,代表n秒后虚拟机将被挂起,所以应该属于task_state。
1、vm_stae怎样更新
vm_state仅在任务结束后更新,即当一个任务成功结束并且设置task_state状态为None。
当有API调用时,vm_state永远不能改变。如果任务失败,并且合适的清理后(比如live迁移失败,任务回滚,虚拟机在源节点正常运行),虚拟机状态不变。如果任务失败并且不能回滚,vm_state状态被置为ERROR。
2、vm_state命名惯例:使用一个形容词
3、vm_state和power_state关系?
二者不是一一映射,代表的侧重点不同,不能通过推理从一个得到另一个,所以都是需要的。
比如,当你去修复一个虚拟机,虚拟机从一个rescue镜像启动,此时power_state状态为RUNNING,但是vm_state状态只能是RESCUED。单单靠power_state是不能确定vm_state是ACTIVE还是RESCUED。
4、power_state和vm_state状态不一致,如何修正?
首先,有正在运行的任务时,vm_state和power_state极有可能不同,因为vm_state代表一个稳定状态,在任务运行期间,状态是过度状态,vm_state本来就是过期的。
当没有任务运行时,power_state和vm_state应该保持一致,除非出错或者失败,这种情况,要具体分析。
a、如果power_state=SHUTOFF,但是vm_state=ACTIVE,极有可能是虚拟机内部shotdown命令出错,所以power_state正确。一个粗暴但等价的方法,手动调用一个内部方法stop()API,虚拟机应该被修正为STOPPED。
b、如果power_state=BLOCKED,vm_state=HARD_DELETED,代表用户已经要求删除虚拟机但是过程失败了。所以尝试再次删除。
c、如果power_state=BLOCKED,vm_state=PAUSED,代表可能是pause()方法调用前出了不可预料的问题。此时修正方法就看怎样对用户最友好了,maybe设置vm_state为ERROR。
到此,会发现 _sync_power_states (同步电源状态)不鸟正在执行的任务,可能导致奇怪的错误。
5、如何从vm_state中获得和EC2等价的状态?
ec2状态包含稳定状态和过渡状态。所以需要同时根据task_state和vm_state来推断ec2状态。
vm_state如下:
vm_state中废弃的状态REBUILDING,MIGRATING,RESIZING都放在了task_state中。而SHUTOFF不用了,因为这个状态很费解,应该根据shutdown_terminate标记被划分到STOPPED或者DELETED。
task_state代表过渡状态,和一个computeAPI紧密相关,表明虚拟机当前执行哪个任务。处于vm_state的虚拟机是不会有task_state,只有正在运行的进程有task_state。
1、特定任务:force_delete(或者hard delete)
虚拟机什么时候都能成功删除。用户删除虚拟机可以释放配额里更多资源,不再被收费。不幸的是,可能出现这种情况,一个前置任务卡住了所以task_state永远不能到None,或者虚拟驱动在销毁虚拟机时卡住了,再或者计算节点因为网络/硬件的原因不可用而无法执行销毁虚拟机操作。所以,不应该等到force_delete() 任务获得计算节点然后更新虚拟机状态为HARD_DELETED。而应该是说,vm_state立马更新而不去检查计算节点。换句话说,force_delete() 任务是一个纯粹的数据库操作。一些善后工作(真正的清除工作)随后进行,也不需要power_state和vm_state之间的一致性操作,因为它们会被定期触发。
2、如何更新?
task_state被设置当确认它是虚拟机上唯一执行的任务时。要做到原子更新,任务开始会生成一个独一无二的task_id(uuid格式)和虚拟机id关联。如果虚拟机已经有一个VM id,说明已经有别的任务在运行。在任务执行过程中,task_id通过RequestContext数据格式传播。在任务执行中途如果要更新ask_state,必须确认虚拟机的task_id匹配当前执行任务的id,否则新任务抢占当前任务(目前只有force_delete)。当任务成,task_state置为None,同时task_id置为None。
因为hard delete是唯一一个可以抢占其他任务的任务,我们没必要立即设置task_id,但是需要检查vm_state以确认它不是HARD_DELETE而不是去检查task_id是否匹配。
3、真的要分开vm_state和task_state吗?
从技术上讲,虚拟机状态(稳定)和任务状态(过渡)没有交集,可以组合使用。分开最大的好处就是状态转换图简单得多——只要考虑vm_state之间的DFA。如果需要增加一个新task_state,状态转换图保持不变。
4、命名变化
最好用动词+”ing“来描述task_state,且这个动词是compute API方法。任务执行期间,task_state不变。要表述任务的进展,应该使用一个单独的领域,而不是简化状态机。
废弃的状态:
RESIZE_VERIFY不是一个过渡状态,而是稳定状态。变成了vm_state中的新状态RESIZED。
参考:
https://wiki.openstack.org/wiki/VMState
http://docs.openstack.org/developer/nova/devref/vmstates.html#preconditions-for-commands
标签:ec2 计算 api 通过 加载 虚拟 pow 释放 confirm
原文地址:http://www.cnblogs.com/zhangyuhang3/p/6910567.html