这篇博文静静的呆在草稿箱大半年了,如果不是因为某些原因被问到,以及因为忽略它而导致的损失,否则我也不知道什么时候会将它完成。感谢这段时间经历的挫折,让我知道不足,希望你能给我更大的决心!
本文试图详细地描述openstack创建虚拟机的完整过程,从用户发起请求到虚拟机成功运行,包括客户端请求的发出、keystone身份验证、nova-api接收请求、nova-scheduler调度、nova-computer创建、nova-network分配网络。对于每一个模块在创建虚拟机的过程中所负责的功能和执行的操作,进行较为详细描述和讨论。为了方便描述,本文假设所有的服务ip地址为localhost,端口使用服务的默认设置端口。openstack为F版。下图为创建虚拟机的一个大概流程图,粗糙地表示下。接下来将对每一个模块进行详细介绍,如有错误,欢迎拍砖!
客户端
创建虚拟机的第一步是需要客户端调用nova-api,发送创建虚拟机请求。目前openstack提供两种客户端:
1 命令行指令nova,通过指定命令行参数,就可以请求nova-api创建虚拟机,一个最简单的创建虚拟机指令如下:
nova boot vm_name --flavor flavor_id --image image_uuid
2 网页交互页面horizon,这是通过web操作页面来调用nova-api创建虚拟机,比较简单易用。选定相关参数后,点击create就可以了。
这两种客户端除了UI不一样以外,功能方面基本都是一样。就创建虚拟机来讲,它们需要完成:
- 用户身份验证。客户端构造一个body格式如下:
向keystone发送HTTP请求(keystone的服务地址:nova命令一般通过环境变量OS_AUTH_URL设置,horizon则通过openstack_dashboard.local.local_settings.OPENSTACK_KEYSTONE_URL设置),url为http://localhost:5000/v2.0/tokens 。如果验证通过,keystone则返回token_id和serviceCatalog。身份验证通过后,客户端才可对nova-api发送创建请求。因为客户端只配置了keystone的服务地址和端口,对于nova-api的服务地址它是不知道的,所以需要先通过keystone验证,然后由keystone将nova-api的服务地址放在serviceCatalog中返回给它。其实serviceCatalog中不仅仅包含nova-api的服务地址,还有glance-api、cinder-api等服务的地址,这些地址在以后的镜像下载、块存储请求时会用到。token_id被放在请求nova-api的headers中,用作nova-api验证。{"auth": { "passwordCredentials": {"username": self.user, "password": self.password}} "tenantName": "admin" }
- 对传入flavor和image参数进行验证,以确定资源是否有效(对于一些非必须参数,此处省略讨论)。对于nova boot,flavor_id和image_uuid需要通过命令行参数指定,novaclient.v1_1.shell._boot()分别向nova-api的"http://localhost:8774/v2/project_id/flavors/flavor_id"和"http://localhost:8774/v2/project_id/images/image_id"发送HTTP请求,验证资源是否存在。对于horizon,它首先执行horizon.api.nova.flavor_list()和horizon.api.glance.image_list_detailed(),获取所有可用的flavor ids和image ids,创建虚拟机时只能从这些可用的id中选择。注意这里nova boot和horizon对于image的验证有些不同,nova boot是请求nova-api,nova-api再请求glance-api以验证image uuid,而horizon是直接请求glance-api获取所有的image ids。
- 最后设置好请求参数后(除name、flavor和image外,其它可使用默认值),通过novaclient.v1_1.ServerManager.create()发送创建虚拟机请求,该函数主要是将请求参数构造成规定格式的body,然后向nova-api发送HTTP请求。关于body的模样,可看看novaclient.v1_1.BootingManagerWithFind._boot() 。以上面的nova boot命令为例&#x