上QQ阅读APP看书,第一时间看更新
2.2.2 容器的创建原理
至此对容器的描述还一直停留在文件和概念的层面,本小节将通过简单的代码抽象,清晰地展现容器的创建原理,使读者对容器有更深刻的理解。
代码一:
pid = clone(fun, stack, flags, clone_arg);
(flags: CLONE_NEWPID | CLONE_NEWNS |
CLONE_NEWUSER | CLONE_NEWNET |
CLONE_NEWIPC | CLONE_NEWUTS |
…)
代码二:
echo $pid > /sys/fs/cgroup/cpu/tasks echo $pid > /sys/fs/cgroup/cpuset/tasks echo $pid > /sys/fs/cgroup/blkio/tasks echo $pid > /sys/fs/cgroup/memory/tasks echo $pid > /sys/fs/cgroup/devices/tasks echo $pid > /sys/fs/cgroup/freezer/tasks
代码三:
fun() { … pivot_root("path_of_rootfs/", path); … exec("/bin/bash"); … }
❏ 对于代码一,通过clone系统调用,并传入各个Namespace对应的clone flag,创建了一个新的子进程,该进程拥有自己的Namespace。根据以上代码可知,该进程拥有自己的pid、mount、user、net、ipc、uts namespace。
❏ 对于代码二,将代码一中产生的进程pid写入各个Cgroup子系统中,这样该进程就可以受到相应Cgroup子系统的控制。
❏ 对于代码三,该fun函数由上面生成的新进程执行,在fun函数中,通过pivot_root系统调用,使进程进入一个新的rootfs,之后通过exec系统调用,在新的Namespace、Cgroup、rootfs中执行“/bin/bash”程序。
通过以上操作,成功地在一个“容器”中运行了一个bash程序。对于Cgroup和Namespace的技术细节,将在以下两节详细描述。