在 LXD 容器中,我创建了一个磁盘映像文件,并最终弄清楚了如何挂载它。但是,挂载映像的副作用是主机操作系统可以查看和读取它。
有什么方法可以将此图像安装到容器内部,但又将其保持为容器的私有图像?
Ubuntu 16.04.3 LTS(GNU/Linux 4.4.0-93-generic x86_64)lxd 版本 2.17
答案1
我可以通过显式创建新的私有挂载命名空间来隐藏挂载。首先,我启用了循环设备和挂载,如下所示此方法。
$ lxc exec z1 touch foo
$ lxc exec z1 truncate -s 100M foo
$ lxc exec z1 mkfs.ext4 foo
mke2fs 1.43.4 (31-Jan-2017)
Discarding device blocks: done
Creating filesystem with 102400 1k blocks and 25688 inodes
Filesystem UUID: 79152d07-1b5e-4b60-b716-84e72a1cce50
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
$ lxc exec z1 mount foo /mnt
$ lxc exec z1 touch /mnt/foo
使用此配置,挂载点在容器外部不容易看到(mount
例如,它不是列出的输出)。我必须使用以下方式访问它/proc/<pid-of-container-process>/cwd
(这反过来只能由 root 访问,而不能由可以运行命令的普通用户访问lxc
):
$ grep /mnt /proc/*/mounts | head
/proc/13782/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/13858/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/14266/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/14394/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/14397/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/14398/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/14406/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/14407/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/14420/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
/proc/14421/mounts:/dev/loop2 /mnt ext4 rw,relatime,data=ordered 0 0
$ ls /proc/14421/cwd/mnt
ls: cannot access '/proc/14421/cwd/mnt': Permission denied
$ sudo ls /proc/14421/cwd/mnt # a process in the container
foo lost+found
现在,使用以下方式创建私有挂载命名空间unshare
:
$ lxc exec z1 bash
root@z1:~# umount /mnt
root@z1:~# unshare --mount -- /bin/bash
root@z1:~# mount --make-private foo /mnt
root@z1:~# ls /mnt
foo lost+found
root@z1:~# exit
root@z1:~# ls /mnt
root@z1:~# exit
现在,这些命令没有产生任何输出:
$ sudo ls /proc/14421/cwd/mnt
$ grep /mnt /proc/*/mounts | head
但现在容器中任何需要访问此挂载点的进程都需要在该挂载命名空间中运行。这可以使用nsenter
, 例如。