BOSH CLI 是BOSH命令行的入口,所有对BOSH的操作都是通过BOSH CLI进行。本文中将介绍几个常用命令的执行过程。
bosh micro deploy
用于部署micro bosh,该命令是扩展的bosh cli 命令,来自包bosh_cli_plugin_micro
. 命令入口在/bosh_cli_plugin_micro/lib/bosh/cli/commands/micro.rb
. bosh micro deploy
的具体对应的方法为Bosh::Cli::Command::Micro#perform
代码片段如下,可查看详细代码
def perform(stemcell=nil)
update = !!options[:update]
manifest = load_yaml_file(deployment)
...
if update
...
method = :update_deployment
else
...
method = :create_deployment
end
confirm_deployment("#{confirmation} micro BOSH instance #{desc}")
...
deployer.send(method, stemcell)
...
update_target
...
end
其中deployer方法返回的Bosh::Deployer::InstanceManager实例,根据IaaS类型有[openstack,aws,vcloud,vsphere]四种,详细代码在/lib/deployer/instance_manager/目录下。代码片段如下
def deployer(manifest_filename=nil)
...
if @deployer.nil?
...
@deployer = Bosh::Deployer::InstanceManager.create(manifest)
end
@deployer
end
以及Bosh::Deployer::InstanceManager.create方法
class << self
include Helpers
def create(config)
plugin = cloud_plugin(config)
begin
require "deployer/instance_manager/#{plugin}"
rescue LoadError
err "Could not find Provider Plugin: #{plugin}"
end
Bosh::Deployer::InstanceManager.const_get(plugin.capitalize).new(config)
end
end
bosh micro deploy
基本过程就是加载deployment文件->新建Bosh::Deployer::InstanceManager::Openstack实例,然后执行其update_deployment
或create_deployment
方法。这里我们深入查看create方法。该方法核心在于Bosh::Deployer::InstanceManager#create方法,代码如下:
def create(stemcell_tgz)
...
state.stemcell_cid = create_stemcell(stemcell_tgz) //1
state.stemcell_name = File.basename(stemcell_tgz, ".tgz")
save_state
step "Creating VM from #{state.stemcell_cid}" do
state.vm_cid = create_vm(state.stemcell_cid)
update_vm_metadata(state.vm_cid, {"Name" => state.name})
discover_bosh_ip
end
save_state
step "Waiting for the agent" do
wait_until_agent_ready
end
step "Updating persistent disk" do
update_persistent_disk
end
unless @apply_spec
step "Fetching apply spec" do
@apply_spec = Specification.new(agent.release_apply_spec)
end
end
apply
step "Waiting for the director" do
wait_until_director_ready
end
end
由此可见,在create方法时,deployer的过程如下:
与此同时,在vm instance上的agent随着vm启动而启动,代码片段如下
module Bosh::Agent
BOSH_APP = BOSH_APP_USER = BOSH_APP_GROUP = "vcap"
class << self
def run(options = {})
Runner.new(options).start
end
end
class Runner < Struct.new(:config)
def initialize(options)
self.config = Bosh::Agent::Config.setup(options)
@logger = Bosh::Agent::Config.logger
end
def start
$stdout.sync = true
@logger.info("Starting agent #{Bosh::Agent::VERSION}...")
if Config.configure
@logger.info("Configuring agent...")
Bosh::Agent::Bootstrap.new.configure
Bosh::Agent::Monit.enable
Bosh::Agent::Monit.start
Bosh::Agent::Monit.start_services
else
@logger.info("Skipping configuration step (use '-c' argument to configure on start) ")
end
if Config.mbus.start_with?("https")
@logger.info("Starting up https agent")
require "bosh_agent/http_handler"
Bosh::Agent::HTTPHandler.start
else
Bosh::Agent::Handler.start
end
end
end
end
其中Bosh::Agent::Bootstrap.new.configure代码如下
def configure
logger.info("Configuring instance")
load_settings
logger.info("Loaded settings: #{@settings.inspect}")
if @settings
update_iptables
update_passwords
update_agent_id
update_credentials
update_hostname
update_mbus
update_blobstore
setup_networking
update_time
setup_data_disk
setup_tmp
Bosh::Agent::Monit.setup_monit_user
Bosh::Agent::Monit.setup_alerts
mount_persistent_disk
harden_permissions
end
{ "settings" => @settings }
end
由此可见,当agent获取了configuration信息后,做了这么几个步骤
在deployer和agent交互的同时,一方面deployer利用agent_client向agent发送命令,并等待执行结束,另一方面由openstack执行的操作,都是通过openstack_cpi线程执行,并通知openstack registry,agent在执行时会从openstack registry获取配置信息,并执行deployer发来的指令。