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. Ext.Net 学习随笔 001 安装Ext.Net

    Ext.Net版本:4.1.0 Ext.Net官网:ext.net Ext.Net官方演示:mvc.ext.net Ext.Net MVC Example 下载:github.com/extnet/E ...

  2. C# SqlBulkCopy

    public void Insert_Table(System.Data.DataTable dataTable)        {            try            {       ...

  3. HTML 表格

    HTML 表格:表格由<table>标签来定义,行数由<tr>标签来定义,单元格由<td>标签来定义:<table border="1"& ...

  4. (转) WTF is computer vision?

        WTF is computer vision? Posted Nov 13, 2016 by Devin Coldewey, Contributor   Next Story   Someon ...

  5. CentOS7关闭防火墙方法

    在之前的版本中关闭防火墙等服务的命令是 service iptables stop /etc/init.d/iptables stop 在RHEL7中,其实没有这个服务 [root@rhel7 ~]# ...

  6. Arcgis 图层编辑器“粘贴”功能菜单灰色不能使用的问题与解决办法

    本人由win7系统更换为win10系统,平常使用的arcgis10.2升级使用10.3版本,相应的VS2012也升级使用2013版本,但是在安装了之后发现"Editor"编辑工具中 ...

  7. appium 环境搭建 java

    1 安装node.js 1.1 安装node.js http://nodejs.cn/download/ 1.2.下载后直接点击exe,按照提示一步一步的安装 1.3 安装成功后,运行cmd,输入no ...

  8. java1234教程系列笔记 S1 Java SE chapter 02 lesson 03 java基本数据类型

    第二章 第三节 数据类型 3.1 分类 基本数据类型.引用类型 3.2整型 byte 8 short 16 int  32 long 64 作业: A:1-10求和 B:float double 的最 ...

  9. 【java】jackson 中JsonFormat date类型字段的使用

    为了便于date类型字段的序列化和反序列化,需要在数据结构的date类型的字段上用JsonFormat注解进行注解具体格式如下 @JsonFormat(pattern = "yyyy-MM- ...

  10. 14、java中的equals()和toString()方法

    /* 所有对象的父类Object Object中的方法: equals() 对象是否相同的比较方法 toString()对象的字符串表现形式 */ class Person { String name ...