无法将基于熔断的卷暴露在Docker容器中。

问题描述 投票:18回答:3

我试图为我的docker容器提供一卷加密的文件系统供内部使用.这个想法是容器将像往常一样写到卷中,但事实上主机将在写到文件系统之前对数据进行加密。

我正在尝试使用EncFS--它在主机上工作得很好,例如:我可以将文件写入到可见的卷中,而在主机上则可以将文件写入到可见的卷中。

encfs /encrypted /visible

我可以把文件写到可见的地方,然后这些文件就会被加密。 然而,当我试图运行一个以可见为卷的容器时,例如:

docker run -i -t --privileged -v /visible:/myvolume imagename bash

我确实在容器中得到了一个卷,但它是在原来的容器上的。/encrypted 文件夹,而不是通过EncFS。如果我把EncFS从 /visible我可以看到容器所写的文件。不用说 /encrypted 是空的。

有没有办法让docker通过EncFS挂载卷,而不是直接写到文件夹?相反,当我使用NFS挂载作为卷时,docker工作得很好。它写到网络设备,而不是写到我挂载设备的本地文件夹。

谢谢,谢谢

linux docker fuse
3个回答
16
投票

我无法在本地复制你的问题。 如果我尝试将一个 encfs 文件系统公开为 Docker 卷,在尝试启动容器时就会出现错误。

FATA[0003] Error response from daemon: Cannot start container <cid>:
setup mount namespace stat /visible: permission denied 

所以有可能是你的问题不一样了 So it's possible you have something different going on. 无论如何,这就是解决我问题的方法。

默认情况下,FUSE只允许挂载文件系统的用户访问该文件系统。 当你在运行一个Docker容器时,这个容器最初是以以下方式运行的 root.

您可以使用 allow_rootallow_other 挂载FUSE文件系统时的挂载选项。 例如

$ encfs -o allow_root /encrypted /other

这里, allow_root 将允许根用户访问挂载点,而 allow_other 将允许任何人访问挂载点(前提是该目录的Unix权限允许他们访问)。

如果我通过 encfs filesytem 挂载,使用 allow_root然后,我可以将该文件系统作为一个Docker卷暴露出来。 该文件系统的内容在容器内部正确可见。


4
投票

这肯定是因为你在主机挂载挂载点之前启动了docker守护进程。在这种情况下,目录名的inode仍然指向主机的本地磁盘。

ls -i /mounts/
1048579 s3-data-mnt

如果你使用s3fs这样的熔断守护进程进行挂载的话

/usr/local/bin/s3fs -o rw -o allow_other -o iam_role=ecsInstanceRole /mounts/s3-data-mnt
ls -i
1 s3-data-mnt

我的猜测是docker会对目录名到inode做一些引导缓存(有更多这方面知识的人可以填补这个空白)。

你的评论是正确的。如果你在挂载完成后简单地重启docker,你的卷将正确地从主机共享到你的容器。(或者你可以简单地推迟启动docker,直到你所有的挂载完成之后)

有趣的是(但现在对我来说是完全的),当退出容器并取消挂载点在主机上的挂载时,我在容器内对共享卷的所有写入都神奇地出现了(它们被存储在主机本地磁盘的inode中)。

[root@host s3-data-mnt]# echo foo > bar
[root@host s3-data-mnt]# ls /mounts/s3-data-mnt
total 6
1 drwxrwxrwx  1 root root    0 Jan  1  1970 .
4 dr-xr-xr-x 28 root root 4096 Sep 16 17:06 ..
1 -rw-r--r--  1 root root    4 Sep 16 17:11 bar
[root@host s3-data-mnt]# docker run -ti -v /mounts/s3-data-mnt:/s3-data busybox /bin/bash
root@5592454f9f4d:/mounts/s3-data# ls -als
total 8
4 drwxr-xr-x  3 root root 4096 Sep 16 16:05 .
4 drwxr-xr-x 12 root root 4096 Sep 16 16:45 ..
root@5592454f9f4d:/s3-data# echo baz > beef
root@5592454f9f4d:/s3-data# ls -als
total 9
4 drwxr-xr-x  3 root root 4096 Sep 16 16:05 .
4 drwxr-xr-x 12 root root 4096 Sep 16 16:45 ..
1 -rw-r--r--  1 root root    4 Sep 16 17:11 beef
root@5592454f9f4d:/s3-data# exit
exit
[root@host s3-data-mnt]# ls /mounts/s3-data-mnt
total 6
1 drwxrwxrwx  1 root root    0 Jan  1  1970 .
4 dr-xr-xr-x 28 root root 4096 Sep 16 17:06 ..
1 -rw-r--r--  1 root root    4 Sep 16 17:11 bar
[root@host /]# umount -l s3-data-mnt
[root@host /]# ls -als
[root@ip-10-0-3-233 /]# ls -als /s3-stn-jira-data-mnt/
total 8
4 drwxr-xr-x  2 root root 4096 Sep 16 17:28 .
4 dr-xr-xr-x 28 root root 4096 Sep 16 17:06 ..
1 -rw-r--r--  1 root root    4 Sep 16 17:11 bar

1
投票

你也许可以通过将挂载调用封装在以下方法来解决这个问题 nsenter 将其挂载在与docker守护进程相同的Linux挂载命名空间中,例如。

nsenter -t "$PID_OF_DOCKER_DAEMON" encfs ...

问题是这种方法是否能在守护进程重启后存活下来。 ;-)

© www.soinside.com 2019 - 2024. All rights reserved.