根据官方提供的流程图,我个人将OpenStack云主机的创建步骤分为四个阶段:
KeyStone验证阶段
Nova服务组件交换
OpenStack其它服务交换
执行创建
第一阶段:KeyStone验证
用户使用Dashboard Horizon或者命令行CLI,通过REST API给Identity 服务Keystone发送用户凭据(credentials)并验证(authenticates)。Keystone使用用户凭据进行验证,然后返回一个auth-token。然后后续操作就可以使用这个auth-token通过REST调用请求OpenStack其他的组件。
Horizon或者CLI将launch instance 或者nova-boot转换形成为一个REST API的请求发送给nova-api。
nova-api接到这个请求后,首先向keystone发送一个请求来确认auth-token是否有效和是否有访问权限。Keystone确认auth-token后,发送一个包含角色和权限的更新后的认证头。
nova-api和Nova数据库交互,将用户的创建虚拟机的请求在nova 数据库里记录下来。
第二阶段:Nova服务组件交互
nova-api以rpc.call的方式发送一个请求给nova-schedule,让nova-scheduler去选择一个计算节点来创建虚拟机。注意是通过消息队列发送给nova-scheduler。
nova-schedule调度服务会侦听Scheduler队列,从队列中获取数据。
nova-scheduler和Nova数据库交互,通过调度算法,也就是filtering 和weighing最终选择一台运行nova-compute的计算节点,然后nova-schedule将虚拟机信息使用rpc.cast的模式发送至nova-compute.计算节点队列。让nova-compute在选择好的计算节点中去创建实例。
Nova-Compute从队列获取请求。
nova-compute发送一个rpc.call 请求给nova-conductor,去获取实例的信息,比如host ID和选择的Flavor(CPU、内存和磁盘)。
nova-conductor从队列中获取请求。
nova-conductor与nova的数据库进行交互。nova-conductor返回实例的信息。nova-compute从队列中获取实例的信息。
第三阶段:OpenStack其它服务交互
在第二阶段nova-compute为了获取到创建实例所需要的资源,比如镜像、网络、存储。会使用在第一阶段用户验证后获取到的auth-tokon分别和镜像服务Glance的glance-api,网络服务Neutron的neutron-server已经块存储服务Cinder的cinder-api进行交互。而且每次对方收到请求后都需要到keystone上去验证auth-token是否有效。
- nova-compute使用验证后获取的auth-token发起一个REST调用给glance-api获取镜像。然后nova-compute使用使用镜像ID。从镜像服务中得到Image URI。从(image storage)镜像存储中加载镜像。
13.glance-api去Keystone上验证auth-token是否有效。如果有效,nova-compute就可以获取镜像的元数据metadata。
14.nova-compute使用验证后获取的auth-token执行一个REST调用给neutron-server,让neutron-server给分配和配置网络,为实例分配IP地址。
15.neutron-Server去Keystone验证auth-token是否有效。如果有效,nova-compute就可以获取到网络的相关信息。
16.nova-compute使用验证后获取的auth-token执行一个REST调用给cinder-api,给实例附加卷存储,也就是云硬盘。
17.cinder-api去Keystone验证auth-token是否有效,如果有效,那么nova-compute就可以获取到块存储的相关信息。
第四阶段:执行创建
在第三阶段,nova-compute已经通过Glance、Neutron和Cinder分别获取到了镜像、网络和存储相关的信息。那么在第四阶段nova-compute就开始创建虚拟机了。
18.nova-compute为hypervisor的驱动生成数据,并且通过libvirt或者其他API让hypervisor执行请求来创建虚拟机。这样虚拟机创建的交互流程基本结束,剩下的步骤就是hypervisor最终创建虚拟机的流程。
然后nova-api去轮训nova database,查看虚拟机的状态是否变成正确创建虚拟机的状态(Active,none,sunning),若状态正确,则虚拟机创建正常成功。
Paste.deploy
python中的WSGI(Web Server Gateway Interface)是Python应用程序或框架与Web服务器之间的一种接口,定义了一套借口来实现服务器与应用端的通信规范。按照一套规范,应用端想要通信,很简单,只需要实现一个接受两个参数的,含有call方法并返回一个可遍历的含有零个或者多个string结果的python对象。
服务端,对于每个http请求,调用一次应用端“注册”的那个协议规定应用必须实现的对象,然后返回相应的响应消息。 WSGI Server唯一的任务就是接收来自client的请求,然后将请求传给application,最后将application的response传递给client。中间存在的一些东西,就需要中间件来处理。
Paste Deployment是用于发现和配置WSGI appliaction和server的系统。对于WSGI application,用户提供一个单独的函数(loadapp),用于从配置文件或者python egg中加载WSGI application。因为WSGI application提供了唯一的单独的简单的访问入口,所以application不需要暴露application的内部的实现细节。
在OpenStack中,定义了很多的资源,每个资源有一些操作函数,最终,这每一个资源组成了一个单一的WSGI APP,这就说明了,一个WSGI Server可以对应多个WSGI APP,这样保证了资源之间的独立性。
最后一个是,ExtensionManager,存在这么多的资源,需要使用一个较好的方式对他们进行管理,能够方便的为后期添加更多的资源,丰富OpenStack的API。这样就出现了ExensionManager,对这些扩展资源进行统一的管理。
在controller的元类中,就会有wsgi_actions和wsgi_extends两个字典,将这些方法收集起来,key为action或者extends的名字,value为该方法,这样http请求中如果有这样的名字,就直接映射到对应的方法上了。
第三部就是对扩展资源使用mapper.resource。第一步已经将所有的扩展资源加载起来了,第三步则遍历ExtensionManager中的self.extensions字典,获取其中所有的extensions,如果该extensions定义了新的资源,则将其提取出来,并判断该资源是否继承于self.resource中的某类资源,然后将该资源封装成WSGI APP,建立路由规则。
完成上面的这些工作之后,APIRouter的最后一个操作便是将包含了所有的WGSI APP的mapper传递到基类Router中去,Router类是所有wsgi request的入口类,接收到wsgi request后,并将该请求分发到具体的某个WSGI APP。
- 首先通过WSGI Server将HTTP request封装成wsgi request
- 使用api-paste.ini文件中定义的Filter对wsgi request进行处理
- 处理完毕后,就根据mapper中的记录,将不同的请求路由到不同的WSGI APP
- WSGI APP接收到请求之后,并将请求disptach到controller中的方法上
从配置文件中找到WSGI APP程序启动的入口,例如nova的api-paste.ini文件。
定义好APP需要操作的资源,这儿我们主要是app的版本资源。
完成好url到资源的映射。