OpenStack Nova 设计与实现

1. Nova

OpenStack采用一种无共享的、基于消息队列的架构,解耦的各模块组合在一起构成了一个统一的IaaS云。

Nova是OpenStack生态中最重要的一个核心组件,管理云生态中的计算功能,控制着一个个虚拟机的状态变迁与生老病死,管理着主机之间的资源分配等等。相比于其他的OpenStack项目,Nova的功能已经相当完备和稳定,很多厂商都会在部署时候直接使用Nova的发行版本,然后针对自身需求对网络和存储进行二次开发。

Nova的服务简介

目前Nova主要有API、Compute、Conductor、Scheduler四个核心服务所组成,它们之间通过AMQP消息队列通信。(一般来说,OpenStack的项目间是通过RESTful来通信的,项目内部不同的服务进程是通过消息总线进行通信的。这样既可以保证各项目的对外提供服务的接口可以被不同的客户端高效支持,又可以保证项目内部通信接口的可扩展性和可靠性,以支持大规模的部署)。

  • API是进入Nova的Http接口。
  • Compute是用于与VMM交互来运行虚拟机并管理虚拟机声明周期的(通常是一个主机host运行一个compute服务)。
  • Scheduler从资源池中选择最合适的计算节点来创建新的虚拟机实例。
  • Conductor为数据库访问提供一层安全保障。设计目标是希望设计数据库的操作的都通过Conductor。

Oslo项目

oslo是OpenStack通用库,包括了众多不需要重复发明的“轮子”。主要的作用就是把OpenStack里面通用的架构抽象提取出来形成一个代码库,和其他的第三方Python库一样,只需要在项目中import对应的库就行了。Oslo库包括很多的子项目,下面列举一些进行简单的介绍:

  • Cliff(Command Line Formulation Framework):可以用来帮助构建命令行程序。主程序只负责基本的命令行参数的解析,然后调用各个子命令去执行不同的操作。
  • oslo.config:用于接续命令行和配置文件中的配置选项,是oslo的第一个项目。
  • oslo.db:针对SQLAlchemy访问的抽象。
  • oslo.i18n:对Python gettext模块的封装,主要用于字符串的翻译和国际化。
  • oslo.messaging:为OpenStack各个项目使用RPC和事件通知提供一套统一的接口。
  • stevedore:运行时动态载入代码。
  • oslo.policy:负责policy的验证和rules的管理。
  • oslo.rootwrap:让其他OpenStack服务以root身份执行shell命令。一般来说OpenStack的服务都是以非特权用户的身份运行的。
  • oslo.test:提供单元测试的基础框架。

Nova 的源码结构

以下是简略版的Nova项目地图,详细版的可以参考
https://github.com/openstack/nova.git

├——etc
│     └—— nova            --Nova配置文件
├——nova
│     ├—— api     --Nova API服务
│     │     ├——ec2       --EC2 API支持
│     │     ├——openstack    --OpenStack API
│     ├——cmd      --各个Nova服务的入口程序
│     ├——compute     --Nova compute服务
│     ├——conductor    --Nova Conductor服务
│     ├——db                   --数据库操作
│     ├——image            --Glance接口抽象
│     ├——objects          -- Object Module
│     ├——scheduler     --Nova scheduler服务
│     ├——tests              --单元测试
│     ├——virt                 --Hypervisor driver
│     ├——volume --Cinder接口抽象
├——setup.cfg               --项目源码地图

Setup.cfg

setup.cfg文件是浏览OpenStack代码中最依仗的文件,可以引导我们去认识一个新的项目,并了解它的代码结构。
入口点是entry_points这个section,这里会定义各个服务的入口点和定义资源所对应的代码目录等:

Nova的其他服务

Nova除了上面的四个主要服务之外,还提供很多其他的服务:

  • Nova-all:用于启动所有的nova服务的辅助脚本
  • Nova-cells:Cell模块允许用户在不影响现有的OpenStack云环境的前提下,增强横向扩展、大规模部署能力。Cell模块启动以后,OpenStack云环境通过添加子cell的方式进行拓展。Nova-cells负责各个cell之间的通信,以及为一个新的虚拟机实例选择合适的cell,所以每个cell都需要运行nova-cells服务。详细参考链接。

  • Nova-cert:管理X509证书。

  • Nova-manage:提供很多与Nova的维护和管理相关的功能。
  • Nova-novncproxy:Nova提供了novncproxy代理支持用户通过vnc访问虚拟机。
  • Nova-rootwrap:用于在OpenStack运行过程中以root身份运行某些shell命令。

2. Nova API

Nova API是访问和使用Nova服务的唯一途径。作为一个中间角色,Nova API把客户端的请求传达给Nova服务,待Nova服务处理完成以后再将处理结果返回客户端。
Nova API是被要求保持高度的稳定,名称以及返回的数据结构都不能轻易的改变。目前在Liberty版本中使用的Nova API版本是v2.1。学习Nova API的设计思路与执行过程,有助于我们对OpenStack有更好的理解。

Nova API的目录结构

对于OpenStack来说,每个API都对应着一种资源,在OpenStack共定义两种类型的资源,核心资源与扩展资源。

  • 核心资源:云平台中最基础的资源,如image,servers,volume,ips等。
  • 扩展资源:扩展资源如keypair,cell,floatingIP等。

Nova API执行过程

Nova API的执行过程主要包括3个阶段:
1. novaclient将用户命令转换成标准的HTTP请求
2. Paste Deploy将请求路由到具体的WSGI Application
3. WSGI Application将请求路由到具体的函数并执行

novaclient将用户命令转换成标准的HTTP请求

本质就是命令行,或者用户界面后台完成对Nova 的RESTful API HTTP的组装,以命令行nova list为例:

[stack@controller2 devstack]$ nova --debug list
DEBUG (session:198) REQ: curl -g -i -X GET http://10.10.0.15:5000/v2.0 -H "Accept: application/json" -H "User-Agent: python-keystoneclient"
…
DEBUG (v2:86) Making authentication request to http://10.10.0.15:5000/v2.0/tokens
DEBUG (connectionpool:387) "POST /v2.0/tokens HTTP/1.1" 200 3088
DEBUG (session:198) REQ: curl -g -i -X GET http://10.10.0.15:8774/v2.1/19f21de2bdfc4091ada8883d68010984 -H "User-Agent: python-novaclient" -H "Accept: application/json" -H "X-Auth-Token: {SHA1}5cced31690d58d52a61814026e14450296dd3e9e"
…DEBUG (session:198) REQ: curl -g -i -X GET http://10.10.0.15:8774/v2.1/19f21de2bdfc4091ada8883d68010984/servers/detail -H "User-Agent: python-novaclient" -H "Accept: application/json" -H "X-OpenStack-Nova-API-Version: 2.6" -H "X-Auth-Token: {SHA1}5cced31690d58d52a61814026e14450296dd3e9e"
DEBUG (connectionpool:387) "GET /v2.1/19f21de2bdfc4091ada8883d68010984/servers/detail HTTP/1.1" 200 15
DEBUG (session:216) RESP: [200] Content-Length: 15 X-Compute-Request-Id: req-a0bf3a96-1bf7-4c8a-b915-eb881b817e7a Vary: X-OpenStack-Nova-API-Version Connection: keep-alive X-Openstack-Nova-Api-Version: 2.6 Date: Thu, 18 Feb 2016 02:59:55 GMT Content-Type: application/json
RESP BODY: {"servers": []}+----+------+--------+------------+-------------+----------+
| ID | Name | Status | Task State | Power State | Networks |
+----+------+--------+------------+-------------+----------+
+----+------+--------+------------+-------------+----------+

上面共发送了两个HTTP请求:

  • 第一个是发送给keystone获取授权的,OpenStack的各种服务都需要授权后才能够进行使用。Nova API的调用都需要拿到token填到“X-Auth-Token”中。
  • 第二个是发送到nova,根据tenant id来获取这个租户下面所有实例的信息。

HTTP请求到WSGI Application

在nova-api启动的时候,会根据配置文件nova.conf里面的enable_apis选项内容创建一个或者多个WSGI Server。Paste Deploy会在各个WSGI Server创建时参与进来,创建时会基于Paste的配置文件(/etc/nova/api-paste.ini)去加载WSGI Application。

  • Api-paste.ini
    将在socket上监听到的http请求准确的路由到特定的WSGI Application
    “GET /v2.1/19f21de2bdfc4091ada8883d68010984/servers/detail”

    定义认证方式和filter过滤分发

    最终将调用应用osapi_compute_app_v21

WSGI Application到具体的执行函数

nova.api.openstack.APIRouterV21中,主要完成的是对所有资源的加载以及路由规则的创建,自此WSGI Routes模块参与进来。

register_resources()函数中会把各个资源的get_resources()函数进行资源注册,同时使用mapper对象建立路由规则。
在Nova里面,每个资源都会被封装成一个 nova.api.openstack.wsgi.Resource对象,对应着一个WSGI应用,这样可以保证资源之间的独立性。最后Router会找到资源对应的controller和方法,进行函数执行。至此,一个HTTP的请求最终分发到对应的资源操作:

“GET /v2.1/19f21de2bdfc4091ada8883d68010984/servers/detail”
就会最终调用到资源servers所对应Controller的detail操作:
nova.api.openstack.compute.servers.ServersController.detail():

3. Nova Conductor

nova-conductor服务的作用是为数据库的访问提供一层安全保障,让nova-compute和数据库解耦,保证数据库的安全性,同时做升级时候也无需升级nova-compute。

  • 引入Conductor优缺点:
    - 提供安全保证,此前都是compute直接访问数据库,一旦其被攻击,就会直接暴露数据库。
    - 解耦,方便数据库升级。
    - 对数据库访问性能提高:此前当使用协程访问时候,所有的数据库访问都是阻塞的;现可以通过创建多个协程使用RPC访问nova-conductor改善这个问题
    - 缺点:RPC调用有延时,nova-conductor本身访问数据库也是有阻塞的。

目前版本,compute所有访问数据库的操作都要交给conductor完成。conductor和compute避免部署在同一个主机,否则移除数据库直接访问就没有任何意义了。
conductor服务不断完善,还需要承担部分原本由compute负责的TaskAPI任务(耗时比较长的任务,如创建虚机,虚机迁移等,详情参考链接)

Nova Conductor源码目录

Conductor服务功能比较简洁,所有的处理都在manager.py文件中的类ConductorManager来完成整整的数据库访问操作。
manager.py文件是nova-conductor注册的RPC Server接收到RPC请求后,manager中的类ConductorManager真正地完成数据库访问操作。
api.py文件是RPC调用的再一层封装,其他模块导入的是api而不是rpcapi

数据库访问的特殊性在于需要区分是不是需要通过RPC访问,api.py文件中定义了4个类:

  • LocalAPI:nova-conductor访问数据库的接口,当nova-compute和nova-conductor部署在一个节点上时,并不需要RPC调用去访问数据库,可以直接通过LocalAPI直接操作数据库。
  • API:nova-conductor访问数据库的接口,当nova-compute和nova-conductor部署不在一个节点上时,类API使用rpcapi.py中定义的类ConductorAPI发送RPC请求给nova-conductor远程访问数据库。
  • LocalComputeAPI:用于TaskAPI任务,nova-api和nova-conductor同节点时,不需要RPC访问。
  • ComputeAPI:用于TaskAPI任务,nova-api和nova-conductor不同节点时,需要RPC访问。

Conductor的数据库访问

对于数据库的访问,不论是本地或者RPC,最终真正完成操作的都是manager.py里面的类CondoctorManager和ComputeTaskManager。
类CondoctorManager:

类ConductorManager经过多重继承于nova.db.base.Base,类Base会根据配置选择db_driver定义导入相应的nova.db模块。在这里面的sqlalchemy的model.py文件中就会有每一个类对应的数据库中的一张表。

4. Nova Scheduler

通常来说,一个主机上面,都会部署着许多个虚机。众多的虚拟机分享着主机的资源,这就需要使用某种规则来进行协调。
在Nova里面,Scheduler服务就是来裁决虚拟机的生存空间和资源分配的,包括找到合适的主机来容纳新的虚拟机,考虑包括内存使用率,CPU负载等多种因素来选择主机。
从Juno开始,社区致力于剥离nova-scheduler为Gantt,从而提供一个通用的调度服务被多个项目使用,目前仍在开发中,尚未投入使用。

调度器类型

目前Nova中实现的调度器有:

  • ChanceScheduler
    随机调度器,从所有nova-compute服务正常的节点中随机选择。
  • FilterScheduler
    过滤调度器,根据指定的过滤条件以及权重挑选最佳节点。
  • CachingScheduler
    FilterScheduler的一种,在FilterScheduler的基础上将各主机资源信息缓存在本地内存中,然后通过后台的定时任务定时从数据库中获取最新的主机资源信息。

调度器的实现

为了方便扩展,Nova将一个调度器必须实现的接口提取出来成为一个父类:nova.scheduler.driver.Scheduler,只要继承了SchedulerDriver并实现其中的接口,就可以实现一个自己的调度器。
不同的调度器不能共存,在nova.conf里面通过制定scheduler_driver选项指定,默认是FilterScheduler。

FilterScheduler从API到调度完成一共有四个阶段:

Rpcapi到Manager

这步的请求和其他服务均保持一致,就是从nova.scheduler.rpcapi:SchedulerAPI发出RPC请求到nova.scheduler.manager:SchedulerManager中。

Manger到Driver

这步是从SchedulerManagerSchedulerDriver的过程,会在类SchedulerManager初始化的时候根据配置文件指定初始化相应的调度器。

Driver到Filters

Filtering就是使用配置文件指定的各种Filters去过滤掉不符合条件的主机。
在Juno版本之后,一共有28个Nova官方支持的Filter,在nova/scheduler/filters目录中,

Filters的配置是在conf文件中指定的。
下面列举部分常用的,更多的信息参考链接。

Filters 功能
AllHostsFilter 不进行任何过滤
ImagePropertiesFilter 根据镜像属性进行过滤
AvailabilityZoneFilter 根据AZ元数据进行过滤
ComputeFilter 挑选出所有处于活跃状态的主机
RamFilter 根据内存的可用情况过滤
DiskFilter 根据磁盘的可用情况过滤
CoreFilter 根据CPU的可用情况过滤
NumInstancesFilter 根据可容纳虚机数的的情况过滤
PciPassthroughFilter 挑选出提供PCI SR-IOV支持的主机
DifferentHostFilter 一次性创建多个虚机时可以差异分布虚机
SameHostFilter 一次性创建多个虚机时都部署在同个主机
TrustedFilter 挑选出所有可信的主机

Weighting

Weighting是指所有符合条件的主机计算权重并排序得出最佳的一个。经过Filters之后,会得到一个Host列表,然后通过配置的weight来得出每个主机总权重值,进行排序选优。

5. Nova Compute

Nova是OpenStack的计算组件,控制着一个个虚拟机的状态变迁与生老病死,而Nova对虚机生命周期的管理正是由nova-compute服务来完成的。

虚拟机状态显示

nova/objects/instance.py中定义的虚拟机属性里面,有三个字段与描述虚拟机状态相关的:

  • Power_state:
    使用Libvirt等virt driver提供的接口从Hypervisor中获取的虚拟机的状态,如:running、shutdown、nostate等。
  • Vm_state:
    虚拟机的稳定状态,如active表示运行良好;
  • Task_state:
    虚拟机的运行状态,与compute-api的执行紧密相关,表示虚拟机正在进行什么样的任务,如suspending。

Virt Driver

Nova本身并不提供虚拟化技术,只是借助各种主流的虚拟化,比如KVM、Xen等实现虚拟机的创建与管理,因此,作为Nova的核心,nova-compute要和不同的Hypervisor进行交互。
各种Hypervisor的支持通过Virt Driver的方式实现,如下目录:

Disk和image是工具函数目录,ironic是提供baremetal支持的,目前Nova中实现了Libvirt、VMware、xen、hyperv四种Virt Driver。

LibVirt + KVM

Nova-compute需要安装在每一个作为计算节点的主机上面,nova-api会通过RPC机制调用Compute API,然后nova-compute调用libvirt库提供的API来实现虚拟机的管理。

VMwareVCDriver

由VMware在Grizzly版本中加入,允许Nova与管理ESXi主机集群的vCenter进行通信。

Exsi与Nova的集成


通过修改配置能够在nova-compute节点使用vCenter来作为计算节点。在混合环境中,会有如下特点:
1. 不同于其他基于内核的hypervisor,vSphere需要一个单独的vCenter主机,VM是运行在Esxi主机上面,而不是运行在对应的compute节点上的。
2. 一个计算节点只能支持一种hypervisor。
3. VMwareVCDriver有限制,一个nova-compute服务只能对应一个vSphere集群。同在vSphere集群下面的虚机有HA的能力。
4. 在nova外部看来,vSphere就相当于一个计算节点,不能感知内部各个Esxi主机的情况,只能通过API获得整个cluster的资源总数。

Nova-scheduler与vCenter DRS

Nova使用Nova-Scheduler服务来确定VM需要创建到哪个节点上。Nova-Scheduler,同DRS一样,通过一些具体参数、policy、亲和性规则,来自动选择VM初始创建的位置。但是,Nova-Scheduler在VM创建之后,是不会再进行周期性LB+电源管理的。
vCenter会管理整个ESXi集群并且将所有ESXi节点与Nova计算节点分离开。当ESXi主机故障时,vSphere HA将被激活并且将所有VM在其他节点上重启,DRS将会保证这些VM的分配平衡。Nova是不感知这些VM移动的,只是vCenter上报的可用资源总数会变少,然后被Nova记录下来,并在下次创建VM时起作用。

典型工作流程

创建虚拟机

  1. 用户发送API命令到nova中,nova-api进行认证处理后,发送RPC消息到nova-Conductor中。
  2. 创建虚拟机等TaskAPI任务,已经由nova-Conductor承担,这里就会调用到nova.conductor.manager:ComputeTaskManager中的build_instances()方法。
  3. Nova-conductor会在build_instances()中生成虚拟需要的详细信息,nova-scheduler根据信息需求来选择一个最佳的主机。
  4. 选择主机后再通过RPC调用nova-compute创建虚机。
  5. Nova-compute再调用具体的Virt Driver来进行虚拟机的创建。

OpenStack创建虚拟机的过程


参考《别以为真懂Openstack: 虚拟机创建的50个步骤和100个知识点》

  • Nova

    • Nova的服务简介
    • Oslo项目
    • Nova 的源码结构
      • Setupcfg
      • Nova的其他服务
  • Nova API
    • Nova API的目录结构
    • Nova API执行过程
      • novaclient将用户命令转换成标准的HTTP请求
      • HTTP请求到WSGI Application
      • WSGI Application到具体的执行函数
  • Nova Conductor
    • Nova Conductor源码目录
    • Conductor的数据库访问
  • Nova Scheduler
    • 调度器类型
    • 调度器的实现
      • Rpcapi到Manager
      • Manger到Driver
      • Driver到Filters
      • Weighting
  • Nova Compute
    • 虚拟机状态显示
    • Virt Driver
      • LibVirt KVM
      • VMwareVCDriver
        • Exsi与Nova的集成
        • Nova-scheduler与vCenter DRS
    • 典型工作流程
      • 创建虚拟机
      • OpenStack创建虚拟机的过程

参考链接:
《OpenStack设计与实现》
Openstack官网
《云计算与OpenStack(虚拟机Nova篇)》
《深入浅出Neutron :OpenStack网络技术》

OpenStack Nova hacking和读书笔记相关推荐

  1. openstack nova 分析笔记

    原文地址:https://blog.csdn.net/u010827484/article/details/82627646 Openstack Nova 分析笔记

  2. 《深入浅出DPDK》读书笔记(十五):DPDK应用篇(Open vSwitch(OVS)中的DPDK性能加速)

    Table of Contents Open vSwitch(OVS)中的DPDK性能加速 174.虚拟交换机简介 175.OVS简介 176.DPDK加速的OVS 177.OVS的数据通路 178. ...

  3. 《深入浅出DPDK》读书笔记(十四):DPDK应用篇(DPDK与网络功能虚拟化:NFV、VNF、IVSHMEM、Virtual BRAS“商业案例”)

    Table of Contents DPDK应用篇 DPDK与网络功能虚拟化 157.网络功能虚拟化 13.1.1起源 158.发展 159.OPNFV与DPDK NFV的部署 160.NFV的部署 ...

  4. 《Hadoop权威指南》读书笔记1

    <Hadoop权威指南>读书笔记 Day1 第一章 1.MapReduce适合一次写入.多次读取数据的应用,关系型数据库则更适合持续更新的数据集. 2.MapReduce是一种线性的可伸缩 ...

  5. linux设备驱动读书笔记

    linux设备驱动读书笔记 设备驱动简介 机制:提供什么能力 策略:如何使用这些能力 在编写驱动时, 程序员应当编写内核代码来存取硬件, 但是不能强加特别的策略给用户, 因为不同的用户有不同的需求. ...

  6. 读书笔记:云计算概念、技术和架构

    最近开始看之前买了好久的书<云计算概念.技术和架构>,最近公司和部门都在紧锣密鼓地推动云计算在生产运维中部署落地,未来的五年规划更是围绕云计算进行铺开,在这个背景下实在有必要多啃几本关于云 ...

  7. 读书笔记《游戏改变世界》

    近几天读完了这本书<游戏改变世界>--简·麦格尼格尔.在博客里发下读书笔记,应该没问题吧? 阅读这本书让我收获颇多,也感慨贫穷限制了我的想象力(手动滑稽),开拓了我的视野.中学阶段的一个想 ...

  8. linux设备驱动读书笔记(转)

    linux设备驱动读书笔记 设备驱动简介 机制:提供什么能力 策略:如何使用这些能力 在编写驱动时, 程序员应当编写内核代码来存取硬件, 但是不能强加特别的策略给用户, 因为不同的用户有不同的需求. ...

  9. 2015 读书笔记--告诉我你怎样去生活

    个人博客同时更新: tintinsnowy.com 楔子 我想用怎么样的文字来谈读书都是多余.阅读是任何人都可以培养的爱好,可以说是对人影响最深远的爱好.培根那篇伟大的散文<谈读书>已经说 ...

最新文章

  1. 笔记本右侧手滑板Synaptics
  2. 99% 的人都能看懂的「补偿」以及最佳实践
  3. php可以做门禁卡系统吗_PHP研发工程师入门篇:论PHP可以做什么?
  4. 【Linux】一步一步学Linux——more命令(39)
  5. ubuntu运行navicat没有反应的解决方法
  6. Java 8:CompletableFuture的权威指南
  7. 二分图----最大匹配,最小点覆盖,最大点独立集
  8. 王道操作系统考研笔记——2.1.9 调度算法
  9. 我写了一个java实体类,implements了Serializable接口,然后我如何让serialversionUID自动生成...
  10. 如何调整html中音乐播放器的大小,html5实现在线响应式音乐播放器
  11. 洛谷 P2678 [NOIP2015提高组] 跳石头(二分答案)
  12. Linux 大小端转换函数
  13. SparkStreaming概述
  14. 1984-1999:中国电影的黄金十五年
  15. CSS 网格 Gird 布局
  16. macos 管理员权限 黑苹果_自己安装黑苹果,其实黑苹果也没那么难~
  17. 开源 制作磁力链接_3个开源链接缩短器
  18. 软件测试影响与分析,软件测试效率影响因素分析 - Mr.南柯 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  19. 20191127上海出差总结
  20. SaltStacks三:写法和高级状态

热门文章

  1. 旋转体体积的两种常用求法及单位转换问题
  2. mysql数据库实体_关系型数据库中实体之间的关系
  3. 关键帧与地图点(二):关键帧
  4. Epoll 反应堆模型核心原理及代码讲解
  5. 朝九晚五IT人生活不容易啊
  6. GNN in KG(一) Modeling Relational Data with Graph Convolutional Networks,ESWC2018
  7. Tik Tok小店:英国tiktok小店怎么核对结算
  8. input函数以及while处理列表和字典
  9. 6代u笔记本完美支持win7_华硕飞行堡垒六代笔记本安装win7系统的操作教程
  10. LW_OOPC.H 面向对象C MISOO 头文件