您的位置:首页 > 大数据 > 人工智能

CloudFoundry warden 创建container 源码研究

2014-03-07 10:14 441 查看
阅读完 warden启动的源码,又看了创建container的源码:

在lib/warden/server.rb中,run!方法下,使用了EM的start_unix_domain_server的方法启动了一个unixsock,第二个参数ClientConnection定义了接收到东西怎么处理,ClientConnection中的process方法具体处理了create:

when Protocol::CreateRequest

container = Server.container_klass.new

container.register_connection(self)

response = container.dispatch(request)

(container_klass为配置中的Warden::Container::Linux)

通过dispatch,会执行linux.rb中的do_create方法。

(1) 获取,设置 rootfs 的存放目录warden 单独运行时 /tmp/warden/rootfs

(2) 执行脚本 src/warden/root/linux/create.sh ,传入参数:新建的container路径;container需要的其他参数

(2.1) 检查 container 路径是否已经存在,如果已经存在,则停止创建

(2.2) 将\src\warden\warden\root\linux\skeleton 目录下的 全部copy到container

(2.3) 执行container下的脚本,unshare -m setup.sh 创建单独的文件系统命名空间

(2.3.1) 将以下信息 写入 container 下的etc/config 文件,后面在启动网络的时候,会加载该文件

id=17jqe2nv7dh

network_netmask=255.255.255.252

network_host_ip=10.254.0.5

network_host_iface=w-17jqe2nv7dh-0

network_container_ip=10.254.0.6

network_container_iface=w-17jqe2nv7dh-1

user_uid=10001

rootfs_path=/tmp/warden/rootfs

allow_nested_warden=false

(2.3.2)执行setup_fs_ubuntu()

mount -n -t aufs -o br:tmp/rootfs=rw:$rootfs_path=ro+wh none mnt

aufs的参数格式表示tmp/rootfs是以读写方式挂载,$rootfs_path以只读方式挂载,堆叠挂载到mnt上

(2.3.3) 将轻量级的container中需要的文件方法container目录下的mnt路径:包括Container中增加用户,配置dns,配置域名,hosts文件。。。。

(2.4) 函数write_bind_mount_commands:执行lib目录下的hook-child-before-pivot.sh

(2.4.1)将request中需要进行绑定的操作写入到hook-child-before-pivot.sh脚本,如果dea需要增加mount的信息,可以通过设置request参数

(2.4.2) 如果允许嵌套warden,需要在该container中创建 /tmp/warden/cgroup 目录,并将新建的container中的/tmp/warden/cgroup 目录和宿主机上的/tmp/warden/cgroup 进行一次mount,cgroup下的子系统 cpu cpuacct devices memory 进行同样的mount操作 (这里只是将进行的操作写入到脚本ook-child-before-pivot.sh)

(3)启动container,调用启动脚本:warden\root\linux\skeleton\start.sh

(3.1) 载入配置文件source ./etc/config

(3.2) 启动网络 ./net.sh setup

(3.3)执行C 代码

nice -n 10 ./bin/wshd --run ./run --lib ./lib --root ./mnt --title "wshd: $id" \

设置进程优先级, 红色部分为 执行./bin/wshd 的参数

Wshd.c 源码:

1、将参数写入结构体wshd_t

2、parent_run 函数,配置wshd.sock路径

w->fd = un_listen(path); 建立socket绑定

rv = barrier_open(&w->barrier_parent); // 建立管道

rv = barrier_open(&w->barrier_child);

unshare(CLONE_NEWNS); 把挂载的文件系统设置成只在新的挂载命名空间(mountnamespace)中可见

run(w->lib_path, "hook-parent-before-clone.sh"); //执行脚本,将 只读的rootfs和可写的rootfs全部挂载到 container中的 mnt目录

pid = child_start(w); // 进行clone clone参数包含

(各个表示的含义http://www.cnblogs.com/lisperl/archive/2012/05/03/2480316.html)

flags |= CLONE_NEWIPC; //

flags |= CLONE_NEWNET;

flags |= CLONE_NEWNS;

flags |= CLONE_NEWPID;

flags |= CLONE_NEWUTS;

克隆完成后,执行函数int child_run(void *data),这个函数还不是很理解:

大体包含:执行脚本hook-child-before-pivot.sh

设置共享内存,执行container内的 /sbin/wshd 启动container
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: