详解CloudFoundry中各个组件的做用

CloudFoundry是一个标杆性的项目,架构设计上有不少值得借鉴之处。从CloudFoundry官网摘了一张图,咱们以此剖析各个组件的做用。 CloudFoundryhtml

Router

Router是整个平台的流量入口,负责分发全部的请求到对应的组件,包括来自外部用户对app的请求和平台内部的管理请求。nginx

Router是PaaS平台中相当重要的一个组件,它在内存中维护了一张路由表,记录了域名与实例的对应关系,所谓的实例自动迁移,靠得就是这张路由表,某实例宕掉了,就从路由表中剔除,新实例建立了,就加入路由表。git

CloudFoundry1.0中的router是用nginx+lua嵌入脚本实现的,2.0用golang重写,改名为gorouter,性能有所提高,并声称试图解决websocket请求和tcp请求(虽然这在笔者看来是没用的),它的代码在https://github.com/cloudfoundry/gorouter,你们能够研究一下。github

Authentication

这块包含两个组件,一个是Login Server,负责登陆,一个是OAuth2 Server(UAA),UAA是个Java的项目,若是想找一个OAuth2开源方案,能够尝试一下UAAgolang

Cloud Controller

Cloud Controller负责管理app的整个生命周期。用户经过命令行工具cf与CloudFoundry Server打交道,实际主要就是和Cloud Controller交互。web

用户把app push给Cloud Controller,Cloud Controller将其存放在Blob Store,在数据库中为该app建立一条记录,存放其meta信息,而且指定一个DEA节点来完成打包动做,产出一个droplet(是一个包含Runtime的包,在任何dea节点均可以经过warden run起来),完成打包以后,droplet回传给Cloud Controller,仍然存放在Blob Store,而后Cloud Controller根据用户要求的实例数目,调度相应的DEA节点部署运行该droplet。另外,Cloud Controller还维护了用户组织关系org、space,以及服务、服务实例等等。数据库

Health Manager

Health Manager最初是用Ruby写的,后来用golang写了一版,称为HM9000,HM9000主要有四个核心功能:缓存

  • 监控app的实际运行状态(好比:running, stopped, crashed等等),版本,实例数目等信息。DEA会持续发送心跳包,汇报它所管辖的实例信息,若是某个实例挂了,会立马发送“droplet.exited”消息,HM9000据此更新app的实际运行数据
  • HM9000经过dump Cloud Controller数据库的方式,获取app的指望状态、版本、实例数目
  • HM9000持续比对app的实际运行状态和指望状态,若是发现app正在运行的实例数目少于要求的实例数目,就发命令给Cloud Controller,要求启动相应数目的实例。HM9000自己,不会要求DEA作些什么。它只是收集数据,比对,再收集数据,再比对
  • 用户经过cf命令行工具是能够控制app各个实例的启停状态的,若是app的状态发生变化,HM9000就会命令Cloud Controller作出相应调整

说到底,HM9000就是保证app可用性的一个基础组件,app运行时超过了分配的quota,或者异常退出,或者DEA节点整个宕机,HM9000都会检测到,而后命令Cloud Controller作实例迁移。HM9000的代码在这里:https://github.com/cloudfoundry/hm9000,有兴趣的同窗能够研究一下安全

Application Execution(DEA)

DEA,即Droplet Execution Agent,部署在全部物理节点上,管理app实例,将状态信息广播出去。好比咱们建立一个app,实例的建立命令最终会下发到DEA,DEA调用warden的接口建立container,若是用户要删除某个app,实例的销毁命令最终也会下发到DEA,DEA调用warden的接口销毁对应的container。websocket

当CloudFoundry刚刚推出的时候,Droplet包含了应用的启动、中止等简单命令。用户应用能够随意访问文件系统,也能够在内网畅通无阻,跑满CPU,占尽内存,写满磁盘。你一切能够想到的破坏性操做均可以作到,太可怕了。CloudFoundry显然不会听任这样的状况过久,如今他们开发出了Warden,一个程序运行容器。这个容器提供了一个孤立的环境,Droplet只能够得到受限的CPU,内存,磁盘访问权限,网络权限,再没有办法搞破坏了。

Warden在Linux上的实现是将Linux内核的资源分红若干个namespace加以区分,底层的机制是CGROUP。这样的设计比虚拟机性能好,启动快,也可以得到足够的安全性。在网络方面,每个Warden实例有一个虚拟网络接口,每一个接口有一个IP,而DEA内有一个子网,这些网络接口就连在这个子网上。安全能够经过iptables来保证。在磁盘方面,每一个warden实例有一个本身的filesystem。这些filesystem使用aufs实现的。Aufs能够共享warden之间的只读内容,区分只写的内容,提升了磁盘空间的利用率。由于aufs只能在固定大小的文件上读写,因此磁盘也没有出现写满的可能性。

LXC是另外一个Linux Container。那为何不使用它,而开发了Warden呢。由于LXC的实现是和Linux绑死的,CloudFoundry但愿warden能运转在各个不一样的平台,而不仅是Linux。另外Warden提供了一个Daemon和若干Api来操做,LXC提供的是系统工具。还有最重要的一点是LXC过于庞大,Warden只须要其中的一点点功能就能够了,更少的代码便于调试。

Service Brokers

app在运行的时候一般须要依赖外部的一些服务,好比数据库服务、缓存服务、短信邮件服务等等。Service Broker就是app接入服务的一种方式。好比咱们要接入MySQL服务,只要实现CloudFoundry要求的Service Broker API便可。但实际状况是在咱们使用CloudFoundry以前,MySQL服务已经由DBA作了服务化、产品化,用起来已经很方便了。有必要实现其Service Broker API,按照CloudFoundry这套规则出牌么?笔者认为没有这个必要。app仍然按照以前访问MySQL服务的方式去作便可,没有任何问题。

Message Bus

CloudFoundry使用NATS做为内部组件之间通讯的媒介,NATS是一个轻量级的基于pub-sub机制的分布式消息队列系统,是整个系统能够松散耦合的基石。

咱们以向router注册路由为例来讲明NATS的做用。不论是外部用户对平台上的应用发起的请求,仍是对内部组件(好比Cloud Controller、UAA)发起的请求,都是经由router作的转发,要能让router转发则首先须要向router注册路由。大致逻辑实现以下:

  • router启动时,会订阅router.register这个channel,同时也会定时的向router.start这个channel发送数据
  • 其余须要向router注册的组件,启动时会订阅router.start这个channel。一旦接收到消息,会马上收集须要注册的信息(如ip、port等),而后向router.register这个channel发送消息。
  • router接收到router.register消息后当即更新路由信息
  • 以上过程不停循环,使router的状态时刻保持最新

Logging and Statistics

Metrics Collector会从各个模块收集监控数据,运维工程师能够据此来监控CloudFoundry,出了问题及时发现并处理。物理机的硬件监控则能够采用传统的一些监控系统来作,好比zabbix之类的。

Log这块是个大话题,CloudFoundry提供了Log Aggregator来收集app的log。咱们也能够经过其余手段直接把log经过网络打出来,好比syslog、scribe之类的。

参考资料

同步发表在个人blog:http://blog.ulricqin.com/article/cloudfoundry-component

相关文章
相关标签/搜索