nova instance状态:power_state, vm_state, task_state

2015-09-22 Openstack 185

nova instance有3种状态:power_state, vm_state, task_state,分别对应horizon界面上的Power State,Status,Task

Openstack wiki上有介绍:

  • power_state is the hypervisor state, loaded “bottom-up” from compute worker;
  • vm_state reflects the stable state based on API calls, matching user expectation, revised “top-down” within API implementation.
  • task_state reflects the transition state introduced by in-progress API calls.
  • power_state and vm_state may conflict with each other, which needs to be resolved case-by-case.

Power_state

power_state反映的是hypervisor的状态。目前都是用libvirt作为hypervisor。
例如,nova会调用libvirt api去查询instance的state

[root@node-2 ~]# virsh list --all
Id Name State
----------------------------------------------------
229 instance-00000139 running
230 instance-00000138 running
231 instance-00000137 running
232 instance-00000155 running
- instance-00000136 shut off
- instance-0000013a shut off [root@node-2 ~]# virsh domstate instance-00000136
shut off

在libvirt中,共有几种状态:

  • undefined
  • defined(也叫stopped)
  • running
  • paused
  • saved

具体解释在这里
下图表示在几种状态的转换关系:

Notes:

  • 有的转换依赖于domain(instance)是transient domain还是persistent domain, 如running ---(shutdown)---> defined/undefined。两者的区别在这里。思考:Openstack创建的domain是否都是persistent domain?
  • virsh create创建transient domain;virsh define;virsh start创建、启动persistent domain

How is it updated?

  1. 调hypervisor api取得的状态总是对的;如果nova数据库中的状态与其不一致,那么更新nova数据库。
  2. nova有定时任务来检查、更新power_state
  3. 如果对instance做了操作(task),并且该操作可能影响power_state,那么在该task结束之前需要更新power_state

power_state list

目前(2015/9/21 master)有6种状态:

# nova/compute/power_state.py

# NOTE(maoy): These are *not* virDomainState values from libvirt.
# The hex value happens to match virDomainState for backward-compatibility
# reasons.
NOSTATE = 0x00
RUNNING = 0x01
PAUSED = 0x03
SHUTDOWN = 0x04 # the VM is powered off
CRASHED = 0x06
SUSPENDED = 0x07 # TODO(justinsb): Power state really needs to be a proper class,
# so that we're not locked into the libvirt status codes and can put mapping
# logic here rather than spread throughout the code
STATE_MAP = {
NOSTATE: 'pending',
RUNNING: 'running',
PAUSED: 'paused',
SHUTDOWN: 'shutdown',
CRASHED: 'crashed',
SUSPENDED: 'suspended',
}

Vm_state

vm_state反映基于API调用的一种稳定状态,而task_state反映的是一种瞬时状态。

How is it updated?

  • 只有当一个task(一个compute api call)结束时,才能更新vm_state。
  • 如果成功则同时设置task_state=None,如果失败,vm_state可能不变(task支持rollback),也可能设置为ERROR。

vm_state list

# nova/compute/vm_states.py

ACTIVE = 'active'        # VM is running
BUILDING = 'building' # VM only exists in DB
PAUSED = 'paused'
SUSPENDED = 'suspended' # VM is suspended to disk.
STOPPED = 'stopped' # VM is powered off, the disk image is still there.
RESCUED = 'rescued' # A rescue image is running with the original VM image attached.
RESIZED = 'resized' # a VM with the new size is active. The user is expected to manually confirm or revert. SOFT_DELETED = 'soft-delete' # VM is marked as deleted but the disk images are still available to restore.
DELETED = 'deleted' # VM is permanently deleted. ERROR = 'error' SHELVED = 'shelved' # VM is powered off, resources still on hypervisor
SHELVED_OFFLOADED = 'shelved_offloaded' # VM and associated resources are not on hypervisor ALLOW_SOFT_REBOOT = [ACTIVE] # states we can soft reboot from
ALLOW_HARD_REBOOT = ALLOW_SOFT_REBOOT + [STOPPED, PAUSED, SUSPENDED, ERROR] # states we allow hard reboot from

Task_state

task_state反映了基于API调用的瞬时状态。
它表示instance当前处于某个API调用中的某个阶段,比vm_state更细化,让用户了解某个action/task执行到哪个步骤了,比如创建instance时会有scheduling -> block_device_mapping -> networking -> spawning。但调用完之后设置为None。

task_state list

# nova/compute/task_states.py
"""Possible task states for instances. urrent moment. These tasks can be generic, such as 'spawning', or specific,
such as 'block_device_mapping'. These task states allow for a better view into
what an instance is doing and should be displayed to users/administrators as
necessary. """ # possible task states during create()
SCHEDULING = 'scheduling'
BLOCK_DEVICE_MAPPING = 'block_device_mapping'
NETWORKING = 'networking'
SPAWNING = 'spawning' # possible task states during snapshot()
IMAGE_SNAPSHOT = 'image_snapshot'
IMAGE_SNAPSHOT_PENDING = 'image_snapshot_pending'
IMAGE_PENDING_UPLOAD = 'image_pending_upload'
IMAGE_UPLOADING = 'image_uploading' # possible task states during backup()
IMAGE_BACKUP = 'image_backup' # possible task states during set_admin_password()
UPDATING_PASSWORD = 'updating_password' # possible task states during resize()
RESIZE_PREP = 'resize_prep'
RESIZE_MIGRATING = 'resize_migrating'
RESIZE_MIGRATED = 'resize_migrated'
RESIZE_FINISH = 'resize_finish' # possible task states during revert_resize()
RESIZE_REVERTING = 'resize_reverting' # possible task states during confirm_resize()
RESIZE_CONFIRMING = 'resize_confirming' # possible task states during reboot()
REBOOTING = 'rebooting'
REBOOT_PENDING = 'reboot_pending'
REBOOT_STARTED = 'reboot_started'
REBOOTING_HARD = 'rebooting_hard'
REBOOT_PENDING_HARD = 'reboot_pending_hard'
REBOOT_STARTED_HARD = 'reboot_started_hard' # possible task states during pause()
PAUSING = 'pausing' # possible task states during unpause()
UNPAUSING = 'unpausing' # possible task states during suspend()
SUSPENDING = 'suspending' # possible task states during resume()
RESUMING = 'resuming' # possible task states during power_off()
POWERING_OFF = 'powering-off' # possible task states during power_on()
POWERING_ON = 'powering-on' # possible task states during rescue()
RESCUING = 'rescuing' # possible task states during unrescue()
UNRESCUING = 'unrescuing' # possible task states during rebuild()
REBUILDING = 'rebuilding'
REBUILD_BLOCK_DEVICE_MAPPING = "rebuild_block_device_mapping"
REBUILD_SPAWNING = 'rebuild_spawning' # possible task states during live_migrate()
MIGRATING = "migrating" # possible task states during delete()
DELETING = 'deleting' # possible task states during soft_delete()
SOFT_DELETING = 'soft-deleting' # possible task states during restore()
RESTORING = 'restoring' # possible task states during shelve()
SHELVING = 'shelving'
SHELVING_IMAGE_PENDING_UPLOAD = 'shelving_image_pending_upload'
SHELVING_IMAGE_UPLOADING = 'shelving_image_uploading' # possible task states during shelve_offload()
SHELVING_OFFLOADING = 'shelving_offloading' # possible task states during unshelve()
UNSHELVING = 'unshelving'

task_state state machine diagram (in-progress):
https://docs.google.com/spreadsheets/d/1uvrFI_L86_tBcZGlE2ck3RnMgtsgjIqYVtWTIT9eD8I/edit#gid=3

http://docs.openstack.org/developer/nova/devref/vmstates.html
http://docs.openstack.org/developer/nova/vmstates.html

Code walk-through

nova-compute定义了如下文件:

  • nova/compute/power_state.py
  • nova/compute/vm_states.py
  • nova/compute/task_states.py

nova-api从自身角度定义了vm_state和task_state的对应关系

  • nova/api/openstack/common.py
from nova.compute import task_states
from nova.compute import vm_states _STATE_MAP = {
vm_states.ACTIVE: {
'default': 'ACTIVE',
task_states.REBOOTING: 'REBOOT', # 前面是task_state, 后面是显示在cli/horizon上的'Status'
task_states.REBOOT_PENDING: 'REBOOT',
task_states.REBOOT_STARTED: 'REBOOT',
task_states.REBOOTING_HARD: 'HARD_REBOOT',
task_states.REBOOT_PENDING_HARD: 'HARD_REBOOT',
task_states.REBOOT_STARTED_HARD: 'HARD_REBOOT',
task_states.UPDATING_PASSWORD: 'PASSWORD',
task_states.REBUILDING: 'REBUILD',
task_states.REBUILD_BLOCK_DEVICE_MAPPING: 'REBUILD',
task_states.REBUILD_SPAWNING: 'REBUILD',
task_states.MIGRATING: 'MIGRATING',
task_states.RESIZE_PREP: 'RESIZE',
task_states.RESIZE_MIGRATING: 'RESIZE',
task_states.RESIZE_MIGRATED: 'RESIZE',
task_states.RESIZE_FINISH: 'RESIZE',
},
vm_states.BUILDING: {
'default': 'BUILD',
},
vm_states.STOPPED: {
'default': 'SHUTOFF',
task_states.RESIZE_PREP: 'RESIZE',
task_states.RESIZE_MIGRATING: 'RESIZE',
task_states.RESIZE_MIGRATED: 'RESIZE',
task_states.RESIZE_FINISH: 'RESIZE',
task_states.REBUILDING: 'REBUILD',
task_states.REBUILD_BLOCK_DEVICE_MAPPING: 'REBUILD',
task_states.REBUILD_SPAWNING: 'REBUILD',
},
vm_states.RESIZED: {
'default': 'VERIFY_RESIZE',
# Note(maoy): the OS API spec 1.1 doesn't have CONFIRMING_RESIZE
# state so we comment that out for future reference only.
#task_states.RESIZE_CONFIRMING: 'CONFIRMING_RESIZE',
task_states.RESIZE_REVERTING: 'REVERT_RESIZE',
},
vm_states.PAUSED: {
'default': 'PAUSED',
task_states.MIGRATING: 'MIGRATING',
},
vm_states.SUSPENDED: {
'default': 'SUSPENDED',
},
vm_states.RESCUED: {
'default': 'RESCUE',
},
vm_states.ERROR: {
'default': 'ERROR',
task_states.REBUILDING: 'REBUILD',
task_states.REBUILD_BLOCK_DEVICE_MAPPING: 'REBUILD',
task_states.REBUILD_SPAWNING: 'REBUILD',
},
vm_states.DELETED: {
'default': 'DELETED',
},
vm_states.SOFT_DELETED: {
'default': 'SOFT_DELETED',
},
vm_states.SHELVED: {
'default': 'SHELVED',
},
vm_states.SHELVED_OFFLOADED: {
'default': 'SHELVED_OFFLOADED',
},
} def status_from_state(vm_state, task_state='default'):
"""Given vm_state and task_state, return a status string."""
task_map = _STATE_MAP.get(vm_state, dict(default='UNKNOWN'))
status = task_map.get(task_state, task_map['default'])
if status == "UNKNOWN":
LOG.error(_LE("status is UNKNOWN from vm_state=%(vm_state)s "
"task_state=%(task_state)s. Bad upgrade or db "
"corrupted?"),
{'vm_state': vm_state, 'task_state': task_state})
return status

status_from_state方法看,_STATE_MAP表示vm_state处于某个状态时,所有可能的task_state有哪些,都穷举出来了。这里注意,某些task_state的default值,在nova/compute/task_states.py中没有定义,如:

    vm_states.ACTIVE: {
'default': 'ACTIVE',
...}
vm_states.STOPPED: {
'default': 'SHUTOFF',
...}
vm_states.RESIZED: {
'default': 'VERIFY_RESIZE',
...}
vm_states.ERROR: {
'default': 'ERROR',
...}

给定一对vm_state/task_state,status_from_state能返回一个status字符串,这个status就是cli/horizon上的'Status':

[root@node-129 ~]# nova list | cut -d"|" -f1-6
+--------------------------------------+-------------------------------------------------------+---------+------------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ID | Name | Status | Task State | Power State
+--------------------------------------+-------------------------------------------------------+---------+------------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
| f6d4e67b-885c-4a10-891f-d91675e52bae | 123 | SHUTOFF | - | Shutdown
| 05be07c9-6b2a-4db9-b03b-8322c035816c | 652 | SHUTOFF | - | Shutdown
| 19d1308c-f19b-4860-979f-220fd376ef58 | ITMGMT | SHUTOFF | - | Shutdown
| c496c710-29f8-46c3-90f8-6c2606d4b252 | Winboo-vm | ACTIVE | - | Running
| a27f4030-ece5-4aeb-a84e-70bf0389f81f | abc | ACTIVE | - | Running

比较一下,nova-api列出的"Status"其实比nova-compute的vm_state(14个)多,共20个:

  • ACTIVE
  • REBOOT
  • HARD_REBOOT
  • PASSWORD
  • REBUILD
  • MIGRATING
  • RESIZE
  • BUILD
  • SHUTOFF
  • VERIFY_RESIZE
  • REVERT_RESIZE
  • PAUSED
  • SUSPENDED
  • RESCUE**
  • ERROR
  • DELETED
  • SOFT_DELETED**
  • SHELVED
  • SHELVED_OFFLOADED**
  • UNKNOWN

状态转移

参考:

不同的操作,只有当instance处于特定的vm_state和task_state时才能进行。这个控制不是由nova-api来完成的,而是由nova-compute来决定的:
nova/compute/api.py定义了nova-compute暴露给外部的接口。大多数方法名称就是操作名,如create,restore, shelve, soft_delete

基本上所有方法都用check_instance_state修饰了。这个修饰器限定了该操作在某些vm_state/task_state下才可以进行。比如:

@wrap_check_policy
@check_instance_lock
@check_instance_state(vm_state=[vm_states.SOFT_DELETED])
def restore(self, context, instance):
"""Restore a previously deleted (but not reclaimed) instance.""" @wrap_check_policy
@check_instance_cell
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.STOPPED,
vm_states.PAUSED, vm_states.SUSPENDED])
def snapshot(self, context, instance, name, extra_properties=None):
"""Snapshot the given instance.""" @wrap_check_policy
@check_instance_lock
@check_instance_state(vm_state=set(
vm_states.ALLOW_SOFT_REBOOT + vm_states.ALLOW_HARD_REBOOT),
task_state=[None, task_states.REBOOTING,
task_states.REBOOT_PENDING,
task_states.REBOOT_STARTED,
task_states.REBOOTING_HARD,
task_states.RESUMING,
task_states.UNPAUSING,
task_states.PAUSING,
task_states.SUSPENDING])
def reboot(self, context, instance, reboot_type):
"""Reboot the given instance."""

所以只要查看check_instance_state的参数就能确定操作可行与否。

openstack vm_lifecycle的更多相关文章

  1. 视频 - 在 VirtualBox 中部署 OpenStack

    大家新年好,CloudMan 今天给大家带来一件新年礼物. 一直以来大家都反馈 OpenStack 学习有两大障碍:1. 实验环境难搭2. 体系复杂,难道大今天我就先帮大家解决环境问题.前两天我抽空在 ...

  2. 启用 Open vSwitch - 每天5分钟玩转 OpenStack(127)

    Linux Bridge 和 Open vSwitch 是目前 OpenStack 中使用最广泛的两种虚机交换机技术. 前面各章节我们已经学习了如何用 Linux Bridge 作为 ML2 mech ...

  3. Openstack Periodic Task

    Openstack Periodic Task 周期性任务在各个模块的manager.py(computer,scheduler,cell,network)中添加. 添加方法:在模块manager类实 ...

  4. 超千个节点OpenStack私有云案例(1):CERN 5000+ 计算节点私有云

    CERN:欧洲核子研究组织 本文根据以下几篇文章整理而来: https://www.openstack.org/summit/tokyo-2015/videos/presentation/unveil ...

  5. 完整部署CentOS7.2+OpenStack+kvm 云平台环境(1)--基础环境搭建

    公司在IDC机房有两台很高配置的服务器,计划在上面部署openstack云平台虚拟化环境,用于承载后期开发测试和其他的一些对内业务.以下对openstack的部署过程及其使用做一详细介绍,仅仅依据本人 ...

  6. 添加 Pool Member - 每天5分钟玩转 OpenStack(123)

    我们已经有了 Load Balance Pool "web servers"和 VIP,接下来需要往 Pool 里添加 member 并学习如何使用 cloud image. 先准 ...

  7. 理解 Neutorn LBaaS - 每天5分钟玩转 OpenStack(120)

    Load Balance as a Service(LBaaS)是 Neutron 提供的一项高级网络服务.LBaaS 允许租户在自己的网络中创建和管理 load balancer. load bal ...

  8. 每天5分钟 玩转OpenStack 目录列表

    最近在学习 OpenStack 的相关知识,一直苦于 OpenStack 的体系庞大以及复杂程度,学习没有进度,停滞不前.偶然机会在 51CTO 上发现了一个热点的专题关于 OpenStack 的,题 ...

  9. openstack七大模块概述

    前言 OpenStack主要由七部分组成,分别是Identify, Image, Network, Compute, Block Storage, Object Storage, Dashboard, ...

随机推荐

  1. 自动化测试工具QTP的使用实例 分类: 软件测试 2015-06-17 00:23 185人阅读 评论(0) 收藏

    1. QTP简介 1.1QTP功能与特点 QTP是QuickTest Professional的简称,是一种自动化软件测试工具.在软件的测试过程中,QTP主要来用来通过已有的测试脚本执行重复的手动测试 ...

  2. 基于日志数据分析以防御CC攻击的想法

    1. What - 什么是CC攻击 CC攻击,即针对应用层HTTP协议的DDos攻击,攻击者在短时间内向目标服务器发送大量的HTTP请求,使得服务器会非常繁忙,资源消耗会增加:同时,如果请求中包含基于 ...

  3. JavaScript 常用小功能

    判断一个是否是隐藏状态 $(curid).is(":visible") 响应回车 $("#password").keydown(function (e) {  ...

  4. XML组成结构以及C#通过DTD验证规范性

    XML 文档包含元素和属性等,它们提供一种灵活且功能强大的方法,为应用程序和组织之间交换数据.所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成: 1.元素 元素是XML的主要构建 ...

  5. C++输入输出流格式控制

    来源:http://blog.csdn.net/virtualdesk/article/details/5355793 1.使用控制符控制输出格式 控制符 作用 dec 设置整数的基数为10 hex ...

  6. Elasticsearch【JAVA REST Client】客户端操作

    ES系统作为集群,环境搭建非常方便简单. 现在在我们的应用中,如何对这个集群进行操作呢? 我们利用ES系统,通常都是下面的架构: 在这里,客户端的请求通过LB进行负载均衡,因为操作任何一个ES的实例, ...

  7. C#中双问号、双冒号等几个特殊关键字

    1.@ 这个东东看似和邮件有关啊,但是在C#的世界里,可跟邮件没有一毛钱关系,它是string的女朋友(当然了string有N多女友),二者结合就可以发挥作用了.你可以给它起个名字,叫做“逐字字符串” ...

  8. Eclipse debug高级技巧(转)

    Debug视图 认识debug视图,红色部分框为线程堆栈视图,黄色部分框为表达式.断点.变量视图,蓝色部分为代码视图. 线程堆栈视图 分别介绍一下这几个按钮的含义: 1.表示当前实现继续运行直到下一个 ...

  9. [Spring MVC] - 从数据库读取MessageSource

    Spring MVC中使用MessageSource默认是写在properties文件当中,以支持国际化. 但很多时候我们需要把数据写到数据库当中,而不是在properties文件当中,以方便日常维护 ...

  10. A 最熟悉的陌生人 (纪念当年就读的梅州市江南高级中学)

    最熟悉的陌生人 作者:张慧桥 “枪与玫瑰” 就象瘟98有时会死机天有时会下雨枪有时会走火美国战机有时会掉下来那样,我上网聊天也只是个偶然. 都是栀子那死丫头惹的祸.让每天都觉得是情人节的我那天我自己都 ...