【容器】容器的创建原理

容器=cgroup(资源控制)+namespace(访问隔离)+rootfs(文件系统隔离)+容器引擎(生命周期控制)

容器的创建原理

  1. 创建进程
    pid = clone(fun, stack, flags, clone_arg);
    (flags: CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWPIC | CLONE_NEWUTS | ...)
    
    通过clone系统调用,并传入各个namespace对应的clone flag,创建了一个新的子进程,该进程用用自己的pid、mount、user、net、ipc、uts namespace。
  2. 设定cgroup
    简单的说,创建一个新的cgroup就是在cgroupfs的挂载目录中创建一个新的文件夹,因为cgroup分了不同的subsystem,挂载在不同的目录下,所以在每个目录下都创建一个新的文件夹,将进程的pid写进去。
    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
    
    将进程pid写入各个cgroup子系统中。
  3. 创建文件系统
    fun()
    {
        ...
        pivot_root("path_of_rootfs/", path);
        ...
        exec("bin/bash");
        ...
    }
    
    该fun函数由上面生成的新进程执行,在fun函数中,通过pivot_root系统调用,使进程进入一个新的rootfs,之后通过进入一个新的rootfs,之后通过exec系统调用,在新的namespace、cgroup、rootfs中执行"/bin/bash"程序。