chroot 只是切根,跟 virtualenv 什么的不大一样,docker 也不大一样。
先说 use case。我习惯的场景:
- chroot 只在从 Linux 里面装 Linux 时使用。需要先展开文件系统、挂载 sys procfs devtmpfs efivars 等等等文件系统,很麻烦的。举个例子,我装 Arch 用的 arch-chroot 就是一个 chroot 的 wrapper
- docker 只是打包管理应用。如果遇到一连串的共享库不一致我可能也会用 docker,或者用类似于 conda 的处理方法。
- conda、virtualenv、我自己写的一些简单的 helper 主要是处理个别程序需要在不同的二进制 /共享库环境下的需求,一般是脚本一类程序的解释器版本的问题或者脚本的库的目录,或者是共享库需要 X Server 以及不一样的版本( preload )
virtualenv 和 conda 之类的工具主要是修改环境变量来修改 shell 和各种工具执行、加载各种程序的行为,比如说 PATH PYTHONPATH PERL5LIB LD_PRELOAD 这些,通过这种方式在一个终端里面执行另一套程序。自己就可以写一些工具来做类似的事情
chroot 实际上是调用了一个 chroot 的函数(
http://man7.org/linux/man-pages/man2/chroot.2.html ),让子进程可以把这个目录认作根目录。并没有隔离太多资源,你实际上还是在同一个命名空间里面用了同样的资源。而且 chroot 需要你提前准备好一套类似于容器镜像的文件系统,很多情况下你还需要把 host 的目录挂载进来才能让程序正常运行。很麻烦的。
此外 chroot 以后如果不切换为普通用户,是可以逃逸出根目录的。
docker 则是利用了 namespace 和 cgroup 来控制和隔离一个进程树,而且用了大量技巧来阻断进程逃逸的过程,而且这几年也出了非常多的基于 kvm 的 runc,相当于轻量级虚拟机,微软打算做的 wsl2 应该是差不多的东西,比如说 kata container,逃逸的难度非常大。而且可以利用现有的 image。主要是为了编排服务出现的。