Openstack liberty中也支持对云主机执行快照,快照是备份系统中一种常用的数据保护技术,在生产系统故障后,能通过快照将系统快速恢复到快照时间点;那Openstack中的云主机快照是否也支持这种故障恢复呢?请看下文:
Openstack支持对处于运行或者停止状态的云主机执行快照,另外Openstack既可以从镜像启动云主机,也可以从启动磁盘启动云主机,根据条件组合,可以执行下面4中快照:
- 镜像启动云主机的离线快照
- 镜像启动云主机的在线快照
- 磁盘启动云主机的离线快照
- 磁盘启动云主机的在线快照
Openstack是否支持上述4种快照组合方式呢? 下文将为您解答。
预计文章篇幅会很长,准备用两篇博文来分析具体的快照过程,本文是第一篇:分析从镜像启动云主机的离线/在线快照过程,下面来看具体内容:
镜像启动云主机的离线快照
通过Openstack Dashboard
或者nova
命令可以发起快照,如下:
//快照命令格式:nova image-create {server} {name}
//下面的命令对id=814a8ad8-9217-4c45-91c7-c2be2016e5da的云主机执行快
//照,快照名称为snapshot1
# nova image-create 814a8ad8-9217-4c45-91c7-c2be2016e5da snapshot1
nova-api
部分
根据nova-api
启动时设置的路由,我们可以很容易的知道快照函数入口是:
nova/api/openstack/compute/servers.py/ServersController._action_create_image
, 下面一起来看看代码:
def _action_create_image(self, req, id, body):
"""Snapshot a server instance.
输入参数如下:
req = Request对象,包含本次请求的上下文
id = 814a8ad8-9217-4c45-91c7-c2be2016e5da
body = {u'createImage': {u'name': u'snapshot1', u'metadata': {}}}
"""
#得到请求上下文,并执行权限验证
context = req.environ['nova.context']
authorize(context, action='create_image')
#从body中分解出快照名及属性
#image_name = 'snapshot1'
#metadata = {}
entity = body["createImage"]
image_name = common.normalize_name(entity["name"])
metadata = entity.get('metadata', {})
#从nova数据库中获取实例信息,包括:metadata,system_metadata
#security_groups,info_cache,flavor及pci_devices等属性信息
#返回InstanceV2对象
instance = self._get_server(context, req, id)
#数据库中获取该实例关联的所有块设备,返回BlockDeviceMappingList对
#象
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
context, instance.uuid)
"""下文省略try{ }except异常处理代码"""
#这里判断系统磁盘类型是否是volume,如果是,说明是从磁盘启动的实例
#这种类型的快照,在下一篇博文中分析,敬请期待
if self.compute_api.is_volume_backed_instance(context, instance,
bdms):
authorize(context, action="create_image:allow_volume_backed")
image = self.compute_api.snapshot_volume_backed(
context,
instance,
image_name,
extra_properties=
metadata)
#镜像启动的实例,执行快照走这个分支,调用:nova/compute/api.py/API
#执行快照,下文具体分析
else:
image = self.compute_api.snapshot(context,
instance,
image_name,
extra_properties=metadata)
# build location of newly-created image entity
image_id = str(image['id'])
#根据glance.conf配置,生成镜像url,我的例子中是:
#http://$glance_host:$glance_port/images/'ffb841fd-d5f8-
#4146-bb29-b12eb5bbf6b2'
image_ref = glance.generate_image_url(image_id)
resp = webob.Response(status_int=202)
resp.headers['Location'] = image_ref
return resp
--------------------------------------------------------------
#接上文: nova/compute/api.py/API.snapshot
def snapshot(self, context, instance, name, extra_properties=None):
"""context 请求上下文
instance InstanceV2实例对象
name 快照名 ‘snapshot1’
extra_properties 快照属性 {}
"""
"""在glance数据库(images表)中添加一条类型为'snapshot'的条目,每
个properties属性作为一条记录添加到image_properties表;
{
'status': u'queued',
'name': u'snapshot1',
'deleted': False,
'container_format': u'bare',
'created_at': datetime.datetime(2016, 6, 22, 7, 26, 29,
tzinfo=<iso8601.Utc>),
'disk_format': u'raw',
'updated_at': datetime.datetime(2016, 6, 22, 7, 26, 29,
tzinfo=<iso8601.Utc>),
'id': u'ffb841fd-d5f8-4146-bb29-b12eb5bbf6b2',
'owner': u'25520b29dce346d38bc4b055c5ffbfcb',
'min_ram': 0,
'checksum': None,
'min_disk': 20,
'is_public': False,
'deleted_at': None,
'properties': {
u'image_type': u'snapshot',
u'instance_uuid': u'814a8ad8-9217-4c45-91c7-c2be2016e5da',
u'user_id': u'b652f9bd65844f739684a20ed77e9a0f',
u'base_image_ref': u'e0cc468f-6501-4a85-9b19-70e782861387'
},
'size': 0
}
"""
image_meta = self._create_image(context, instance, name,
'snapshot',
extra_properties=extra_properties)
#更新实例的任务状态:镜像快照等待中
inst