编者按:《通过 demo 学习 OpenStack 开发》专栏是刘陈泓的系列文章,专栏通过开发一个 demo 的形式来介绍一些参与 OpenStack 项目开发的必要的基础知识,希望帮助大家入门企业级 Python 项目的开发和 OpenStack 项目的开发。刘陈泓主要关注 OpenStack 的身份认证和计费领域。另外,还对云计算、分布式系统应用和开发感兴趣。
使用 OpenStack 服务的方式
OpenStack 项目作为一个 IaaS 平台,提供了三种使用方式:
- 通过Web 界面,也就是通过 Dashboard(面板)来使用平台上的功能。
- 通过命令行,也就是通过 keystone, nova, neutron 等命令,或者通过最新的 OpenStack 命令来使用各个服务的功能(社区目前的发展目标是使用一个单一的 OpenStack 命令替代过去的每个项目一个命令的方式,以后会只存在一个 OpenStack 命令)。
- 通过API,也就是通过各个 OpenStack 项目提供的 API 来使用各个服务的功能。
上面提到的三种方式中,通过 API 这种方式是基础,是其他两种方式可行的基础。
通过 Web 界面使用 OpenStack 服务这种方式是通过 OpenStack 的Horizon项目提供的。Horizon 项目是一个 Django 应用,实现了一个面板功能,包含了前后端的代码(除了 Python,还包括了 CSS 和 JS)。Horizon 项目主要是提供一种交互界面,它会通过 API 来和各个 OpenStack 服务进行交互,然后在 Web 界面上展示各个服务的状态;它也会接收用户的操作,然后调用各个服务的 API 来完成用户对各个服务的使用。
通过命令行是用 OpenStack 服务的方式是由一系列项目来提供的,这些项目一般都命名为python-projectclient
,比如python-keystoneclient
,python-novaclietn
等。这些命令行项目分别对应到各个主要的服务,为用户提供命令行操作界面和 Python 的 SDK。比如python-keystoneclient
对应到keystone
,为用户提供了keystone
这个命令,同时也提供了keyston
项目的 SDK(其实是在 SDK 的基础上实现了命令行)。这些 client 项目提供的 SDK 其实也是封装了对各自服务的 API 的调用。由于每个主要项目都有一个自己的命令行工具,社区觉得不好,于是又有了一个新的项目python-OpenStackclient
,用来提供一个统一的命令行工具 OpenStack(命令的名字就叫做 OpenStack),这个工具实现了命令行,然后使用各个服务的 client 项目提供的 SDK 来完成对应的操作。
通过 API 使用 OpenStack 的方式是由各个服务自己实现的,比如负责计算的 nova 项目实现了计算相关的 API,负责认证的 keystone 项目实现了认证和授权相关的 API。这些 API 都是有统一的形式的,都是采用了HTTP协议实现的符合REST规范的 API。OpenStack 中如何实现这些 API 就是本文重点要将的内容。
基于 HTTP 协议的 RESTful API
REST 的全称是 Representational State Transfer,中文翻译过来是表征状态转移,是 Roy Fielding 在他的博士论文 ** Architectural Styles and the Design of Network-based Software Architectures ** 提出的一种软件架构风格。可以先到 wikipedia 页面了解一下这个风格的特点。一般会把满足这种设计风格的 API 成为RESTful API
。由于这种软件设计风格非常适合采用 HTTP 协议来实现,因此 HTTP 协议是目前实现 RESTful API 的主要方案。
OpenStack 就是基于 HTTP 协议和 JSON 来实现自己的 RESTful API(之前 OpenStack 还有采用 XML 来表示数据的,现在都已经转到 JSON 了)。当一个服务要提供 API 时,它就会启动一个 HTTP 服务端,用来对外提供 RESTful API。
OpenStack 的 API 都是有详细的文档记录的,可以查看所有的 API 文档。每个 API 的文档形式如下:
当然,你可以点开detail看到详细的说明。从上面这个 API 的文档来看,你会觉得这个和开发网站时使用的 GET 方法和 POST 方法差不多,实际上也是差不多的,只不过对 HTTP 协议的使用方法做了满足 REST 风格的规定而已。
Python 如何实现 RESTful API
因为 Python 能够进行 Web 开发,所以用来开发 RESTful API 也就不成问题,这两者的技术基础是一样。在 Python 下开发 RESTful API 应用,无非是解决两个问题:
- 服务如何部署?
- 用什么框架开发?
服务如何部署?
说到 Python 的 Web 服务部署这个问题,就不得不提到 WSGI。目前 Python 有两种方式来开发和部署一个 Web 应用:用 WSGI 和不用 WSGI。如果你不了解 WSGI,那么你需要先看下另外这篇关于 WSGI 的文章: WSGI 简介。
OpenStack 的 API 服务都是使用 WSGI 的方式来部署的。在生产环境中部署 WSGI,一般会考虑使用 Web 服务器 + 应用服务器 + 应用 (框架) 的方案。OpenStack 官方推荐的是使用Apache + mod_wsgi的方案,不过这个要换成其他方案也很容易,你也可以选nginx + uWSGI。对于开发调试的目的,有些项目也会提供使用 eventlet 的单进程部署方案,比如 Keystone 项目的keystone-all
命令。采用 eventlet 这种异步架构来进行应用开发也是一个比较大的话题,本文不覆盖这方面的内容。
当然,也可以不用 WSGI。在 Python 中,如果不使用 WSGI 的化,一般开发者会选择一些专门的服务器和框架,比如 Tornado ,或者最新最潮的 aiohttp 。不过在 OpenStack 的项目中我还没见过不使用 WSGI 的。
用什么框架开发
Python 的 Web 开发框架很多,最出名自然是 Django 了。基本上,还活跃的框架都支持 RESTful API 的开发,有些框架还专门为 RESTful API 的开发提供了便利的功能(比如 Pecan),有些框架则通过第三方模块来提供这种便利,比如 Django 和 Flask 都有不少和 REST 相关的第三方库。
对于框架选择,也没有什么特别好的标准,一般都是比较性能、文档、社区是否活跃等。在我看来,选择流行的一般就不会错。
OpenStack 中的 RESTful API 开发
上面已经谈到了 OpenStack 都是使用 WSGI,也提到了部署方式。这一章来说一下 OpenStack 中使用的框架。
OpenStack 项目倾向于不重新发明轮子,一般都会选择现有的库和框架来使用,除非现有的框架不满足需求。因为 Web 框架的选择很多,而且都满足需求,所以 OpenStack 项目到目前为止都是使用现成的 Web 框架。
OpenStack 早期的项目并没有使用一个框架,而是使用了几个不同的模块来组合出一个框架:Paste + PasteDeploy + Routes + WebOb,这几个不同的模块分别负责应用的 WSGI 化、URL 路由和请求处理等功能。Nova, Glance, Neutron, Keystone 等早期的项目都是使用这样的架构来实现 RESTful API 的。
早期的这种技术选型带来的好处是”框架”具备足够的灵活性,缺点则是要把这几个模块组合起来实现一个 REST 服务,需要写很多代码,连 WSGI 的入口函数都要自己实现(比如 Keystone 项目的 keystone/common/wsgi.py 文件中的class Application
)。因为灵活性的好处不是很明显,而代码量大的坏处很明显,比如上面那个class Application
需要在每个项目中复制一遍,所以社区的新项目就开始使用新的 Web 框架Pecan。
Pecan 是一个基于对象路由的框架,即灵活又简单。Pecan 主要实现了 URL 路由功能,支持 RESTful API。Pecan 没有实现模板、session 管理和 ORM 等功能,但是这些功能可以通过其他的模块来实现。对于 OpenStack 来说,Pecan 是一个很好的选择,因为 OpenStack 项目中统一使用 sqlalchemy 来实现 ORM,API 的实现也不需要模板功能,安全控制则基于 Keystone 体系。使用 Pecan 来开发 REST 服务,代码量很少,代码结构也清晰。Ceilometer 项目就是使用了 Pecan。
感谢魏星对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群(已满),InfoQ 读者交流群(#2))。
评论