从数据库分析OpenStack创建虚机流程

作者简介:李金葵,邮箱:892697603@qq.com

治大国若烹小鲜,学OpenStack亦是如此。每一个深入学习OpenStack的人都会从虚拟机创建流程开始自己的OpenStack代码分析之旅,因为它贯穿核心组件,覆盖了大部分OpenStack通用技术。食材的做法有煎、炒、烹、炸,把虚拟机创建流程比作食材,本文就给它换个做法,给读者呈现不同的口味。

基本介绍

在OpenStack创建虚拟机的过程中,可能会涉及到的数据库有三个,分别是:

  • nova
  • nova_api
  • nova_cell0

下图是OpenStack的所有的数据库

这三个数据库里存放的表主要有:

  • nova

早期的OpenStack只有nova一个数据库,里面存放了所有的关于虚拟机的表。如instance表:存放每一个主机主机信息(后面会介绍到);quotas表:项目配额信息 ;fixed_ips表;块存储设备表等。

  • nova_api

从nova数据库中移除的一部分全局数据表组成的数据库,如flavors、key_pairs、quotas等。noav_api的出现是为了解决大规模时消息队列和数据库瓶颈问题。

  • nova_cell0

nova_cell0数据中存放了所有创建失败的instance。虚拟机创建失败后不属于任何一个cell,那么就记录在nova_cell0中。

OpenStack创建虚拟机的过程可以分为三个大的部分:

  • 界面或命令行发送请求到nova-api;
  • nova-api接收到请求,经过nova-scheduler,nova-condutor等模块拿到创建虚拟机的计算节点信息,发送到相应节点;
  • 计算节点的nova-compute请求glance、neutron、cinder等服务获取创建的必要数据,然后调用底层Hypervior创建虚拟机;

代码流程

OpenStack版本众多,本文使用的是Newton。创建虚拟机对应的代码流程大致如下,其中双冒号后面是类名,单冒号后面是函数名。

下面就从虚拟机创建的三个部分结合代码流程,逐个分析在整个过程中数据库的变化。

一、接收请求

工作流程

Dashborad或者CLI命令行请求创建虚拟机,novaclient收到创建命令,将token发送到keystone去验证。keystone通过查询memcached和数据库中的token,返回token的有效性,然后novaclient发送请求到nova-api。nova-api 同样验证token,最后进入到创建虚拟机的第一个函数当中去,

即nova/api/OpenStack/compute/servers.py文件下

controller类中的create方法。这里就是虚拟机创建的入口,万里长征的第一步。

这个方法主要是对传入的虚拟机的参数做简单验证,检查字段合法性、可用域等信息。nova/compute/api.py中的create方法检查是否创建多个实例,是否指定IP,是否指定端口等信息。最后谈一下nova-api模块的一个重要的函数_create_instance()。该函数完成了很多数据库操作。

如上图中,2是为虚拟机指定了创建的域要执行的代码,3是未指定创建的域,需要任务调度完成的代码。不管是否需要调度,创建之前都要将创建虚拟机的参数写入到数据库中,1就是完成这个任务。1中的函数具体的工作如下:

从上图可见创建了4个数据表记录,分别是:req_spec、instance、build_request、

inst_mapping。下面分析四张表的重要意义。

instance表是一张基本表,很多表都依赖于instance表,由于instance表意义重大,下面分析instance表的具体字段。

instance字段分析

从创建instance表的函数传入的数据可以看到,参数有instance_type、image、instance、security_group、block_device_mapping、num_instances、index等字段。

如下是完整的instances表,有多达52个字段。这里给读者一个读后小任务—-分析instances中自己感兴趣的字段,如果能够分析清楚,功力肯定更进一步。

多余的字段暂且不讨论,与创建虚拟机密切相关的字段有三个,分别是:

  • power_state 从Hypervisor获取的虚拟机的状态
  • vm_state 虚拟机通过api产生的状态,有Active、Error、Reboot、Build、Shutoff五种
  • task_state 表示虚拟机正在执行的某种操作

通过这三个字段的变化,能够完整的描述虚拟机创建的过程。如流程图所示,从instance表创建时,vm_state的字段就填入值:Building。power_state和task_state暂时还没有数据。下面的分析就以这个三个字段为主线,串联整个流程。

二、虚机调度

工作流程

nova-api接收到创建请求之后,通过RPC调用nova-conductor写入数据库信息,然后调用nova-scheduler选定创建虚拟机的主机,最后调用nova-compute完成虚拟机的创建。

主要代码是在RPC调用中,下面简单分析nova-conductor中的RPC调用。首先api.py发起调用,使用nova-conductor的客户端。

客户端封装好参数之后直接调用服务端

服务端收到调用,接收参数,完成处理。

在这个过程中,vm_state一直处于Building的状态,task_state则会有一个调度的任务。

在nova/compute/api.py文件下的API.py类的populate_instance_for_create方法中将instance表中的vm_state设置成BUILDING,将task_state设置成SCHEDULING,表明该过程在调度。

调度过程不再详细描述,在整个第二部分中数据的读写有很多。读者有兴趣再做分析。

三、获取创建资源

工作流程

当nova-compute接收到创建虚拟机的请求之后,会调用nova-conductor获取虚拟机的创建参数,如cpu,内存,磁盘,镜像,网络等。接着从glance服务获取镜像,从neutron服务获取网络,从cinder服务获取磁盘(如果安装了cinder服务)。最后调用底层的Hypervisor完成虚拟机创建。

底层创建好之后vm_state的状态会从building变成active,而task_state的状态在获取网络时是NETWORKING,获取磁盘时是BLOCK_DEVICE,最后变成spawning孵化中。

数据表字段变化

进入nova-compute模块之后,

在nova/compute/manager.py

文件ComputeManager类的_do_build_and_run_instance函数中,instance表中要写入vm_states和task_state的状态。

在compute代码模块下的_build_resource函数是为了获取网络资源和磁盘资源。

获取网络时,task_state变成NETWORKING

在neutron服务中,当其收到来自nova_compute的请求之后,会创建网卡对应的port表,在post中填充IP地址时会从ipallocationpools中选择相应网络的网段ip。然后将已经分配过的ip地址写入到ipallocations表中。

更多neutron数据库的内容,可参考如下文章:

https://www.cnblogs.com/goldsunshine/p/7941970.html

获取磁盘时,

task_state变成BLOCK_DEVICE_MAPPING

当所有的资源都获取完成之后,nova-compute会调用底层Hypervisor完成创建,这时task_state的任务会变成孵化状态,这个状态也是持续时间最长的。

当底层驱动创建好虚拟机之后,spwaning的任务完成,instance表中的task_state字段变成none,同时vm_state变成Active,power_state变成Running,虚拟机的创建就完成了。

总结

OpenStack 创建虚拟机流程的分析就到这里结束了,希望数据库读写能够辅助读者更好理解这个过程。一篇文章要分析整个流程是远远不够的,只能是描述一个大概轮廓。由于OpenStack版本众多,代码上可能会有小的出入,读者需仔细辨别。

原文发布于微信公众号 - SDNLAB(SDNLAB)

原文发表时间:2018-08-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏魏豪的专栏

另一个Web应用服务器——Tomcat

Tomcat 由于其比较突出的优势,譬如 技术先进、性能稳定,而且免费,所以深受 Java 语言爱好者的喜爱,并且得到了部分软件开发商的认可,目前已经成为比较流...

3310
来自专栏转载gongluck的CSDN博客

如何用Doxgen制作chm格式文档

对程序员来说,在开发自己的接口时,制作一个easy-go的文档也是coding中必不可少的一步,而且是相当重要的一步,虽然国内很多程序员,现在都略过了这一步。 ...

39311
来自专栏Django Scrapy

conda的使用-管理不同版本的py

当需要管理多种版本的python pip 会比较麻烦 pip安装好的包升级换代也繁琐,anaconda就是来解决这一难题的工具 Anaconda Anacon...

3827
来自专栏生信宝典

Linux学习 - 命令运行监测和软件安装

命令运行监测 监测命令的运行时间 time command ct@ehbio:~$ time sleep 5 real 0m5.003s # 程序开始至...

2226
来自专栏恰童鞋骚年

借助GitHub托管你的项目代码

PS:话说自己注册了GitHub都很久了,却没有怎么去弄,现在系统学习一下,也把自己的学习经历总结下来share给大家,希望大家都能把GitHub用起来,把你的...

1023
来自专栏pythonlove

Linux防火墙iptables(三)

我们前面两篇已经把iptables介绍的比较充分了,今天来说一个iptables对layer 7的实践。我们说过iptables/netfilter工作在内核空...

1542
来自专栏北京马哥教育

ssh代理

ssh隧道技术 1. 用ssh做正向连接 啥叫正向连接?就是client连上server,然后把server能访问的机器地址和端口(当然也包括server自己)...

5368
来自专栏马涛涛的专栏

使用leancloud给简历加数据库,实现留言功能

数据必须存在服务器上,这样任何设备访问服务器都可以得到数据,如果存在客户端的本地,那么其他客户端设备无法读取到.所以数据必须存储在服务器的数据库上

2035
来自专栏accesshub

腾讯云和AWS VPC互通配置

此处仅描述了部署在腾讯云的网关和控制台建立连接的过程,但同样适用于腾讯云,AWS,百度云,华为云。

2253
来自专栏程序员的SOD蜜

分布式系统的消息&服务模式简单总结

分布式系统的消息&服务模式简单总结 在一个分布式系统中,有各种消息的处理,有各种服务模式,有同步异步,有高并发问题甚至应对高并发问题的Actor编程模型,本文尝...

5407

扫码关注云+社区

领取腾讯云代金券