Nova API服务之 创建虚拟机流程(3)
2016-11-01 16:23
357 查看
上篇文章谈到的get_project_quotas方法,进入这个方法。
这条语句主要实现的是根据project_id查询数据库,获取各种资源的限定值,这里的资源包括instances,ram,
cores,以字典形式返回给project_quotas。
b) project_usages = db.quota_usage_get_all_by_project(context,project_id)
这条语句和上条类似,这里也会根据project_id查询数据库,获取各种资源的限定值,只是这里获取到的还包括了
in_use和reserved。同样以字典形式返回给project_usages。
c) class_quotas = db.quota_class_get_all_by_name
根据quota_class来查询QuotaClass类。
分析完上面的三个主要的方法,接下来的代码实现的就是从字典project_quotas/project_usages中,为资源
instance、ram、cores读取limit的值。得到的结果是如下的形式。
看db.quota_reserve方法,这个方法主要完成的是对资源进行配额检测和更新数据库的操作,这里就不展开了。
到这里reserve方法就分析完成了,这个方法分析完后,上文中的_check_num_instances_quota方法也就分析完成
了。
这个方法主要实现的是资源配额管理,根据配额限制确定所要创建的实例数目,并获取分配好的资源uuid的列表。
回到_validate_and_provision_instance方法。
1、为了限制限制用户对服务器资源的使用,Nova引入quotas(配额)的概念。quotas可分为两类:
(1)、限制单个虚拟机创建请求对硬件资源的使用情况。例如默认每次请求能够最多指定128项metadata,最多能够指
定5个插入文件。代码分别检查客户端传入的metadata和插入文件是否超标
(2)、限制某一个租户能够使用的硬件资源总数。例如默认每个租户可以使用20个VCPU,50G内存,最多可创建10个虚
拟机。代码调用_check_num_instances_quota方法检查当前租户能够创建多少个虚拟机。
Nova中各个硬件资源的默认quotas参见/nova/quota.py文件的quota_opts变量。
(3)、检查虚拟机的磁盘镜像。检查磁盘镜像是否可用,检查客户端指定的虚拟机规格是否足以运行虚拟机镜像。
image = {} 当客户端没有指定磁盘映像,_validate_and_provision_instance方法将磁盘映像设置为空,因为有些
小的操作系统不需要磁盘镜像,只需要指定内存和kernel。
(image_service, image_id) = glance.get_remote_image_service(context,image_href)
image = image_service.show(context,image_id)
这段代码的作用是通过glanceclient获取镜像文件信息。在openstack中,不同组件之间的通信是通过RESTful API
完成的,openstack的处理方式是为每个组件都包含了这样一个client,它们都继承于HTTPClient这个基类,但做了
一些个性化的封装,用于向各自的组件发送HTTP请求。
nova需要和glance通信,以获取镜像文件的信息,所以需要声明了这样一个glance client。代码
glance.get_remote_image_service(context,image_href)的作用就是创建一个glaceclient对象,然后把这个对象
封装入GlanceImageService类里,即返回值image_service。然后调用该类下的show方法来获取镜像文件的信息。
(4)、base_options 主要是将客户端传过来的数据转化为方便数据库处理的base_options变量。数据转化是客户端和
服务器之间通信很重要的工作。例如:在servers包的Controller方法中就专门使用ViewBuilder类,完成数据转化的
工作。
(5)、为每个虚拟机创建一条数据库记录。调用send_update_with_states方法,通知Nova API服务更新虚拟机状态。
(6)、QUOTAS.commit修改租户的quotas,为新创建的虚拟机预留硬件资源。
回到_create_instance方法,我们来回顾一下这个方法。
1、调用_validate_and_provision_instance方法完成虚拟机创建的准备工作。
2、调用_record_action_start方法更新数据库中InstanceAction表的记录,将虚拟机状态改为“开始创建”。
3、调用scheduler_rpcapi.run_instance方法,向Nova Scheduler服务发送RPC请求,将虚拟机创建请求交给Nova
Scheduler服务处理。
总结:Compute API类的create方法完成的工作总结:
1、create方法首先调用_check_create_policies方法,检查当前用户是否具有创建虚拟机的权限。然互调用
_create_instance方法进一步处理虚拟机的创建请求。
2、_create_instance方法首先调用_validate_and_provision_instance方法完成虚拟机创建的准备工作。
然后对每个要创建的虚拟机 调用_record_action_start方法更新Nova数据库中InstanceAction表的记录。
最后远程调用Nova Scheduler服务的 run_instance方法,进一步处理虚拟机的创建请求。
3、_validate_and_provision_instance完成的工作:验证客户端传入的参数、修改租户的quotas,为虚拟机预留硬件
资源;在数据库中创建虚拟机记录。
def get_project_quotas(self, context, resources, project_id, quota_class=None, defaults=True, usages=True): """ 根据给定的资源项,对于 给定的对象 进行配额检索,返回配额限制值 """ quotas = {} #对于一个给定的项目,<strong><span style="color:#ff0000;">检索它的所有的配额</span></strong> #根据project_id查询数据库中相应项目的数据库信息,获取其中的hard_limit值,也就是获取规定的资源最大限额值 project_quotas = db.quota_get_all_by_project(context, project_id) #检索一个给定资源的当前的所有相关的使用情况 if usages: project_usages = db.quota_usage_get_all_by_project(context,project_id) #<strong><span style="color:#ff0000;">通过适当的类获取配额信息</span></strong>。如果project ID匹配context中的一个,那么使用context中的quota_class类,否则,使用所提供的quota_class类(如果有的话) #选取合适的类,为后面做准备 if project_id == context.project_id: quota_class = context.quota_class if quota_class: class_quotas = db.quota_class_get_all_by_name(context, quota_class) else: class_quotas = {} for resource in resources.values(): # Omit default/quota class values if not defaults and resource.name not in project_quotas: continue quotas[resource.name] = dict( limit=project_quotas.get(resource.name, class_quotas.get(resource.name, resource.default)), ) # Include usages if desired. This is optional because one # internal consumer of this interface wants to access the # usages directly from inside a transaction. if usages: usage = project_usages.get(resource.name, {}) quotas[resource.name].update( in_use=usage.get('in_use', 0), reserved=usage.get('reserved', 0), ) return quotasa) project_quotas =db.quota_get_all_by_project(context, project_id)
这条语句主要实现的是根据project_id查询数据库,获取各种资源的限定值,这里的资源包括instances,ram,
cores,以字典形式返回给project_quotas。
b) project_usages = db.quota_usage_get_all_by_project(context,project_id)
这条语句和上条类似,这里也会根据project_id查询数据库,获取各种资源的限定值,只是这里获取到的还包括了
in_use和reserved。同样以字典形式返回给project_usages。
c) class_quotas = db.quota_class_get_all_by_name
根据quota_class来查询QuotaClass类。
分析完上面的三个主要的方法,接下来的代码实现的就是从字典project_quotas/project_usages中,为资源
instance、ram、cores读取limit的值。得到的结果是如下的形式。
resource.name = instances limit:10 resource.name = ram limit:51200 resource.name = cores limit:20至此,我们分析完了get_project_quotas方法,下面回到_get_quotas方法。
def _get_quotas(self, context, resources, keys, has_sync, project_id=None): ... #获取并返回磁盘配额 quotas = self.get_project_quotas(context, sub_resources,project_id,context.quota_class, usages=False) return dict((k, v['limit']) for k, v in quotas.items())可以看到获取到quotas后,返回的各项(instance、ram、cores)的限额。然后再回到reserve方法。
def reserve(self, context, resources, deltas, expire=None, project_id=None): ... quotas = self._get_quotas(context, resources, deltas.keys(), has_sync=True, project_id=project_id) return db.quota_reserve(context, resources, quotas, deltas, expire, CONF.until_refresh, CONF.max_age, project_id=project_id)执行完_get_quotas语句后,得到的quotas的结果类似这样:quotas = {instances:10, ram:51200, cores:20}。来
看db.quota_reserve方法,这个方法主要完成的是对资源进行配额检测和更新数据库的操作,这里就不展开了。
到这里reserve方法就分析完成了,这个方法分析完后,上文中的_check_num_instances_quota方法也就分析完成
了。
这个方法主要实现的是资源配额管理,根据配额限制确定所要创建的实例数目,并获取分配好的资源uuid的列表。
回到_validate_and_provision_instance方法。
class API(base.Base): def _validate_and_provision_instance(self,context,instance_type, ...): #一些参数的验证和初始化 if not metadata: metadata = {} if not security_group: security_group = 'default' ... #如果客户端没有指定虚拟机规格,则使用默认的格式 ,检查虚拟机的规格是否可用 if not instance_type: instance_type = instance_type.get_default_instance_type() ... #根据配额资源限制计算所要建立实例的数目,并获取了分配好的资源(块存储)的UUID的列表 num_instances, quota_reservations = self._check_num_instances_quota( context, instance_type,...) try: instances = [] instance_uuids = [] #检查metadata项数是否超标 self._check_metadata_properties_quota(context, metadata) #检查注入文件的个数和大小是否超标 self._check_injected_file_quota(context, injected_files) #检查需求网络是否合法 self._check_requested_networks(context, requested_networks) #获取、检查虚拟机镜像文件 if image_href: #获取虚拟机镜像文件的uuid (image_service, image_id) = glance.get_remote_image_service(context, image_href) #获取虚拟机镜像文件信息 image = image_service.show(context, image_id) #检查镜像是否可用 if image['status'] != 'active': raise exception.ImageNotActive(image_id=image_id) else: image = {} #检查虚拟机内存是否足够大 if instance_type['memory_mb'] < int(image.get('min_ram') or 0): raise exception.InstanceTypeMemoryTooSmall() #检查虚拟机磁盘是否足够大 if instance_type['root_gb'] < int(image.get('min_disk') or 0): raise exception.InstanceTypeDiskTooSmall() ... #用于创建数据库的记录 base_options = { 'reservation_id': reservation_id, ...} #获取镜像中指定的参数 options_from_image = self._inherit_properties_from_image( image, auto_disk_config) #将镜像中的参数合并至base_options base_options.update(options_from_image) ... for i in xrange(num_instances): options = base_options.copy() #在数据库中创建虚拟机记录 instance = self.create_db_entry_for_new_instance(context, instance_type, image, options, ...) #保存创建的虚拟机列表 instances.append(instance) instance_uuids.append(instance['uuid']) #通知Nova API,虚拟机当前状态为BUILDING notification.send_update_with_states(context,instance,...) expect Exception: ... #修改租户的QUOTAS,为虚拟机预留硬件资源 <span style="font-family: SimSun;">QUOTAS.commit</span><span style="font-family: SimSun;">(context,quota_reservations)</span> ... return (instances,request_spec,filter_properties)
1、为了限制限制用户对服务器资源的使用,Nova引入quotas(配额)的概念。quotas可分为两类:
(1)、限制单个虚拟机创建请求对硬件资源的使用情况。例如默认每次请求能够最多指定128项metadata,最多能够指
定5个插入文件。代码分别检查客户端传入的metadata和插入文件是否超标
(2)、限制某一个租户能够使用的硬件资源总数。例如默认每个租户可以使用20个VCPU,50G内存,最多可创建10个虚
拟机。代码调用_check_num_instances_quota方法检查当前租户能够创建多少个虚拟机。
Nova中各个硬件资源的默认quotas参见/nova/quota.py文件的quota_opts变量。
(3)、检查虚拟机的磁盘镜像。检查磁盘镜像是否可用,检查客户端指定的虚拟机规格是否足以运行虚拟机镜像。
image = {} 当客户端没有指定磁盘映像,_validate_and_provision_instance方法将磁盘映像设置为空,因为有些
小的操作系统不需要磁盘镜像,只需要指定内存和kernel。
(image_service, image_id) = glance.get_remote_image_service(context,image_href)
image = image_service.show(context,image_id)
这段代码的作用是通过glanceclient获取镜像文件信息。在openstack中,不同组件之间的通信是通过RESTful API
完成的,openstack的处理方式是为每个组件都包含了这样一个client,它们都继承于HTTPClient这个基类,但做了
一些个性化的封装,用于向各自的组件发送HTTP请求。
nova需要和glance通信,以获取镜像文件的信息,所以需要声明了这样一个glance client。代码
glance.get_remote_image_service(context,image_href)的作用就是创建一个glaceclient对象,然后把这个对象
封装入GlanceImageService类里,即返回值image_service。然后调用该类下的show方法来获取镜像文件的信息。
(4)、base_options 主要是将客户端传过来的数据转化为方便数据库处理的base_options变量。数据转化是客户端和
服务器之间通信很重要的工作。例如:在servers包的Controller方法中就专门使用ViewBuilder类,完成数据转化的
工作。
(5)、为每个虚拟机创建一条数据库记录。调用send_update_with_states方法,通知Nova API服务更新虚拟机状态。
(6)、QUOTAS.commit修改租户的quotas,为新创建的虚拟机预留硬件资源。
回到_create_instance方法,我们来回顾一下这个方法。
class API(base.Base): def _create_instance(self,context,instance_type, ...): ... #验证客户端传入参数,做虚拟机创建前的准备工作 (instances,request_spec,filter_properties) = self._validate_and_provision_instance(context, instance_type, ...) for instance in instances: #更新InstanceAction表记录 self._record_action_start(context,instance,instance_actions.CREATE) #向Nova Scheduler服务发送RPC请求,创建虚拟机 self.scheduler_rpcapi.run_instance(context,...) return (instances,reservation_id)
1、调用_validate_and_provision_instance方法完成虚拟机创建的准备工作。
2、调用_record_action_start方法更新数据库中InstanceAction表的记录,将虚拟机状态改为“开始创建”。
3、调用scheduler_rpcapi.run_instance方法,向Nova Scheduler服务发送RPC请求,将虚拟机创建请求交给Nova
Scheduler服务处理。
总结:Compute API类的create方法完成的工作总结:
1、create方法首先调用_check_create_policies方法,检查当前用户是否具有创建虚拟机的权限。然互调用
_create_instance方法进一步处理虚拟机的创建请求。
2、_create_instance方法首先调用_validate_and_provision_instance方法完成虚拟机创建的准备工作。
然后对每个要创建的虚拟机 调用_record_action_start方法更新Nova数据库中InstanceAction表的记录。
最后远程调用Nova Scheduler服务的 run_instance方法,进一步处理虚拟机的创建请求。
3、_validate_and_provision_instance完成的工作:验证客户端传入的参数、修改租户的quotas,为虚拟机预留硬件
资源;在数据库中创建虚拟机记录。
相关文章推荐
- Nova API服务 之 创建虚拟机流程(1)
- Nova API服务 之 创建虚拟机流程(2)
- nova-api源码分析(一)--------创建虚机流程
- create instance 生成创建虚拟机从nova到调用libvirt流程(pycharm debug):
- VMWare 环境下devstack创建虚拟机报错及修改nova-api返回数据得条目
- openstack:nova中“从镜像启动”创建虚拟机的流程
- NOVA-API服务启动流程
- nova组件、架构、代码目录以及创建虚拟机流程
- NOVA-API服务的启动流程
- openstack:nova中“从云硬盘启动”创建虚拟机的流程
- OpenStack中nova组件创建虚拟机的源码流程
- nova创建虚拟机源码分析系列之一 restful api
- openstack Nova分析之 创建虚拟机流程(4)
- 【openstack】Nova创建虚拟机流程1
- 【openstack】Nova创建虚拟机流程2 -scheduler
- 【openstack】Nova创建虚拟机流程3-compute
- openstack之nova-api服务流程分析