我正在Docker一个旧项目。该项目中的一个功能引入了用户指定的Git存储库,并且由于存储库的大小可能会导致文件系统不堪重负,因此我创建了一个固定大小的本地文件系统,然后安装了它。这是为了防止Web主机填充其文件系统。
通用方法是这样的:
IMAGE=filesystem/image.img
MOUNT_POINT=filesystem/mount
SIZE=20
PROJECT_ROOT=`pwd`
# Number of M to set aside for this filing system
dd if=/dev/zero of=$IMAGE bs=1M count=$SIZE &> /dev/null
# Format: the -F permits creation even though it's not a "block special device"
mkfs.ext3 -F -q $IMAGE
# Mount if the filing system is not already mounted
$MOUNTCMD | cut -d ' ' -f 3 | grep -q "^${PROJECT_ROOT}/${MOUNT_POINT}$"
if [ $? -ne 0 ]; then
# -p Create all parent dirs as necessary
mkdir -p $MOUNT_POINT
/bin/mount -t ext3 $IMAGE $MOUNT_POINT
fi
这在Linux本地或远程VM上运行良好。但是,我想在容器中运行此Shell代码或类似的代码。我想要这样做的部分原因是将所有杂物包含在一个容器中,以便使构建新的主机尽可能简单(在我看来,在上设置自定义安装和cron-restart规则主机对此表示反对)。
因此,此命令在容器内不起作用(“文件系统”是主机上的Docker卷)
mount -t ext3 filesystem/image.img filesystem/mount
mount: can't setup loop device: No space left on device
它也不适用于容器文件夹(“filesystem2”是容器目录):
dd if=/dev/zero of=filesystem2/image.img bs=1M count=20
mount -t ext3 filesystem2/image.img filesystem2/mount
mount: can't setup loop device: No space left on device
我想知道容器是否没有正确的内部机械来进行安装,因此我是否应该改变路线。我不希望在此上花费太多时间(我只是将项目移到仅Docker的服务器上),这就是为什么我想让
mount
运行的原因。其他选择
如果那不可能,那么我需要研究一个既可以使用Docker又可以使用Swarm的大小受限制的Docker卷。关于此功能是否确实有效,网络上存在相互矛盾的报告(see this question)。
有一个suggestion here表示Flocker支持此功能。但是,我犹豫使用该方法,因为它似乎出现在be abandoned上,大概受了ClusterHQ破产的影响。
This post表示我可以将
--storage-opt size=120G
与docker run
一起使用。但是,docker service create
似乎不支持它(除非该选项已重命名)。更新资料
根据convo的评论,我取得了一些进展。我发现将
--privileged
添加到docker run
可以进行挂载,但要删除安全隔离。一位有用的评论者说,最好使用更细粒度的--cap-add SYS_ADMIN
控件,允许容器保留一些隔离。但是,Docker Swarm尚未实现这两个标志中的任何一个,因此我无法使用此解决方案。 This lengthy feature request向我建议不要急于添加此功能;它已经待了两年了。
最佳答案
您将无法在容器内安全地执行此操作。 Docker会从容器中删除安装特权,因为使用该特权您可以安装主机文件系统并转义容器。但是,您可以在容器外部执行此操作,然后使用默认的本地驱动程序将文件系统作为卷挂载到容器中。大多数文件系统不支持size选项,tmpfs是少数异常(exception)之一。它们大多数使用您通过镜像文件创建命令定义的基础设备的大小:
dd if=/dev/zero of=filesystem/image.img bs=1M count=$SIZE
我在让docker动态创建循环设备方面遇到了麻烦,因此这是手动创建它的过程:
$ sudo losetup --find --show ./vol-image.img
/dev/loop0
$ sudo mkfs -t ext3 /dev/loop0
mke2fs 1.43.4 (31-Jan-2017)
Creating filesystem with 10240 1k blocks and 2560 inodes
Filesystem UUID: 25c95fcd-6c78-4b8e-b923-f808517b28df
Superblock backups stored on blocks:
8193
Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
定义卷挂载选项时,几乎逐字传递了您在命令行上运行的mount命令:
docker volume create --driver local --opt type=ext3 \
--opt device=filesystem/image.img app_vol
docker service create --mount type=volume,src=app_vol,dst=/filesystem/mount ...
或在单个服务中创建命令:
docker service create \
--mount type=volume,src=app_vol,dst=/filesystem/mount,volume-driver=local,volume-opt=type=ext3,volume-opt=device=filesystem/image.img ...
使用
docker run
,命令如下所示:$ docker run -it --rm --mount type=volume,dst=/data,src=ext3vol,volume-driver=local,volume-opt=type=ext3,volume-opt=device=/dev/loop0 busybox /bin/sh
/ # ls -al /data
total 17
drwxr-xr-x 3 root root 1024 Sep 19 14:39 .
drwxr-xr-x 1 root root 4096 Sep 19 14:40 ..
drwx------ 2 root root 12288 Sep 19 14:39 lost+found
唯一的先决条件是在创建服务之前创建此文件和循环设备,并且无论计划了什么服务都可以访问此文件。我还建议使这些命令中的所有路径完全合格,而不要相对于当前目录。我很确定在某些地方相对路径不起作用。
关于docker - 我可以在Docker Alpine容器内使用 “mount”吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52348221/