@dujun
2014-12-24T19:40:43.000000Z
字数 4876
阅读 1981
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个脚本:
./scripts/clone_nise_bosh.sh
./scripts/clone_cf_release.sh
./scripts/install_environemnt.sh
./scripts/install_cf_release.sh
然后,就部署就完成了!
该脚本做了这么几件事情:clone cf-release,执行bundle install,做了cf-release(bundle install的时候自然会安装bosh_cli工具)。
就去github上clone nise_bosh。
两句话:
cd nise_bosh
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个过程:
@nb = NiseBosh::Builder.new(@options, Logger.new($stdout))
send("run_#{@run_mode}_mode")
有趣的是下面这个send
方法,class Runner
定义了若干个run_xxx_mode
方法,为了能根据@run_mode
动态调用,所以用了ruby meta programming。至于class Builder
,下面会分析。
下面我们来分析下run_default_mode
方法。首先,调用class Builder
的initialize_environment
方法(下面会分析),接着调用class Builder
的job_templates
方法,返回deployment manifest的jobs(micro, micro_ng)下面的templates,然后会调用class Builder
的job_template_packages
方法,该方法用于生成job.MF,获取jobs所对应的packages,并在屏幕输出^_^。然后再执行最后一个步骤:@nb.install_job(@job_name, @template_only)
,即执行class Builder
的install_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。
bin
init就是上面提到的install_environemnt.sh
间接执行的脚本。这里做的事情简单说就是在模拟stemcell和bosh-agent做的一些事情,包括:安装base_apt
,安装runit(用于监控bosh-agent?),配置logrotate,创建vcap用户,内核补丁?,安装配置monit。
就是调用上面说的重头戏class Runner
的run
方法。nise-bosh这个命令的调用方式一般是这样的:
Usage: nise-bosh [OPTION]... RELEASE_REPOSITORY DEPLOY_MANIFEST JOB_NAME
or: nise-bosh -a [OPTION]... RELEASE_REPOSITORY DEPLOY_MANIFEST JOB_NAME [OUTPUT_PATH]
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
,该类的初始化方法有点意思:
def initialize(options, logger)
...
initialize_release_file
initialize_depoy_manifest
...
# injection
Bosh::Agent::Configuration.set_nise_bosh(self)
Bosh::Agent::Message::Apply.set_nise_bosh(self)
Bosh::Director::DeploymentPlan::Template.set_nise_bosh(self)
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
方法主要做了两件事情:
def initialize_environment
initialize_directories
initialize_monit
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_user
和setup_alerts
方法。
job_templates
方法,返回deployment manifest的jobs(micro, micro_ng)下面的templates。
job_template_packages
方法会调用Bosh::Cli::ReleaseCompiler
的find_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_properties和bind_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启动进程。