目录

前言

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阶段)的更多相关文章

  1. Openstack Nova 源码分析 — 使用 VCDriver 创建 VMware Instance

    目录 目录 前言 流程图 nova-compute vCenter 前言 在上一篇Openstack Nova 源码分析 - Create instances (nova-conductor阶段)中, ...

  2. Openstack nova-scheduler 源码分析 — Filters/Weighting

    目录 目录 前言 调度器 FilterScheduler调度器的工作流程 Filters 过滤器 Filters 类型 Weighting 权重 源码实现 关键文件及其意义 阶段一nova-sched ...

  3. Openstack Nova 源码分析 — RPC 远程调用过程

    目录 目录 Nova Project Services Project 的程序入口 setuppy Nova中RPC远程过程调用 nova-compute RPC API的实现 novacompute ...

  4. nova创建虚拟机源码分析系列之五 nova源码分发实现

    前面讲了很多nova restful的功能,无非是为本篇博文分析做铺垫.本节说明nova创建虚拟机的请求发送到openstack之后,nova是如何处理该条URL的请求,分析到处理的类. nova对于 ...

  5. nova创建虚拟机源码分析系列之四 nova代码模拟

    在前面的三篇博文中,介绍了restful和SWGI的实现.结合restful和WSGI配置就能够简单的实现nova服务模型的最简单的操作. 如下的内容是借鉴网上博文,因为写的很巧妙,将nova管理虚拟 ...

  6. gophercloud openstack networking 源码分析

    1.network 部分 // Package networks contains functionality for working with Neutron network resources. ...

  7. 【Canal源码分析】Sink及Store工作过程

    一.序列图 二.源码分析 2.1 Sink Sink阶段所做的事情,就是根据一定的规则,对binlog数据进行一定的过滤.我们之前跟踪过parser过程的代码,发现在parser完成后,会把数据放到一 ...

  8. nova创建虚拟机源码分析系列之七 传入参数转换成内部id

    上一篇博文将nova创建虚机的流程推进到了/compute/api.py中的create()函数,接下来就继续分析. 在分析之前简单介绍nova组件源码的架构.以conductor组件为例: 每个组件 ...

  9. 【OpenStack】OpenStack系列13之Nova源码解析与API扩展

    学习思路 议程:代码结构-主干流程-分层架构-业务模型-数据库模型-消息模型 分布式架构:Api:横向扩展    rpc:纵向扩展 分层架构:Controller接口层.View/Manager逻辑层 ...

随机推荐

  1. IDEA工具,配置相关笔记

    1.修改背景颜色(黑/白)File -> settings -> Editor -> Color Scheme -> General -> (Scheme选择Defaul ...

  2. Android中怎么破解游戏之修改金币数

    我们在玩游戏的时候总是会遇到一些东东需要进行购买的,但是我们可能又舍不得花钱,那么我们该怎么办呢?那就是用游戏外挂吧!我们这里说的是Android中的游戏,在网上搜索一下移动端游戏外挂,可能会找到一款 ...

  3. JAVA学习之环境搭建

    了解到JAVA语言的跨平台性的原理是通过在不同的操作系统中安装对应版本的的JAVA虚拟机(JVM)实现 开发JAVA前必须先搭建JAVA环境: 1.JAVA开发工具包JDK(JAVA DEVELOPM ...

  4. Linux的命名空间

    1. 为什么提供命名空间 命名空间是一种轻量级的虚拟化手段. 传统的虚拟化软件,是虚拟化多个不同的操作系统,对共享资源的限制很大. 通过提供命名空间,可以让进程与进程之间,用户与用户之间彼此看不到对方 ...

  5. springfox-swagger原理解析与使用过程中遇到的坑

    swagger简介 swagger确实是个好东西,可以跟据业务代码自动生成相关的api接口文档,尤其用于restful风格中的项目,开发人员几乎可以不用专门去维护rest api,这个框架可以自动为你 ...

  6. 如何在react中实现一个倒计时组件

    倒计时组件 import React, { Component } from 'react' import $ from 'jquery' import "../../css/spellTE ...

  7. JQuery on绑定click无效的的bug解决办法?

    如果你在移动端使用zepto.js, touch 来代替click事件,那就没有上述标题的问题了.如果你仍然使用了click,在点击事件中苹果机就可能出现无效的结果. 第一种方法: 解决的方法很巧妙, ...

  8. C# 基于创建一个mysql 连接池

    创建一个连接池操作类 using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using Syste ...

  9. Dubbo多注册中心和Zookeeper服务的迁移

    一.Dubbo多注册中心 1. 应用场景 例如阿里有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心. consumer.xml <?xm ...

  10. 新项目UX设计0到1的正确开启方式

    无论是在BAT还是创业小公司,都随时可能接到从0开始的新项目,那么作为负责新项目的主设OR独立设计师,我们应该从何开启工作呢?