上节总结道Warden::Container::Linux实际上是真正处理请求的类,DEA或者runner通过socket连接以后发送给warden server的请求,都会被转给Warden::Container::Linux处理。该类负责warden container的创建和销毁,bash command在warden container内部的处理和输入输出流定向等。在整个warden的架构中,地位不言而喻。
Warden::Container::Linux使用diapatch方法分发消息,下面具体看一下创建一个warden container历经的流程。
CreateRequest历经before_create, acound_create, do_create, after_create,其中最主要的是do_create方法。
def do_create(request, response)
options = { :env => env.dup }
if request.rootfs
unless Dir.exist? request.rootfs
raise WardenError.new("rootfs #{request.rootfs} not found")
end
options[:env]["rootfs_path"] = request.rootfs
end
#调用create.sh,创建linux skeleton文件结构,开启wshd进程
sh File.join(root_path, "create.sh"), container_path, options
logger.debug("Container created")
#在hook-child-before-pivot.sh中mount对应的文件系统如,buildpack_cache, droplet目录等
write_bind_mount_commands(request)
logger.debug2("Wrote bind mount commands")
#最后是启动warden虚机
sh File.join(container_path, "start.sh"), options
logger.debug("Container started")
nil
end
1.create.sh
[ -n "$DEBUG" ] && set -o xtrace
set -o nounset
set -o errexit
shopt -s nullglob
cd $(dirname "${0}")
if [ $# -ne 1 ]; then
echo "Usage: ${0} <instance_path>"
exit 1
fi
target=${1}
if [ -d ${target} ]; then
echo "\"${target}\" already exists, aborting..."
exit 1
fi
#这里最主要的是将skeleton目录(其实就是一个小型linux虚机目录)拷贝到对应的warden instance目录, 之后调用unshare –m “${target}”/setup.sh,会调用${instance}/shetup.sh
cp -r skeleton "${target}"
unshare -m "${target}"/setup.sh
echo ${target}
2. mount必要的文件系统,例如buildpack cache等。
def add_bind_mount(file, src_path, dst_path, mode)
dst_path = File.join(container_path, "mnt", dst_path[1..-1])
file.puts "mkdir -p #{dst_path}"
file.puts "mount -n --bind #{src_path} #{dst_path}"
file.puts "mount -n --bind -o remount,#{mode} #{src_path} #{dst_path}"
end
hook-child-before-pivot.sh
mkdir -p /var/vcap/data/warden/depot/17vedc80gj3/mnt/var/vcap/data/dea_next/droplets/850c48ada15591d8c6a56a0e1c64cb2846ea00dd
mount -n --bind /var/vcap/data/dea_next/droplets/850c48ada15591d8c6a56a0e1c64cb2846ea00dd /var/vcap/data/warden/depot/17vedc80gj3/mnt/var/vcap/data/dea_next/droplets/850c48ada15591d8c6a56a0e1c64cb2846ea00dd
mount -n --bind -o remount,ro /var/vcap/data/dea_next/droplets/850c48ada15591d8c6a56a0e1c64cb2846ea00dd /var/vcap/data/warden/depot/17vedc80gj3/mnt/var/vcap/data/dea_next/droplets/850c48ada15591d8c6a56a0e1c64cb2846ea00dd
mkdir -p /var/vcap/data/warden/depot/17vedc80gj3/mnt/var/vcap/packages/buildpack_cache
mount -n --bind /var/vcap/packages/buildpack_cache /var/vcap/data/warden/depot/17vedc80gj3/mnt/var/vcap/packages/buildpack_cache
mount -n --bind -o remount,ro /var/vcap/packages/buildpack_cache /var/vcap/data/warden/depot/17vedc80gj3/mnt/var/vcap/packages/buildpack_cache
3.调用${instance}/start.sh,开启wshd进程。该wshd进程应该负责启动在wanden容器中的各个进程,例如bash, java, liberty/tomcat进程等
#!/bin/bash
[ -n "$DEBUG" ] && set -o xtrace
set -o nounset
set -o errexit
shopt -s nullglob
cd $(dirname $0)
source ./etc/config
if [ -f ./run/wshd.pid ]
then
echo "wshd is already running..."
exit 1
fi
./net.sh setup
./bin/wshd --run ./run --lib ./lib --root ./mnt --title "wshd: $id" \
1> ./run/wshd.out.log \
2> ./run/wshd.err.log