docker - 我可以在Docker Alpine容器内使用 “mount”吗?

标签 docker sh mount alpine

我正在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=120Gdocker 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/

相关文章:

bash - 检测远程安装

linux df 显示旧的挂载

node.js - 从AWS SAM中的 Node 应用程序连接到docker中的mongodb

docker - 无法在 docker/bin/sh : <program>: not found 中运行 go 程序

docker - 从我的本地计算机连接到 docker localhost 端口

bash - 我刚刚分配了一个变量,但 echo $variable 显示了其他内容

tomcat - docker tomcat重新部署应用程序

docker - Jenkins sh 脚本在特定容器中运行时挂起

bash - 将带有空格的第二列视为一列

docker - 使用卷时如何排除子文件夹?