Cloud Foundry技术全貌及核心组件分析
文/彭麟历经一年多的发展,Cloud Foundry的架构设计和实现有了众多改进和优化。为了便于大家了解和深入研究首个开源PaaS平台——Cloud Foundry,《程序员》杂志携手Cloud Foundry社区开设了“深入Cloud Foundry”专栏,旨在从架构组成、核心模块功能、源代码分析等角度来全面剖析Cloud Foundry,同时会结合各行业的典型案例来讲解Cloud Foud..
·
文/彭麟 历经一年多的发展,Cloud Foundry的架构设计和实现有了众多改进和优化。为了便于大家了解和深入研究首个开源PaaS平台——Cloud Foundry,《程序员》杂志携手Cloud Foundry社区开设了“深入Cloud Foundry”专栏,旨在从架构组成、核心模块功能、源代码分析等角度来全面剖析Cloud Foundry,同时会结合各行业的典型案例来讲解Cloud Foudry在具体应用场景中的表现。
架构设计及核心组件 从总体上看,Cloud Foundry的架构如图1所示。 [caption id="attachment_14475" align="aligncenter" width="532" caption="图1 Cloud Foundry架构图"]
[/caption] 经过一年多的发展,Cloud Foundry的组件增加了很多。但核心组件并没有变化,增加的组件是原架构基础上的细化和专门化。Stager组件解决了打包(Stage)过程需要操作大量文件且操作时间长的问题,所以它作为独立进程,使打包工作异步进行,不阻塞作为核心组件的Cloud Controller。 下面是对Cloud Foundry核心组件的描述。
Router。顾名思义,Router组件在Cloud Foundry中是对所有进来的请求进行路由。进入Router的请求主要有两类。
- 第一类是来自VMC Client或者STS的,由Cloud Foundry使用者发出,叫做管理请求。这类请求会被路由到Cloud Controller组件处理。
- 第二类是对所部署的App的访问请求。这部分请求会被路由到App execution,即DEA组件中。简单地说,所有进入Cloud Foundry系统的请求都会经过Router组件。Router组件是可扩展的,由多个 Router共同处理进来的请求。但如何对Router做负载均衡不属于Cloud Foundry的实现范围。Cloud Foundry只须保证所有Router都可以处理任何请求,而管理员可用DNS实现负载均衡,也可部署专用硬件来实现,或者简单点,弄个Nginx做负载均衡。
[/caption]
- 使用Nginx的Lua扩展,在Lua中加入URL查询和统计的逻辑。
- 如果Lua不知道当前的URL应该路由给哪一个DEA,则会发一个查询请求到router_uls_server.rb(也就是图2中的“Upstream Locator SVC”)。
- router_uls_server.rb是一个简单的Sinatra应用,它存储了所有URL与DEA IP:Port对应关系。另外,它也管理了请求的Session数据。
[/caption] Cloud Foundry刚推出时,用户部署的应用可以在内网畅通无阻,跑满CPU,占尽内存,写满磁盘。因此,Cloud Foundry开发出了Warden,用这个程序运行容器解决这一问题。这个容器提供了一个隔绝环境,Droplet只可以获得受限的CPU、内存、磁盘访问权限和网络权限。 Warden在Linux上的实现是将Linux 内核的资源分成若干个namespace加以区分,底层的机制是CGROUP。这样的设计比虚拟机性能好,启动更快,也能够获得足够的安全性。 DEA的运行原理没有发生根本改变:Cloud Controller模块会发送start/stop等基本的App管理请求给DEA,dea.rb接收这些请求,然后从blobstore下载合适的Droplet。前面说到Droplet是一个带有运行脚本和运行环境的tar包,DEA只需要把它拿过来解压,并执行里面的start脚本,就可让应用运行起来,App也就可以被访问了。换句话说,就是这台服务器的某一个端口已经在待命,只要有request从这个端口进来,这个App就可以接收并返回正确的信息。 接着,dea.rb要做以下一些善后的工作。 把这个信息告诉Router模块(前面说到,所有进入Cloud Foundry的请求都是由Router模块处理并转发的,包括用户对App的访问请求。一个App运行起来后,需要告诉Router,让它根据负载均衡等原则把合适的请求转进来,使这个App的实例能够干活)。
- 一些统计性的工作。例如要把这个用户又新部署了一个App告诉Cloud Controller,以作quota控制等。
- 把运行信息告诉Health Manager模块,实时报告该App的实例运行情况。
- 发一个POST到“apps”,创建一个App;
- 发一个PUT到“apps/:name/application”,上传App;
- 发一个GET到“apps/:name/”,取得App状态,查看是否已启动;
- 如果没有启动,发一个PUT到“apps/:name/”,使其启动。
[/caption]
Health Manager。它做的事情不复杂,简单地说,是从各个DEA获得运行信息,然后进行统计分析、报告、发出告警等。
Services。服务应属于PaaS的第三层。Cloud Foundry把Service模块设计成一个独立的、插件式的模块,便于第三方方便地把自己的服务整合成Cloud Foundry服务。在GitHub上有以下两个相关的子项目值得关注。
- vcap-services-base:顾名思义,它包括Cloud Foundry服务的框架及核心类库。如果开发自定义服务,需要引用到里面的类。
- vcap-services:目前Cloud Foundry支持的,包括官方及大部分第三方贡献的服务。这个项目的根文件目录是根据服务名称划分的,可以选择其中自己感兴趣的来研究。
- 准备被访问的服务。以PostgreSQL为例,配置好程序和防火墙,让其可以通过类似 postgres://xyzhr:secret@db.xyzcorp.com:5432/xyz_hr_db的URI访问。
- 注册以上URI到Service Broker。
[/caption]
NATS (Message bus)。 Cloud Foundry的架构是基于消息发布和订阅的。联系各模块的是一个叫NATS的组件。NATS是由Cloud Foundry开发的一个基于事件驱动的、轻量级的消息系统。它基于EventMachine实现。第一版本Cloud Foundry被人诟病的一个问题就是NATS服务器是单节点的,让人不大放心。新版NATS能支持多服务器节点,NATS服务器间通过THIN来做通信。NATS的GitHub开源地址是:
https://github.com/derekcollison/nats。代码量不多但设计很精妙,推荐研究它的源代码。 Cloud Foundry各种优秀特性均源于消息通信架构。每台服务器上的各模块会根据当前的行为,向对应主题发布消息,同时也按照需要监听多个主题,彼此以消息进行通信。 可以说,Cloud Foundry的核心是一套消息系统,如果想了解Cloud Foundry的来龙去脉,跟踪它里面复杂的消息机制是非常好的方法。举个最简单的例子,一个装有DEA组件的服务器为加强云的计算能力,被加入到Cloud Foundry集群中。它首先需要表明已准备好随时提供服务,Cloud Controller可将App部署到它这里,Router也可将相关的请求交给它处理;Health Manger可定时为它体检等,它会发布一条消息到主题“dea.start”:
NATS.publish('dea.start', @hello_message_json)@hello_message_json包括DEA的UUID、ip、 port、版本信息等内容。Cloud Controller、Router、Health Manger及其他模块会监听这个主题,得到通知,各自干活。 理解Cloud Foundry的最好方法其实是选定某一操作,如部署一个App、创建服务等,以消息为线索,跟踪到各模块,看其如何处理。这样就可以观察到整个Cloud Foundry的工作流程。本专栏第2篇文章将专门介绍如何以NATS为主线理解Cloud Foundry原理,这里就不做过多叙述了。 总结 在过去的一年中,Cloud Foundry发生了很多改变,足可看出Cloud Foundry社区的活跃。非常希望本文已把Cloud Foundry的原理讲得足够明白,但请不要把本文作为参考手册使用,在VMware中国开发者关系团队的努力下,Cloud Foundry的文档相当完善,强烈推荐以其作为参考(网址: www.cloudfoundry.cn)。 作者彭麟,EMC中国研究院云计算平台与应用实验室高级研究员,主要关注分布式计算、大型系统架构及云计算平台设计领域的相关研究工作。加入EMC 之前,曾就职于阿尔卡特朗讯,参与多个运营商级别的应用产品及系统的架构设计。 本文选自《程序员》杂志2013年1期,未经允许不得转载。如需转载请联系 market@csdn.net 《程序员》2013年杂志订阅送好礼活动火热进行中
更多推荐
已为社区贡献1642条内容
所有评论(0)