[关闭]
@dujun 2014-12-24T11:40:43.000000Z 字数 4876 阅读 1907

cf_nise_installer源码分析

cf_nise_installer


为什么要学习cf_nise_installer?原因有这么几点:

1.稳定。经过实践检验,cf_nise_installer还是比较可靠、简单易用的。

2.维护力度。yudai这家伙秉承日本人的敬业精神,基本上一个星期一个更新,紧跟cf-release的脚本。每次更新cf_nise_installer绑定的cf-release必然自己亲身测试过。所以,用cf_nise_installer装的cf必然是最新的。
【注】鉴于yudai目前已经不维护nise_bosh,所以最近的cf-release不一定能够部署,但cf-170是肯定可以部署的。

3.这个工具的大部分脚本都是shell写的,对学习者来说是个shell代码宝库(nise_bosh例外,是ruby写的)。

4.去繁从简,这个工具有助于初学者认清安装cf的本质过程,去掉bosh那些复杂的概念,回归安装系统软件这个最原始的本质。

5.nise_bosh与bosh还是有千丝万缕的联系的,学习完bosh后,必须要看下nise_bosh是如何灵活地重用bosh的功能组件的?nise_bosh至少用了bosh_cli,bosh-director,bosh_agent等组件。

manifests

manifests目录下就一个部署的demo文件template.yml

scripts

启动脚本,主要做的事情就是检测机器的系统(ubuntu)和架构(x86 64bit),检测git是否安装(如果没有安装则安装一个),最后执行install.sh脚本。

该脚本主要做的事情包括:rbenv安装ruby,然后执行4个脚本:

  1. ./scripts/clone_nise_bosh.sh
  2. ./scripts/clone_cf_release.sh
  3. ./scripts/install_environemnt.sh
  4. ./scripts/install_cf_release.sh

然后,就部署就完成了!

该脚本做了这么几件事情:clone cf-release,执行bundle install,做了cf-release(bundle install的时候自然会安装bosh_cli工具)。

就去github上clone nise_bosh。

两句话:

  1. cd nise_bosh
  2. sudo ./bin/init

具体init做了什么,下面会详细介绍。

rbenv安装ruby-1.9.3-p484,安装bundler这个ruby gem。

首先要执行scripts/generate_deploy_manifest.sh,具体generate_deploy_manifest.sh做了什么,下面会介绍。然后,进入nise_bosh工程目录,执行bundle install。最后,进入bin/nise-bosh实例化class Runner并调用该类的run方法。run方法是重头戏,下面要好好分析一下。

首先我们得分析class Runner初始化方法,该初始化方法主要设置了@run_mode = :default,并调用了该类的parse_argv方法,填充了@options

接着看run方法,主要是2个过程:

  1. @nb = NiseBosh::Builder.new(@options, Logger.new($stdout))
  2. send("run_#{@run_mode}_mode")

有趣的是下面这个send方法,class Runner定义了若干个run_xxx_mode方法,为了能根据@run_mode动态调用,所以用了ruby meta programming。至于class Builder,下面会分析。

下面我们来分析下run_default_mode方法。首先,调用class Builderinitialize_environment方法(下面会分析),接着调用class Builderjob_templates方法,返回deployment manifest的jobs(micro, micro_ng)下面的templates,然后会调用class Builderjob_template_packages方法,该方法用于生成job.MF,获取jobs所对应的packages,并在屏幕输出^_^。然后再执行最后一个步骤:@nb.install_job(@job_name, @template_only),即执行class Builderinstall_job方法。执行完就done了。这样就部署完成了!

install_job的过程包括install_packages的过程,install_packages的过程又包括解析包依赖的过程(yudai自己写的递归),依据就是jobs的dependencies

顾名思义,就是generate deployment manifest。记得前面提到过,manifests目录下有一个部署的demo文件template.yml,我们实际部署的时候会以这个文件为原型,替换里面的IP,domain,password这三个字段,形成一个新的可用于部署的manifests/deploy.yml

start脚本做的是启动所有monit管理的进程。当然启动过程是由先后顺序的:先postgre,nats,然后其他的一起启动。

与start.sh刚好相反,stop是stop monit管理的进程,也是有先后顺序的,最后stop的是postgre。

nise_bosh

bin

init就是上面提到的install_environemnt.sh间接执行的脚本。这里做的事情简单说就是在模拟stemcell和bosh-agent做的一些事情,包括:安装base_apt,安装runit(用于监控bosh-agent?),配置logrotate,创建vcap用户,内核补丁?,安装配置monit

就是调用上面说的重头戏class Runnerrun方法。nise-bosh这个命令的调用方式一般是这样的:

  1. Usage: nise-bosh [OPTION]... RELEASE_REPOSITORY DEPLOY_MANIFEST JOB_NAME
  2. or: nise-bosh -a [OPTION]... RELEASE_REPOSITORY DEPLOY_MANIFEST JOB_NAME [OUTPUT_PATH]
  3. or: nise-bosh -p [--no-dependency] RELEASE_REPOSITORY PACKAGE_NAME...

像default mode,就3个参数:RELEASE_REPOSITORY dir,DEPLOY_MANIFEST,JOB_NAME(micro or micro_ng)。

lib

定义了class Builder,该类的初始化方法有点意思:

  1. def initialize(options, logger)
  2. ...
  3. initialize_release_file
  4. initialize_depoy_manifest
  5. ...
  6. # injection
  7. Bosh::Agent::Configuration.set_nise_bosh(self)
  8. Bosh::Agent::Message::Apply.set_nise_bosh(self)
  9. Bosh::Director::DeploymentPlan::Template.set_nise_bosh(self)
  10. end

首先看initialize_release_file方法,其实就是找部署的release_file。要么你用最新的final_release(别人已经做好了),要么你用dev_release(自己做的),要么你用最新的(nise-bosh会sort),要么你自己指定release版本(通过options传入参数)。

接着看initialize_depoy_manifest方法,该方法的作用就是加载deployment manifest,比较有意思的是,yudai说nise-bosh的deployment manifest与bosh的deployment manifest是兼容的,甚至是其子集,这一点在这里可以提现。nise-bosh的manifest甚至有compilation等字段!

后面重用了bosh_agent和bosh-director模块,貌似用到了ruby元编程,不知道什么意思。???

该类的很多方法会被bin目录下的脚本调用,下面逐一加以分析:

initialize_environment方法主要做了两件事情:

  1. def initialize_environment
  2. initialize_directories
  3. initialize_monit
  4. end

initialize_directories主要是模拟bosh-agent做的事情,即建立一系列目录((bosh jobs packages monit store shared),并调用bosh-agent的[class Bootstrap]的setup_data_sys方法(其实就是建立data和sys目录)。initialize_monit则是在调用bosh_agent的Monit类的setup_monit_usersetup_alerts方法。

job_templates方法,返回deployment manifest的jobs(micro, micro_ng)下面的templates

job_template_packages方法会调用Bosh::Cli::ReleaseCompilerfind_job方法,该方法会根据.final_builds或者.dev_builds找local或者remote blobstore中的job,最终生成job.MF,而该方法要的是packages

bosh里面的[install_job]是很多人纠结的问题,现在借nise-bosh好好梳理一下,见代码。首先,调用bosh-director的DeploymentPlan模块,做组装(Assembler)工作(其实就是调用bosh-director的9个prepare stages中的一部分stages:bind_propertiesbind_instance_networks)。接着调用bosh-director的JobUpdater模块,update job,对bosh-director而言,update job已经是最后一个步骤。然后,是bosh-agent的事情了,它要install_packages(这些packages是runtime dependencies,至于如何调用send方法,不是很清楚??),当然,在把package传给bosh-agent模块之前,nise-bosh自己用递归的方式解析了安装包的依赖,这里的依赖关系依据是package dependencies。安装包的依赖解析完之后,就让bosh-agent去做packaging操作,疑问:dummy_blob??。最后,bosh_agent会apply_spec,所以,不要误以为bosh-agent是apply_spec的时候在编译安装job依赖的packages。结论:yudai果然对bosh非常熟悉。

总的来说,cf_nise_installer分成两个部分:bootstrap.sh安装组件,start.sh启动进程。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注