我可以使用"mount"吗?Docker Alpine容器中? [英] Can I use "mount" inside a Docker Alpine container?

查看:89
本文介绍了我可以使用"mount"吗?Docker Alpine容器中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对一个旧项目进行Docker设计.该项目中的一个功能引入了用户指定的Git存储库,并且由于存储库的大小可能会导致文件系统不堪重负,因此我创建了一个固定大小的本地文件系统,然后安装了它.这是为了防止Web主机填充其文件系统.

一般方法是这样:

  IMAGE = filesystem/image.imgMOUNT_POINT =文件系统/挂载尺码= 20PROJECT_ROOT =`pwd`#为该归档系统保留的M数dd if =/dev/zero of = $ IMAGE bs = 1M count = $ SIZE&/dev/空#格式:-F允许创建,即使它不是阻止特殊设备"mkfs.ext3 -F -q $ IMAGE#如果尚未安装文件系统,则安装$ MOUNTCMD |切-d''-f 3 |grep -q"^ $ {PROJECT_ROOT}/$ {MOUNT_POINT} $"如果[$?-ne 0];然后#-p根据需要创建所有父目录mkdir -p $ MOUNT_POINT/bin/mount -t ext3 $ IMAGE $ MOUNT_POINT科幻 

这在Linux本地或远程VM中工作正常.但是,我想在容器中 运行此shell代码或类似的代码.我想要这样做的部分原因是将所有杂物包含在容器中,以便构建新的主机尽可能地简单(在我看来,在上设置自定义安装和cron-restart规则主机对此表示反对.

因此,此命令在容器内不起作用(文件系统"是主机上的Docker卷)

  mount -t ext3文件系统/image.img文件系统/安装安装:无法设置循环设备:设备上没有剩余空间 

它也不适用于容器文件夹("filesystem2"是容器目录):

  dd if =/dev/zero of = filesystem2/image.img bs = 1M count = 20挂载-t ext3 filesystem2/image.img文件系统2/挂载安装:无法设置循环设备:设备上没有剩余空间 

我想知道容器是否没有正确的内部机械来进行安装,因此我是否应该改变路线.我不希望在此上花费过多的时间(我只是将项目移至仅Docker的服务器上),这就是为什么我想让 mount 正常工作的原因.

其他选项

如果这不可能,那么我需要研究一个既可用于Docker又可用于Swarm的大小受限制的Docker卷.关于此功能是否确实有效,网络上存在相互矛盾的报告(看到此问题).

此处的建议可以说这在Flocker中受支持.但是,我很犹豫使用它,因为它似乎被抛弃了,大概是受到了ClusterHQ的影响破产.

此帖子表示我可以将-storage-opt size = 120G docker run .但是,它似乎不受 docker service create 支持(除非该选项已重命名).

更新

根据评论组,我取得了一些进展;我发现将-privileged 添加到 docker run 可以进行挂载,但要以删除安全隔离为代价.一位有用的评论者说,最好使用更细粒度的-cap-add SYS_ADMIN 控件,以使容器保留其某些隔离性.

但是,Docker Swarm尚未实现这两个标志中的任何一个,因此我无法使用此解决方案.这个冗长的功能请求向我建议不要将此功能添加到匆忙;已经有两年了.

解决方案

您将无法在容器内安全地执行此操作.Docker从容器中删除了安装特权,因为使用此方法,您可以安装主机文件系统并转义容器.但是,您可以在容器外部执行此操作,然后使用默认的本地驱动程序将文件系统作为卷挂载到容器中.大多数文件系统不支持size选项,tmpfs是少数例外之一.其中大多数使用您通过映像文件创建命令定义的基础设备的大小:

  dd if =/dev/zero of = filesystem/image.img bs = 1M count = $ SIZE 

我无法让docker动态创建循环设备,因此这是手动创建循环设备的过程:

  $ sudo losttup --find --show ./vol-image.img/dev/loop0$ sudo mkfs -t ext3/dev/loop0mke2fs 1.43.4(2017年1月31日)创建具有10240个1k块和2560个inode的文件系统文件系统UUID:25c95fcd-6c78-4b8e-b923-f808517b28df存储在块上的超级块备份:8193分配组表:已完成编写inode表:已完成创建日志(1024个块):完成编写超级块和文件系统记帐信息:已完成 

定义卷挂载选项时,几乎是从在命令行上运行的mount命令逐字传递的:

  docker volume create --driver local --opt type = ext3 \--opt设备=文件系统/image.img app_voldocker服务创建--mount type = volume,src = app_vol,dst =/filesystem/mount ... 

或在单个服务中创建命令:

  docker服务创建\--mount类型=卷,src = app_vol,dst =/文件系统/挂载,volume-driver =本地,volume-opt =类型= ext3,volume-opt =设备=文件系统/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总计17drwxr-xr-x 3根根1024 Sep 19 14:39.drwxr-xr-x 1根根4096 Sep 19 14:40 ..drwx ------ 2根root 12288 Sep 19 14:39 lost + found 

唯一的先决条件是您在创建服务之前创建此文件并循环设备,并且无论计划了服务的哪个位置都可以访问此文件.我还建议使这些命令中的所有路径完全合格,而不要相对于当前目录.我很确定在某些地方相对路径不起作用.

I am Dockerising an old project. A feature in the project pulls in user-specified Git repos, and since the size of a repo could cause the filing system to be overwhelmed, I created a local filing system of a fixed size, and then mounted it. This was intended to prevent the web host from having its file system filled up.

The general approach is this:

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

This works fine in a Linux local or remote VM. However, I'd like to run this shell code, or something like it, inside a container. Part of the reason I'd like to do that is to contain all fiddly stuff inside a container, so that building a new host machine is as kept as simple as possible (in my view, setting up custom mounts and cron-restart rules on the host works against that).

So, this command does not work inside a container ("filesystem" is an on-host Docker volume)

mount -t ext3 filesystem/image.img filesystem/mount
mount: can't setup loop device: No space left on device

It also does not work on a container folder ("filesystem2" is a container directory):

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

I wonder whether containers just don't have the right internal machinery to do mounting, and thus whether I should change course. I'd prefer not to spend too much time on this (I'm just moving a project to a Docker-only server) which is why I would like to get mount working if I can.

Other options

If that's not possible, then a size-limited Docker volume, that works with both Docker and Swarm, may be an alternative I'd need to look into. There are conflicting reports on the web as to whether this actually works (see this question).

There is a suggestion here to say this is supported in Flocker. However, I am hesitant to use that, as it appears to be abandoned, presumably having been affected by ClusterHQ going bust.

This post indicates I can use --storage-opt size=120G with docker run. However, it does not look like it is supported by docker service create (unless perhaps the option has been renamed).

Update

As per the comment convo, I made some progress; I found that adding --privileged to the docker run enables mounting, at the cost of removing security isolation. A helpful commenter says that it is better to use the more fine-grained control of --cap-add SYS_ADMIN, allowing the container to retain some of its isolation.

However, Docker Swarm has not yet implemented either of these flags, so I can't use this solution. This lengthy feature request suggests to me that this feature is not going to be added in a hurry; it's been pending for two years already.

解决方案

You won't be able to safely do this inside of a container. Docker removes the mount privilege from containers because using this you could mount the host filesystem and escape the container. However, you can do this outside of the container and mount the filesystem into the container as a volume using the default local driver. The size option isn't supported by most filesystems, tmpfs being one of the few exceptions. Most of them use the size of the underlying device which you defined with the image file creation command:

dd if=/dev/zero of=filesystem/image.img bs=1M count=$SIZE

I had trouble getting docker to create the loop device dynamically, so here's the process to create it manually:

$ 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

When defining the volume mount options are passed almost verbatim from the mount command you run on the command line:

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 ...

or in a single service create command:

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 ...

With docker run, the command looks like:

$ 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

The only prerequisite is that you create this file and loop device before creating the service, and that this file is accessible wherever the service is scheduled. I would also suggest making all of the paths in these commands fully qualified rather than relative to the current directory. I'm pretty sure there are a few places that relative paths don't work.

这篇关于我可以使用"mount"吗?Docker Alpine容器中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆