我们现在想要将进程囚禁在某个固定的路径下, 不要让他在宿主机上乱跑, 这样就能做到容器内的监狱的效果, 本节聊聊如何打造一个小型监狱.
第一次进入监狱
# 开始准备监狱内的设备, 我们先准备一个sh
$ mkdir -p jail/bin
$ cp /bin/sh jail/bin
# 这些是sh会用到的依赖库
$ cp -r /{lib,lib64} jail
# 看看现在监狱里有啥
$ tree jail | head -n 5
jail
|-- bin
| `-- sh
|-- lib
| |-- apparmor
`-- lib64
# 进监狱看看
$ chroot jail /bin/sh
$ pwd
/
$ ls
/bin/sh: 2: ls: not found
进了监狱以后, root路径正式变成了 ./jail, 我们在chroot里指定进入监狱以后执行的操作是 jail/bin/sh, 因为根路径下并没有 /bin/ls, 因此报错 ls not found. 好, 我们已经初步具备如何打造一个小型监狱的能力了. 进一步的, 我们想为这个小型监狱里准备更多的工具, 我们先通过 logout /exit 退出监狱, 接着:
隔离宿主机的pid信息
# 我们添加进 ps /mount 两样工具
$ cp /bin/{ps, mount} jail/bin
$ mkdir -p jail/proc && cd jail
# 再次进入监狱
$ chroot . /bin/sh
# 我们把刚刚创造的 /proc 路径挂载上一个proc文件系统
# 因为使用 ps 命令的基本要求, 就是要有/proc
$ mount -t proc proc /proc && ps
PID TTY TIME CMD
13965 ? 00:00:00 bash
14765 ? 00:00:00 sh
14769 ? 00:00:00 ps
[pid信息是未隔离状态?] 从上面的结果可以看到, 尽管我们人的确在监狱内, 但居然能看到外面世界的进程信息, 这不容器, 也不隔离, 现在我们尝试一下看看如何隔离宿主机的pid信息
# fork出一个子进程执行sh命令(新shell)
# 并令这个子进程处在一个新的pid命名空间下
$ unshare --pid --fork /bin/sh
# 进入监狱
$ chroot . /bin/sh
# 并挂载新的proc文件系统
$ mount -t proc proc /proc && ps
PID TTY TIME CMD
1 ? 00:00:00 sh
3 ? 00:00:00 sh
7 ? 00:00:00 ps
$ pstree
sh # unshare搞出来的sh
|--sh # chroot搞出来的sh
|-- pstree
[隔离完成的监狱] 现在可以看到了, 此时我们的监狱内只有三个进程了, 分别是1/3/7, 这种表现已经跟Docker容器非常接近了, 因为你知道它们不可能真的是1/3/7号进程, 仅仅是因为它们处于一个新的命名空间下
Reference