我基本上想做这样的事情:让我们想象一个名为 的实用程序layer
。
# sudo layer somefile apt install gcc
layer
将在某种容器中启动 apt。 Apt 会认为它在实际文件系统上安装了 gcc,但实际上它正在将所有内容写入somefile
.apt
仍然可以访问整个文件系统。所以它不像docker。
然后,我可以做类似的事情
# sudo layer somefile bash
bash# gcc -c foo.c
即使bash
实际上并未安装在系统上,但安装gcc
在.某种形式的容器/监狱,但可以访问文件系统的其余部分。我的目的是创建虚拟开发环境而不污染我的文件系统。apt
gcc
somefile
有没有办法做到这一点?
答案1
如果您不介意一些自定义脚本,您可以使用覆盖文件系统(自 2014 年起包含在 Linux 内核中)。
OverlayFS 将两个文件系统位置相互叠加:覆盖挂载点显示 中的所有内容lower
,除非它已被 中的某些内容修改或隐藏upper
。对覆盖安装点所做的所有修改都记录在upper
;lower
从未被触及。
此外,OverlayFS 需要一个work
没有明确记录的目录,但显然在修改移动到upper
.
使用它,您可以创建您正在寻找的容器类型(请参阅下面的可能的边缘情况):
mkdir -p /var/tmp/myoverlay/{upper,work,mount}
mount -t overlay -o lowerdir=/,upperdir=/var/tmp/myoverlay/upper,workdir=/var/tmp/myoverlay/work overlayfs /var/tmp/myoverlay/mount
要“进入”容器,您可以使用chroot
(“更改根目录”)命令在新创建的容器中运行命令(shell 或其他)/var/tmp/myoverlay/mount
:
chroot /var/tmp/myoverlay/mount
# or
chroot /var/tmp/myoverlay/mount /usr/bin/apt moo # paths are relative to the new root directory
请注意,这对于尝试访问硬件设备、伪终端、进程或系统功能的程序来说可能还不够:这些是由内核作为特殊的可安装文件系统提供的 - 请参阅下面的输出mount
:
proc on /proc type proc
sysfs on /sys type sysfs
udev on /dev type devtmpfs
devpts on /dev/pts type devpts
您可以将它们安装到覆盖安装点(在输入之前):
mount -t proc proc /var/tmp/myoverlay/mount/proc
mount -t sysfs sys /var/tmp/myoverlay/mount/sys
mount -t devtmpfs dev /var/tmp/myoverlay/mount/dev
mount -t devpts devpts /var/tmp/myoverlay/mount/dev/pts
请注意,这将使您的容器比您想要的更多地访问系统。最终,您需要知道您的确切用例,以确定覆盖文件系统是否与该特定用例的正常系统充分分离。
可能还有一个额外的困难,具体取决于您的文件系统布局:目录lower
按原样使用,而不遵循安装在其下方的任何其他文件系统。例如,如果您/home
是一个单独的文件系统,则 OverlayFS 将仅向您显示位于 的空挂载点/home
。
在这些情况下,您需要为每个安装点创建单独的覆盖,然后将其他覆盖安装到根覆盖中。
此时,您将面临这样一种情况:适当的虚拟化通常是更明智的选择。
答案2
您可以使用overlay
文件系统。
modprobe overlay
mkdir -p /path/data /path/work /path/mount
mount -t overlay overlay -o lowerdir=/,upperdir=/path/data,workdir=/path/work /path/mount
现在您可以chroot
访问/path/mount
并查看根目录中的所有内容,但更改将写入/path/data
.您可以/path/mount
稍后使用相同的选项卸载并重新安装它。