cloud foundry之dea_ng源码浅析

导读

dea的源码确实很多,在阅读起来存在很大困难,它其中集成了directory_server,以便在用户push应用的时候能够 实时地知道应用的打包情况,这部分代码是用go语言写的,我们在这里暂且先不去理会它。在v1版本中dea就是应用 运行的场所,但在v2版本中app运行的真正地方是在是在warden里面,但是dea启到了一个app管理的作用,一个应用 真正想要在warden中运行起来还是得靠dea。

几个概念

  • droplet :这是cloud foundry中最重要的概念之一,何为droplet,就是客户应用程序的打包,它被cloud_con troller_ng保存在一个droplet仓库中,以供dea去用url下载下来,然后拿去warden里面运行。droplet与应用程序 是一一对应的,用户有多少个应用就有多少个droplet。那么droplet是如何打包的呢?这部分工作当然是由dea来完 成,dea会启动一个应用实例(instance)来专管打包事项。
  • instance :看名字就知道instance就是app的运行实例,它与warden容器中的container是一一对应的,有多少个 container就是有多少个应用实例在起着,如果用户想要把一个应用启动多次,那么dea会把一份droplet用来启动多 个instance,各个instance之间是独立的。
  • staging_task :它是一个cloud controller发过来的任务,用户上传上来的应用要在warden里面运行,必须经过 打包,而打包任务需要dea来进行,所以staging_task就是这个打包存储的任务。它实际上也是为新上传的应用起了 一个instance,然后在warden里面下载环境等,然后打包好发给cloud controller。
  • snapshot :即实例快照,不言而喻,它就是一个实例instance包含的所有信息,dea会为每个起着的instance 保存一份快照,以便下次能通过snapshot快速地启动起来。

bootstrap.rb

bootstrap是整个dea启动的入口类,它的代码看起来非常的清晰:

  1. 确认配置文件,dea的配置文件里有dea所能掌握的内存和磁盘空间信息,里面有index的配置,说明dea是被建议 启动多个的,这也是云计算的要求所在。config里面有个比较重要的配置: warden_socket: /tmp/warden.sock 这是dea与warden通信的socket。

  2. 建立droplet仓库,很好理解dea中药启动多个应用,必须得有一个位置存放本地的droplet(从cloud controller 那里获取的),它就是一个hash表,key是droplet的编号(经过加密的),value就是droplet,别的没啥说的。倒是 droplet这个类会管理自己的行为,droplet的类变量会保持自己的存储目录,编号和等待下载队列,droplet的下载 和删除都是由这个类来控制着。

  3. 建立instance仓库,instance仓库保存着dea中的各个instance,这里就是instance的工作站,一切instance的 增加和删除都要通过这里,instance的管理是通过instance_manager这个类,而具体的要warden去执行的具体工作 则是instance类本身的任务。

  4. 建立staging_task仓库,打包可不是一项简单的任务,牵扯到很多方面,它本省就包括建立instance来帮助打 包,如果app是ruby应用就需要去下载ruby环境,如果是java应用就需要jdk,它主要包括一些buildpack,env, message等方面,在后面我们会对打包细说。

  5. 建立资源管理器,resource是dea的重要资源,它掌握着dea所能把握的cpu,内存和磁盘的空间,及他们的使用 率,当cloud controller来询问他们的资源情况,这个资源管理器中就会有相关信息。

  6. 建立快照和directory_server,snapshot能将instance和staging_task保存起来,如果dea在运行的过程中死掉, 那么重启它时,它会从快照中迅速获取上次运行的相关信息,这就相当于是一个持久化的过程,没有什么难理解的 地方,关于directory_server我们会单独拿出来说。

  7. 建立相关文件夹和捕捉信号,这里的文件夹主要是在/tmp目录下,它是dea存储droplet包,快照等信息的地方, 捕捉的信号主要是一些中断的信号,包括系统的中断和程序指定的中断,捕捉到这些消息后,dea将自动停止运行。

  8. 建立定时任务,每隔一定时间(默认是10secs)去检查instance的活性,如果instance没有报告自己的活性, 那么这个instance就会被认为是死掉了。

9.剩下就是建立nats连接,到router那注册directory_server与instances的url,以便外界能够访问。

说到这里大家就应该对dea所做的工作有一个大致的了解了,下面我们来选择一些比较重要的类来进行解析,以便 能有一个更完整的印象。

droplet

与droplet紧密相关的两个类是Droplet和DropletRegistry,后者没啥好说的就是一个前者类的仓库罢了,Droplet主 要有下面四个方法:

  • download 去cloud controller那儿下载droplet包
  • local_copy 看名字是将本地的droplet自己存入droplet仓库中
  • destroy 删除这个droplet
  • with_pending_downloads 建立下载等待列表

droplet的下载依靠dea/utils/download这个download类。

instance

与instance相关的是Instance,InstanceManager和InstanceRegistry等,后者无非就是对instance的一些增删和 选择动作,我们先来看看InstanceRegistry的方法,首先它有三个定时任务:

  • reap_orphaned_crashes 去除没有在仓库中注册的孤儿instances
  • reap_crashes 去除那些已经失活了的instances,即没有回应dea的心跳动作
  • reap_crashes_under_disk_pressure 当磁盘出现压力时,清除死掉的instances(按时间戳来选择)

还有一个方法instances_filtered_by_message,它根据参数message来选择instances。注意每个app可能启动多 个instance。

然后进入Instance,这个类代码比较多,想要看明白比较困难,得先来理清一下思路:

  • instance有8个状态: "BORN","STARTING","RUNNING","STOPPING","STOPPED","CRASHED","DELETED", "RESUMING"。源码中间的很多动作都是对着八个状态之间的转换的处理,最主要的是InstanceManager,它会 把这些状态之间的转换实时发送出去,让其他组件知晓(特别是cc)。基本上对instance的所有操作都是在对 这八个状态之间的转换进行的。

  • instance中包含的信息有:应用信息,服务信息,资源信息。应用信息是从cc处获得的,包括droplet,app等 等,服务信息主要是这个应用需要绑定的服务,资源信息自然就是这个instance所占用的物理资源。这些信息基 本上就是这个instance的全部生存情况。

  • Contain这个类就是warden创建的instance运行容器,dea的命令在warden中执行是靠这个类联系起来的,dea 接收cc发来的所有任务都要靠它与warden通信来执行,比如:dea的app启动,停止命令等。源码里面有个link 函数,它是instance的状态从resuming到running时,需要将dea中的instance和warden里面的contain联系起来 时起作用。

  • 快照,没什么好说的就是保存一份instance的完整信息,以便快速重启。

大致就只能分析这么多了,里面的代码实在太多。

staging_task

staging_task顾名思义,就是dea承担的打包任务,StagingTaskRegistry没什么好说的,打包任务仓库而已,直接 进入StagingTask这个类,它无非关系到三个方面:

  • app的下载,用户上传的不可能是一个droplet,只能是一个应用,它会从cc那里下载到app的package,然后放 到warden中解包安装必要的环境,如sinatra的程序就需要ruby环境。
  • buildpack_cache,上文中提到的ruby环境到底从哪里去下载,如果你认为是从Internet上面下载,那么你只答 对了一半,因为几乎所有的平台都会提供一个cache机制。contain会先去buildpack_cache中寻找合适的环境包, 如果没有才去网上下载,这就是为什么我们在测试的时候,打包会那么快,光是下载的时间就足够你等的。已经 下载的包会被存储到buildpack_cahce中,以供下次使用。
  • 打包完成后会被打包成为droplet,然后upload给cc。

最后完成一些清理工作,整个打包过程就算完成了。

后记

dea大致的工作流程就是这样,如果要进行cloud foundry方面的开发,需要去调试平台,这里面的代码就需要去 好好追踪一下,想了解一下cloud foundry,到这里已经可以了。下一篇,我会解读warden,整个平台最底层,最 核心的部分is coming。



Previous     Next
zhing /
Published under (CC) BY-NC-SA in categories cloudfoundry  tagged with cloudfoundry