Cloud Foundry技术全貌及核心组件分析



架构设计及核心组件


从总体上看,Cloud Foundry 的架构如图1 所示。经过不断的发展,Cloud Foundry 的组件增加了很多。但核心组件并没有变化,增加的组件是原架构基础上的细化和专门化。Stager 组件解决了打包(Stage)过程需要操作大量文件且操作时间长的问题,所以它作为独立进程,使打包工作异步进行,不阻塞作为核心组件的Cloud Controller。下面是对Cloud Foundry 核心组件的描述。Router。顾名思义,Router 组件在Cloud Foundry中是对所有进来的请求进行路由。进入Router 的请求主要有两类。

  

图1 Cloud Foundry的架构图

第一类是来自VMC Client 或者STS 的,由Cloud Foundry 使用者发出,叫作管理请求。这类请求会被路由到Cloud Controller 组件处理。第二类是对所部署的App 的访问请求。这部分请求会被路由到App execution,即DEA 组件中。简单地说,所有进入Cloud Foundry 系统的请求都会经过Router 组件。Router 组件是可扩展的,由多个 Router 共同处理进来的请求。但如何对Router 做负载均衡不属于Cloud Foundry 的实现范围,Cloud Foundry 只须保证所有Router 都可以处理任何请求,而管理员可用DNS 实现负载均衡,也可部署专用硬件来实现,或者简单点,弄个Nginx 做负载均衡。

在第一个版本中,Router 工作由router.rb 来做,所有请求都必须经过Ruby 代码处理转发。这个设计简单直接,只是容易引起性能问题,新版中做了如下改进,如图2 所示(左侧为第一版本,右侧为新版)。

 

图2 Router工作过程(新旧版对比)

使用Nginx 的Lua 扩展,在Lua 中加入URL查询和统计的逻辑。如果Lua 不知道当前的URL 应该路由给哪一个DEA,则会发一个查询请求到router_uls_server.rb(也就是图3 中的“Upstream Locator SVC”)。router_uls_server.rb是一个简单的Sinatra应用,它存储了所有URL 与DEA IP:Port 对应关系。另外,它也管理了请求的Session 数据。

 

图3 DEA模块架构图(新旧版对比)

这样一来,大量的业务请求在Lua 查询过并保存位置后,都由Nginx 直接转发,不再经过

Router,性能和稳定性都大幅提高。

Router 的设计中有个难点:我们知道HTTP 请求是有上下文的,那如何保证请求的上下文完整呢?简单说就是如何保证有上下文的请求每次都可以找到同一个DEA 处理?Cloud Foundry 是支持Session 的,当Router 发现用户请求中带了Cookie 信息,它会在Cookie 里暗藏一个应用实例的id。当有新请求时,Router 通过解析Cookie 得到上次的应用实例,然后转发到同一台DEA 上。这信息与上面的查询类似,会先存在于Upstream Locator SVC 中,当Lua 知道后会保存在Nginx内部提高效率。

DEA (Droplet Execution Agency)。首先要解释下什么叫做Droplet。在Cloud Foundry 中,

Droplet 指把提交的源代码及Cloud Foundry 配置好的运行环境(如Java Web 就是一个Tomcat),再加一些控制脚本,如start/stop 等,全部打包在一起的tar 文件。Staging App 是指制作Droplet,然后把它存储起来的过程。Cloud Foundry 会保存这个Droplet,直到启动(start)一个App 时,一台部署了DEA 模块的服务器会来拿这个Droplet的副本去运行。因此,如果将App 扩展到10 个实例(instance),那么这个Droplet 就会被复制10 份,供10 台DEA 服务器运行。

图3 是DEA 模块的架构图(左侧为第一版本,右侧为新版)。

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 的实例运行情况。

另外,DEA 还要负责部分对Droplet 的查询工作。例如,如果用户通过Cloud Controller 想查询一个App 的log 信息,那么DEA 需要从该Droplet 里面取到log 返回等。

Cloud Controller。Cloud Foundry 的管理模块。简单来说,就是与VMC 和STS 交互的服务器端,它收到指令后发消息到各模快,管理整个云的运行,相当于Cloud Foundry 的大脑。

以部署一个App 到Cloud Foundry 为例。在输入push命令后,VMC开始工作,在做完一轮用户鉴权、查看所部署的App 数量是否超过预定数额、问了一堆相关App 的问题后,需要发4 个指令。

发一个POST 到“apps”,创建一个App;发一个PUT 到“apps/:name/application”,上传App;发一个GET 到“apps/:name/”,取得App 状态,查看是否已启动;如果没有启动,发一个PUT 到“apps/:name/”,使其启动。

第一版的Cloud Controller 是基于Ruby on Rails的,新版的Cloud Controller 用Sinatra 进行了重写,并把部分工作独立成组件, Cloud Controller变得更轻。另一个重要的改进是,第一个版本的Droplet 是通过NFS 共享的,这样会带来安全、性能等方面的问题,新版中采用了自己开发的blobstore 存放Droplet。

随着Cloud Foundry 逐渐成熟,权限管理功能在新版本中逐渐完善。在原有的用户模型基础上,加入了组织和用户空间等概念,细化了管理模型。用户模型的认证是由UAA 模块实现的。在企业环境中,如果用Cloud Foundry 的开源代码搭建私有云,它可以与企业已有的认证系统进行整合,例如LDAP、CAS 等。权限控制是由ACM 模块实现的。图4 给出了用户访问Cloud Controller 某个API 的过程。

 

图4 用户访问Cloud Controller某个API的过程

Health Manager。它做的事情不复杂,简单地说是从各个DEA 拿到运行信息,然后进行统计分析、报告、发出告警等。

Services。服务应属于PaaS 的第三层。Cloud Foundry 把Service 模块设计成一个独立的、插件式的模块,便于第三方方便地把自己的服务整合成Cloud Foundry 服务。在GitHub 上有以下两个相关的子项目值得关注。

vcap-services-base: 顾名思义, 包括CloudFoundry 服务的框架及核心类库。如果开发自定义服务,需要引用到里面的类。vcap-services:目前Cloud Foundry 支持的,包括官方及大部分第三方贡献的服务。这个项目的根文件目录是根据服务名称划分的,可以选择其中自己感兴趣的来研究。

由此可见,Service 模块十分方便为第三方提供自定义服务。从架构来说, Cloud Foundry 服务部分使用了模板方法设计模式,可通过重写钩子方法来实现自己的服务,如果不需要特别逻辑则可以使用默认方法。

现实情况中,种种原因使有些系统服务难以或不愿意迁移到云端,为此Cloud Foundry 引入了Service Broker 模块。

Service Broker 可以使部署在Cloud Foundry 上的应用能访问本地服务。Service Broker 的使用方法如下。

准备被访问的服务。以PostgreSQL 为例,配置好程序和防火墙,让其可以通过类似 postgres://xyzhr:secret@db.xyzcorp.com:5432/xyz_hr_db 的URI 访问。

注册以上URI 到Service Broker。

使用Service Broker 暴露的服务与使用Cloud Foundry 的系统服务无异,准备被访问的服务中的访问服务的URI 通过环境变量传给App。App通过URI 访问暴露出来的服务,这过程不必通过Service Broker。这个过程如图5 所示,与使用系统服务类似,此处不再赘述。

 

图5 使用Service Broker所暴露的服务的过程

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、por t、版本信息等内容。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)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • ​1 轻诉架构 1.1 应用之云飘啊飘 我们知道Cloud Foundry (CF)是一个PaaS平台。 CF命令...
    史春奇阅读 4,106评论 1 5
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,724评论 6 342
  • 1 我承认 这几天在讲题过程中,我发现思维训练多么重要。慢下来,咬文嚼字多么重要。其实就是慢下来体会。很...
    福娃婧阅读 343评论 0 0
  • 常用的设计模式 •单例模式 •组合模式 •观察者模式 •代理模式 •享元模式 •工厂方法模式 •抽象工厂模式 #M...
    指尖猿阅读 268评论 1 3