有了前面的一些基础之后,我们再来看一下,大家可能非常关系的一个问题,就是如何通过OpenStack创建一个虚拟机实例。本文注重结构性分析,细节性问题,请小伙伴们自己多思考撒,因为我也是正在边学Python,边看nova源码的,我的理解肯定会有错误的地方,也劳烦大神们,看到错误的时候,和小弟说一下,先谢了。
1、nova-api <文件位于/nova/api/openstackcompute/server.py>
nova-api起到了一个Cloud Controller的作用,主要为所有的API查询提供了一个接口(比如Openstack API ,EC2 API),引发多数业务流程的活动(如运行一个实例),并实施一些政策(主要是配额检查)。
因为今天我们主题是虚拟机实例的启动过程,所以,重点关注/nova/api/openstackcompute/server.py。找到类class Controller(wsgi.Controller):create()代码段,我们知道nova-api的作用就是对外提供标准REST接口的服务。下面的代码段,已经标注了很多内容,大家看一下即可。
nova-api的create方法作用是将REST接口参数映射到内部接口compute-api.create(),参数转换完成后,create最后会调用如下代码,转去调用comput-api
2、compute-api 的处理过程
compute-api的作用是对外提供了管理compute的api接口,外部模块通过这些接口完成对计算资源的操作。
我们看下上面的代码:a) 首先进行了能否创建实例的资格验证 b)再调用了_create_instance()方法
3、在_create_instance()方法中,做的一些操作有,验证各种参数,如意套餐类型instance_type是否存在,租户配额限制检查等,没问题后,commit一下,确定资源的占用。为了简化问题,我大概描述一下该方法做的事情,具体小伙伴们看一下代码就知道了。
完成上面的操作后,在_create_instance() 最后调用了 self.compute_task_api.build_instances(context,*)方法。
4、我们通过寻找compute_task_api,找到了这个其实conductor.ComputeTaskAPI()的一个对象。
注:关于conductor的话,我们单独还会再讲,G版中开始添加了这个conductor,以前的版本是没有这个东西的。主要作用是隔离compute对数据库的直接操作。
我们转到/nova/conductor/api.py文件下
哈哈,看到了吧,上面的调用给conductor发送了一个rpc消息。根据OpenStack AMQP的rpc消息传递的原理,我们很顺理成章的转到/nova/conductor/manager.py去查看是否在manager.py里面会有”build_instance”方法。找了下,果然有,请看如下代码:[python] [view
看到最后一行,self.scheduler_rpcapi.run_instance(context,)方法,conductor通过调用Scheduler的rpcapi接口,把请求启动虚拟机的相关信息传递到调度器上。就是从这里开始,相关的工作就被转移到了Scheduler中了(关于具体怎么调度的,会有专门的博文,讲述这个过程,今天只关注,虚拟机实例请求是怎么一步一步建立的*)
5、再次转到/nova/scheduler/目录
(1)首先看/nova/shceduler/rpcapi.py**
继续看到最后一句,Scheduler-rpcpai把消息发送到了Scheduler的manager去处理具体的run_instance()方法。(2) 看到/nova/scheduler/manager.py
找到如下代码:
上图代码中,driver通过动态读取nova.conf配置文件,我们知道driver = Filter_Scheduler。创建实例调度的时候,我们默认使用的是FilterScheduler类中的schedule_run_instance()方法,在该方法中,有如下调用,主要作用是通过_schedule方法,筛选出我们需要已经按照经过(Filters筛选+权重计算)的符合条件的最后weight_hosts列表。—筛选的具体过程,我们以后再看,现在暂不做讨论。
Scheduler通过一系列操作选定了最后的compute节点之后,必然要讲控制权,转移到compute中,所以,又要开始一次rpc调用了,如下面代码所述:
(7) 控制权转移,我们需要看/nova/compute目录了,因为前面已经讲过,rpc过来的消息,最后会经过compute-manager处理,所以,我们直接看/nova/compute/compute.py下面的run_instance()方法,代码如下:
至此,再经过compute内部一些操作,一个实例就创建完成了,具体细节不再讨论。