容器=cgroup(資源控制)+namespace(訪問隔離)+rootfs(文件系統隔離)+容器引擎(生命周期控制)
容器的創建原理
- 創建進程
通過clone系統調用,并傳入各個namespace對應的clone flag,創建了一個新的子進程,該進程用用自己的pid、mount、user、net、ipc、uts namespace。pid = clone(fun, stack, flags, clone_arg); (flags: CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWPIC | CLONE_NEWUTS | ...) - 設定cgroup
簡單的說,創建一個新的cgroup就是在cgroupfs的掛載目錄中創建一個新的文件夾,因為cgroup分了不同的subsystem,掛載在不同的目錄下,所以在每個目錄下都創建一個新的文件夾,將進程的pid寫進去。
將進程pid寫入各個cgroup子系統中。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函數由上面生成的新進程執行,在fun函數中,通過pivot_root系統調用,使進程進入一個新的rootfs,之后通過進入一個新的rootfs,之后通過exec系統調用,在新的namespace、cgroup、rootfs中執行"/bin/bash"程序。fun() { ... pivot_root("path_of_rootfs/", path); ... exec("bin/bash"); ... }