https://yikun.github.io/2017/09/27/OpenStack-Nova%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%88%9B%E5%BB%BA%E6%B5%81%E7%A8%8B%E8%A7%A3%E6%9E%90/html
1. 概述
Nova是OpenStack中处理计算业务(虚拟机、裸机、容器)的组件,总体的虚拟机建立流程天然是学习和熟悉Nova组件的第一步。本篇文章主要基于OpenStack Pike版本,基于最新的Cell v2架构部署为例,来介绍虚拟机的建立流程,并分析了Pike等最近几个版本中,虚拟机建立流程的关键变化。python
2. 虚拟机建立流程
上图是虚拟机建立流程的总体流程,能够看到总体虚拟机建立流程一次通过了API、Conductor、Scheduler、Placement、Compute等主要服务,下面咱们逐步介绍下虚拟机建立时,这些服务作的一些事情以及在Pike版本新引入的部分:git
2.1 Nova-API
在OpenStack的组件中,基本每一个组件都会有一个API服务,对于Nova来讲API服务主要的做用就是接收由用户经过Client或者一些其余REST请求工具(好比 curl、postman)发送的请求。通常来讲会包含一些虚拟机建立的参数,好比虚拟机的规格、可用域之类的信息。github
在虚拟机建立的流程中,API就是Nova的入口,当API接收到请求后,主要会处理一些关于参数校验、配额检测等事务。数据库
1. 参数校验
例如,咱们指定镜像和规格来建立一个虚拟机时,一般会使用:json
1
|
nova --debug boot --image 81e58b1a-4732-4255-b4f8-c844430485d2 --flavor 1 yikun
|
咱们经过--debug
来开启debug模式,来看看命令行究竟作了什么事,能够从回显中,看到一个关键的信息:api
curl -g -i -X POST http://xxx.xxx.xxx.xxx/compute/v2.1/servers -H “Accept: application/json” -H “User-Agent: python-novaclient” -H “OpenStack-API-Version: compute 2.53” -H “X-OpenStack-Nova-API-Version: 2.53” -H “X-Auth-Token: $token” -H “Content-Type: application/json” -d ‘{“server”: {“name”: “yikun”, “imageRef”: “81e58b1a-4732-4255-b4f8-c844430485d2”, “flavorRef”: “1”, “max_count”: 1, “min_count”: 1, “networks”: “auto”}}’网络
咱们能够看到虚拟机建立时,传入了一些诸如虚拟机名称、镜像、规格、个数、网络等基本信息。在API中,首先就会对这些参数进行校验,好比镜像ID是否合法、网络是否正确等。数据结构
2. 配额检测
值得一提的是,在Pike版本的虚拟机建立开始时,对配额检测进行了优化。架构
我先看看以前的实现,在以前版本的Nova中,Quota检测过程相对来讲比较复杂,首先会进行reserve操做,对资源进行预占,而后预占成功,而且建立成功后,最终会进行commit操做。然而,为了保证在并发的场景下,不会对超过用户配额(这都是钱啊!),所以在reserve和commit进行资源更新的时候都会quota相关的数据表的用户相关行加把锁,也就是说更新quota记录的时候,一个用户去更新时,其余用户再想刷新只能等着,直到前一个用户完成数据库记录刷新为止,这样就大大下降的效率,并发的性能也就不是很客观了。
另外,因为须要对cell v2进行支持,目前全部的quota表均已移动到API的数据库了能够参考BPCellsV2 - Move quota tables to API database。Cell V2的设计思想是,由API、Super Conductor去访问上层的全局数据库(nova_api数据库),而底下的cell中的组件,只须要关心cell中的逻辑便可。所以,为了完全的解耦,让cell中的compute无需再访问api数据库进行诸如commit操做,在Pike版本,社区对quota机制进行了优化,详情能够参考Count resources to check quota in API for cells这个BP。
所以Pike版本以后,配额检测变成了这样:
- 首先,api中进行第一次Quota检测,主要方法就是收集地下各个cell数据库中的资源信息,而后和api数据库中的quota上限进行对比。例如,一个用户能够建立10个虚拟机,在cell1中有2个,cell2中有7个,再建立一个虚拟机时,会搜集cell1和cell2中的虚拟机个数之和(9个),而后加上变化(新增一个),与总配额进行比较。
- 二次检测(cell v2在super conductor里作)。因为在并发场景下,可能出现同时检测发现知足,以后进行建立,就会形成配额的超分,针对这个问题,社区目前给出的方案是,在建立虚拟机记录以后,再进行recheck,若是发现超额了,会将超额分配的虚拟机标记为ERROR,再也不继续往下走了。
每次检测的逻辑都调用相同的函数,具体逻辑以下图所示:
2.2 Nova Super Conductor
Super Conductor在建立虚拟机的流程其实和以前差很少,选个合适的节点(调度),而后,写入虚拟机相关的记录,而后,投递消息到选定的Compute节点进行虚拟机的建立。
在Cell v2场景,虚拟机的建立记录已经须要写入的子cell中,所以,conductor须要作的事,包括一下几个步骤:
- 进行调度,选出host。
- 根据host,经过host_mappings找到对应的cell
- 在对应的cell db中建立虚拟机记录,而且记录instances_mappings信息
- 经过cell_mappings来查找对应的cell的mq,而后投递到对应的cell中的compute
完成这些操做时,须要牵扯到3个关键的数据结构,咱们来简单的看一下:
- host_mappings:记录了host和cell的映射信息
- instances_mappings:记录了虚拟机和cell的映射信息
- cell_mappings:记录了cell和cell对应的mq的映射信息
与Cell v1不太相同,在目前的设计中,认为scheduler能看到的应该是底下可以提供资源的具体的全部的Resource Provider(对于计算资源来讲,就是全部的计算节点),而不是整个cell,也就是说全部cell中的资源scheduler均可以看到,而子cell就负责建立就行了。所以,在super conductor中,须要作一些transfer的事情,这样也就没必要在像cell v1那样,在子cell里还得搞个scheduler去作调度。
2.3 Nova-Scheduler
刚才咱们在conductor中,已经介绍了,在选择具体哪一个节点来建立虚拟机时,调用了Scheduler的select_destination方法,在以前的版本的调度中,就是OpenStack最经典的Filter&Weight的调度,已经有大量的资料介绍过具体的实现和用法。能够参考官方文档Filter Scheduler。
在Pike版本中,在调度这部分仍是作了比较大的调度,主要就是2个相关变更。
-
经过Placement获取可用的备选资源,参考Placement Allocation Requests的实现。
在Ocata版本时,Resource Providers - Scheduler Filters in DB这个BP就已经在调度前加了一步,获取备选节点。从BP的标题就能够看出,设计者想经过Placement服务提供的新的一套机制,来作过滤。缘由是以前的调度须要在scheduler维护每个compute节点的hoststate信息,而后调度的时候,再一个个去查,这过低效了,尤为是在计算节点数目比较多的时候。所以,增长了一个“预过滤”的流程,经过向Placement查询,Placement服务直接经过SQL去查一把,把知足条件(好比CPU充足、RAM充足等)先获取到。
而原来获取备选节点的时候,只支持获取单一的Resource Provider,这个BP加强了获取备选资源的能力,用于后续支持更复杂的请求,好比共享资源、嵌套资源的Provider查询。后面,Placement还会陆续支持更多的请求,好比对一些非存量不可计数的资源的支持。这样留给后面Filter&Weight的压力就小一些了,再日后,会不会彻底取代Filter呢?我想,现有的各类过滤均可以经过Placement支持后,彻底有可能的。 -
Scheduler经过Placement来claim资源。参考Scheduler claiming resources to the Placement API的实现。
在最先的时候,claim资源是由compute来作的,如今至关于提早到scheduler去搞了。有什么好处呢?咱们先看看原来的问题:
调度时刻和真正的去compute节点去claim资源的时刻之间是由一段时间的,在资源不是那么充足的环境,就会形成在scheduler调度的时候,资源还没刷新,因此调度时候成功了,可是真正下来的时候,才发现compute实际已经没有资源了,而后又“跨越半个地球”去作重调度,无形地增长了系统的负载。
并且增长了建立的时长(哦,哪怕建立失败呢?),你想一想,用户创了那么久的虚拟机,最后你告诉我调度失败了,用户不太能忍。
因此这个BP就把Claim资源放在调度处了,我上一个调度请求处理完,立刻就告诉placement,这资源老子用了,其余人不要动了。OK,世界终于清净了,能拿到资源的拿到了,拿不到资源的立刻也知道本身拿不到了,大大加强了调度的用户体验。
2.4 Placement
恩,在调度的时候,已经介绍过这个服务了,在虚拟机建立的流程中,比较经常使用的接口就是获取备选资源和claim资源。
Placement目标很宏伟,大体的做用就是:资源我来管,要资源问我要,用了资源告诉我。后面准备用一篇文章总体介绍一下Placement。(yep,这个Flag我立下了,会写的)
2.5 Nova-Compute
好吧,到最后一个服务了,Compute。这个里面依旧仍是作那么几件事,挂卷,挂网卡,调driver的接口启动一下虚拟机。至此,咱们可爱的虚拟机就起来了。
3. 结语
总体的看一下,其实在Pike版本,Nova仍是有不少的变更。真的是一个版本过去了,建立虚拟机的流程已经面目全非了。
从P版本的虚拟机建立流程来看,主要的优化集中在基于Cell V2架构下的多cell支持、调度的优化、Quota的优化,然后续的发展,目前也是集中在Placement各类资源的支持以及在Cell v2场景的诸如基本流程、调度等的优化。