Openstack Nova 源码分析 — Create instances (nova-conductor阶段)
目录
前言
Nova 控制着一个个虚拟机的状态变迁和生命周期,这种对虚拟机生命周期的管理是由 nova-compute service 来完成的。
在了解 Nova 创建虚拟机的流程之前,需要先补充一些 Openstack 基本概念。
Instance
Instance 表示一个虚拟机,是虚拟化世界的个体,类似与现实世界中的人类。所以,相同的,Instance 也具有一些特征性的标识,也可以称之为属性。如下:
1. 一个唯一的 ID 去标识 Instance
2. 一些描述 Instance 规格特征的信息。EG. Size/内存/InstanceName
3. 有字段去表示 Instance 运行在哪一台 Host
4. 有字段去表示 Instance Status
5. 有字段去表示 Create | Delete Instance 的时间
…
Nova 在 /opt/stack/nova/nova/objects/instance.py 中对 Instance 进行了描述。
NOTE:/opt/stack/nova/nova/objects/ 该目录下存放数据库表对象文件,一个 Class 映射到一个张数据库表。
86 class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
1 base.NovaObjectDictCompat):
2 fields = {
3 'id': fields.IntegerField(),
4
5 'user_id': fields.StringField(nullable=True),
6 'project_id': fields.StringField(nullable=True),
7
...
Flavor
在 Create Instance 之前,需要为 Instance 指定一组资源(Disk/Memory/VCPU/RootDisk/EphemeralDisk/Swap)。
nova-compute 在执行创建之前,需要通过这些资源配置来判断是否由足够的 Host 资源来实现创建。这组资源的设置就是 flavor,即创建虚拟机的规格。每个 Instance 对象的 instance_type_id
字段就表示该 Instance 所拥有的 flavor 。
执行 Commands :nova flavor-list
可以查看 Nova 默认 flavor 的信息 ; nova flavor-create
创建新的 flavor 。
Instance Status
Instance 拥有三个字段与描述其状态有关,这些状态刚被用于程序流的条件判断。
power_status: 使用 libvirt 或 Virt Driver 提供的接口从 Hypervisor 中获取的 Instance Power Status。
- Running
- Shutdown
- NoState
vm_state: 虚拟机的稳定状态。
- Active:正常运行
- Suspended:停止运行
task_state:过渡状态,与 Compute API 的执行密切相关,表示 Instance 正在执行什么任务,只有在执行任务的时候才会有 task_state 。
Virt Driver
Openstack Nova 仅仅是作为云计算虚拟机的管理工具,其本身并不提供任何的虚拟化技术,而是交由具体的 Hypervisor 来实现虚拟机的创建和管理。因此,nova-compute 需要和不同的 Hpyervisor 进行交互,并使用 Virt Driver 来作为这种交互的支撑,其代码实现存放在 /opt/stack/nova/nova/virt/ 目录下。
目前,Nova 实现了 Hyper-V/Libvirt/VMware/Xen 这四种 Virt Dirver 。可以通过配置选项 compute_dirver
来指定使用哪一种 Virt Driver 。
compute_driver = libvirt.LibvirtDriver
compute_driver=vmwareapi.VMwareVCDriver
EXAMPLE:nova-compute 通过 Virt Dirver 来调用 Libvirt 库中提供的 API 来实现虚拟机的管理。
从上图可以看出,nova-compute 必须部署在 Linux+KVM 的 Host 上,当然,现在的 Linux Kernel Version 大多都嵌入了 KVM 虚拟化技术。
Resource Tracker
nova-compute 需要在数据库中存储 Host 的资源使用情况,以便于 nova-scheduler 获取作为选择 Host 依据的数据。Node Project 使用 ConputeNode 数据库表对象来保存 Compute Node的配置信息和资源使用情况(/opt/stack/nova/nova/objects/compute_node.py)。所以 nova-compute 会为每一个 Host 创建一个 ResourceTracker 对象,用于更新 ComputeNode 对象在数据库中对应的 compute_nodes 表。
有两种更新*compute_nodes表的方式:*
Claim 机制:在创建 Instance 之前,预先测试 Host 的可用资源能否满足 Create Instance。如果满足,则首先更新数据库,将虚拟机申请的资源从可用资源中减去。 如果后来创建失败或者将虚拟机删除时,会再通过 Claim 将原来减去的部分再添加到可用资源中去。实现:nova.compute.resource_tracker:instance_claims
Periodic Task:在 nova.compute.manager.ComputeManager 中有个周期性任务
update_available_resource()
用于更新 Host 的资源数据。
NOTE:上面两种数据库更新方式并不冲突。Claim 实在数据库当前数据的基础上去计算并更新,可以保证数据库里可用资源的及时更新。 Periodic Task 是为了数据库内信息的准确性,它每次执行都会通过 Hypervisor 去获取 Host 的信息,并将这些信息更新到数据库中。前者是在 Create Instance 的时候执行,后者是周期性执行。
nova-conductor
Conductor Service 的加入,使得 nova-compute 和数据库解耦,为数据库提供了一重安全保障,提高了对数据库的访问效率,而且还可以实现升级数据库 schema 的同时无需上级 nova-compute 。所以 nova-compute 所有访问数据库的操作都是交由 nova-conductor 去完成。
随着 nova-conductor 的不断完善,它还需要承担部分原来属于 nova-compute 的 TaskAPI 的任务。TaskAPI 主要包含了耗时较长的任务,例如:Create Instance/Migrate Instance 等等。
Create Instance(nova-conductor阶段)
Create Instance 属于 TaskAPI 任务,耗时较长,由 nova-conductor 来承担。但是需要注意的是,对 Instance 管理的流程可以分为俩个阶段,就是调度阶段和执行阶段。调度阶段由 Openstack 负责,主要是 Nova Project 中的几个 Services 来协同完成。而执行阶段则由 Hypervisor 来具体实现。Openstack 仅仅扮演了 管理者的角色。
- 在 nova.conductor.rpcapi 中定义一个
build_instances()
RPC 接口函数:
301 def build_instances(self, context, instances, image, filter_properties,
1 admin_password, injected_files, requested_networks,
2 security_groups, block_device_mapping, legacy_bdm=True):
3 image_p = jsonutils.to_primitive(image)
4 version = '1.10'
5 if not self.client.can_send_version(version):
6 version = '1.9'
7 if 'instance_type' in filter_properties:
8 flavor = filter_properties['instance_type']
9 flavor_p = objects_base.obj_to_primitive(flavor)
10 filter_properties = dict(filter_properties,
11 instance_type=flavor_p)
12 kw = {'instances': instances, 'image': image_p,
13 'filter_properties': filter_properties,
14 'admin_password': admin_password,
15 'injected_files': injected_files,
16 'requested_networks': requested_networks,
17 'security_groups': security_groups}
18 if not self.client.can_send_version(version):
19 version = '1.8'
20 kw['requested_networks'] = kw['requested_networks'].as_tuples()
21 if not self.client.can_send_version('1.7'):
22 version = '1.5'
23 bdm_p = objects_base.obj_to_primitive(block_device_mapping)
24 kw.update({'block_device_mapping': bdm_p,
25 'legacy_bdm': legacy_bdm})
26
27 cctxt = self.client.prepare(version=version)
28 cctxt.cast(context, 'build_instances', **kw)
# /opt/stack/nova/nova/conductor/manager.py
# 创建虚拟机属于 TaskAPI 任务,所有的 TaskAPI 都交由 nova-conductor 来处理,所以 manager.py 的实现在 Conductor 中
515 class ComputeTaskManager(base.Base):
1 """Namespace for compute methods.
2
3 This class presents an rpc API for nova-conductor under the 'compute_task'
4 namespace. The methods here are compute operations that are invoked
5 by the API service. These methods see the operation to completion, which
6 may involve coordinating activities on multiple compute nodes.
7 """
...
526 def __init__(self):
1 super(ComputeTaskManager, self).__init__()
2 self.compute_rpcapi = compute_rpcapi.ComputeAPI()
3 self.image_api = image.API()
4 self.servicegroup_api = servicegroup.API()
5 self.scheduler_client = scheduler_client.SchedulerClient()
6 self.notifier = rpc.get_notifier('compute', CONF.host)
# 其中 Scheduler client 是对 Scheduler_rpcapi 的封装,本质上是一个 Scheduler 提供的 rpcapi:
# nova.manager.ComputeTaskManager:scheduler_client
# ==> nova.scheduler.client.__init__:__init__
# ==> nova.scheduler.client.query.SchedulerQueryClient:__init__
# ==> self.scheduler_rpcapi = scheduler_rpcapi.SchedulerAPI()
...
# 1.(被调用) HTTP Request ==> nova.api ==> RPC cast ==> nova-conductor (nova.conductor.manager:ComputeTaskManager.build_instances() 是 nova.conductor.rpcapi.build_instances RPC 接口的实际功能实现函数)
# 参数传递过程: nova-api 调用 conductor.rpcapi:build_instances() 并传入实参
# ==> 将实参和其他信息打包发送到消息队列(数据流形式)
# ==> 将实参传入 conductor.manager:build_instances() ;
708 def build_instances(self, context, instances, image, filter_properties,
1 admin_password, injected_files, requested_networks,
2 security_groups, block_device_mapping=None, legacy_bdm=True):
3 # TODO(ndipanov): Remove block_device_mapping and legacy_bdm in version
4 # 2.0 of the RPC API.
713 request_spec = scheduler_utils.build_request_spec(context, image,
1 instances)
# request_spec 是一个字典类型,包含了详细的虚拟机信息,nova-scheduler 依据这些信息来选择一个最佳的主机并返回给 nova-conductor
...
# 2.(调用) nova-conductor 通过 RPC call 方式调用 nova-scheduler 的接口函数: nova.scheduler.rpcapi:select_destinations()
# 通过 nova-scheduler 来获取 HOSTS
738 hosts = self.scheduler_client.select_destinations(context,
1 request_spec, filter_properties)
...
# 3.(调用) nova-conductor ==> RPC cast ==> nova-compute (nova.compute.build_and_run_instance())
763 self.compute_rpcapi.build_and_run_instance(context,
1 instance=instance, host=host['host'], image=image,
2 request_spec=request_spec,
3 filter_properties=local_filter_props,
4 admin_password=admin_password,
5 injected_files=injected_files,
6 requested_networks=requested_networks,
7 security_groups=security_groups,
8 block_device_mapping=bdms, node=host['nodename'],
9 limits=host['limits'])
在 经过一番远程调用之后,终于进入到了 nova-compute 调用 Virt Dirver 的阶段。
Openstack Nova 源码分析 — Create instances (nova-conductor阶段)的更多相关文章
- Openstack Nova 源码分析 — 使用 VCDriver 创建 VMware Instance
目录 目录 前言 流程图 nova-compute vCenter 前言 在上一篇Openstack Nova 源码分析 - Create instances (nova-conductor阶段)中, ...
- Openstack nova-scheduler 源码分析 — Filters/Weighting
目录 目录 前言 调度器 FilterScheduler调度器的工作流程 Filters 过滤器 Filters 类型 Weighting 权重 源码实现 关键文件及其意义 阶段一nova-sched ...
- Openstack Nova 源码分析 — RPC 远程调用过程
目录 目录 Nova Project Services Project 的程序入口 setuppy Nova中RPC远程过程调用 nova-compute RPC API的实现 novacompute ...
- nova创建虚拟机源码分析系列之五 nova源码分发实现
前面讲了很多nova restful的功能,无非是为本篇博文分析做铺垫.本节说明nova创建虚拟机的请求发送到openstack之后,nova是如何处理该条URL的请求,分析到处理的类. nova对于 ...
- nova创建虚拟机源码分析系列之四 nova代码模拟
在前面的三篇博文中,介绍了restful和SWGI的实现.结合restful和WSGI配置就能够简单的实现nova服务模型的最简单的操作. 如下的内容是借鉴网上博文,因为写的很巧妙,将nova管理虚拟 ...
- gophercloud openstack networking 源码分析
1.network 部分 // Package networks contains functionality for working with Neutron network resources. ...
- 【Canal源码分析】Sink及Store工作过程
一.序列图 二.源码分析 2.1 Sink Sink阶段所做的事情,就是根据一定的规则,对binlog数据进行一定的过滤.我们之前跟踪过parser过程的代码,发现在parser完成后,会把数据放到一 ...
- nova创建虚拟机源码分析系列之七 传入参数转换成内部id
上一篇博文将nova创建虚机的流程推进到了/compute/api.py中的create()函数,接下来就继续分析. 在分析之前简单介绍nova组件源码的架构.以conductor组件为例: 每个组件 ...
- 【OpenStack】OpenStack系列13之Nova源码解析与API扩展
学习思路 议程:代码结构-主干流程-分层架构-业务模型-数据库模型-消息模型 分布式架构:Api:横向扩展 rpc:纵向扩展 分层架构:Controller接口层.View/Manager逻辑层 ...
随机推荐
- thinkphp SAE
SAE介绍 Sina App Engine(简称SAE)是新浪研发中心开发的国内首个公有云计算平台,是新浪云计算战略的核心组成部分,作为一个简单高效的分布式Web服务开发.运行平台越来越受开发者青睐. ...
- Shiro学习(24)在线回话管理
有时候需要显示当前在线人数.当前在线用户,有时候可能需要强制某个用户下线等:此时就需要获取相应的在线用户并进行一些操作. 本章基于<第十六章 综合实例>代码构建. 会话控制器 Java代码 ...
- mycat简介
开源数据库中间件-MyCat简介 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求.这个时候 ...
- Dubbo入门到精通学习笔记(十五):Redis集群的安装(Redis3+CentOS)、Redis集群的高可用测试(含Jedis客户端的使用)、Redis集群的扩展测试
文章目录 Redis集群的安装(Redis3+CentOS) 参考文档 Redis 集群介绍.特性.规范等(可看提供的参考文档+视频解说) Redis 集群的安装(Redis3.0.3 + CentO ...
- C++变长参数
如果C++的变长参数经过了多轮的调用,就可能失去作用 间接引址,但是只能引用到第一个变长参数. va_list marker; va_start(marker, format); s_logger ...
- Codeforces451A-Game With Sticks-思维
After winning gold and silver in IOI 2014, Akshat and Malvika want to have some fun. Now they are pl ...
- Java服务定位器模式
当我们想要使用JNDI查找来定位各种服务时,使用服务定位器设计模式. 考虑到为服务查找JNDI的高成本,所以在服务定位器模式使用缓存技术. 首次需要服务时,服务定位器在JNDI中查找并缓存服务对象. ...
- vs设置html的模板快
打开vs编辑器,点击文件-->首选项-->用户代码片段 之后选择先对应的编辑器模板 进入里面编写相对应的代码块 之后直接在编辑器中调用.
- PHPExcel导出工作蒲(多表合并)教程+详细代码解读
最近做了一个需求,导出统计数据,因为需要同时导出多个不同的统计数据,所以不能像以往导出数据列表一样去实现这个需求,刚好空下来就记录一下(PHPExcel导出Excel多sheet合并) 一.主要使用的 ...
- Codeforces Round #535 F-MST Unification
题目大意: 给定n m 为图中的点数n和边数m 给定m条边的信息 u v w 为u点到v点有一条长度为w的边 图中无环无重边 这个图的MST的花费为k 但可能存在多种花费为k的MST的方案 此时对图中 ...