代码之家  ›  专栏  ›  技术社区  ›  halfer Jay Gong

我可以在Docker Alpine集装箱内使用“mount”吗?

  •  0
  • halfer Jay Gong  · 技术社区  · 6 年前

    一般做法如下:

    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
    

    里面 一个容器。我想这样做的部分原因是在一个容器中包含所有精巧的东西,以便构建一个新的主机尽可能简单(在我看来,在主机上设置自定义挂载和cron重启规则是不可行的)。

    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卷,与Docker和Swarm一起工作,可能是我需要研究的另一个选择。关于这是否真的有效,网上有相互矛盾的报道( see this question ).

    有一个 suggestion here 要说这一点,弗洛克是支持的。然而,我很犹豫是否使用它,因为它似乎 be abandoned ,大概是受到了ClusterHQ破产的影响。

    This post 表示我可以使用 --storage-opt size=120G docker run . 但是,它看起来不像是由 docker service create (除非该选项可能已重命名)。

    更新

    根据conva的评论,我取得了一些进展;我发现 --privileged 以移除安全隔离为代价实现装载。一位有用的评论者说,最好使用更细粒度的 --cap-add SYS_ADMIN

    然而,DockerSwarm还没有实现这两个标志,所以我不能使用这个解决方案。 This lengthy feature request

    2 回复  |  直到 6 年前
        1
  •  1
  •   BMitch    6 年前

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

    $ 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
    

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

    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
    

        2
  •  1
  •   halfer Jay Gong    6 年前

    我找到了一个我很满意的大小限制解决方案,它不使用Linux mount

    在提出这个问题之前,我没有尝试过安装Docker卷,因为我的部分研究偶然发现了一张堆栈溢出海报,这让我怀疑Docker卷是否可以遵守大小限制。我的测试表明他们可以,但您可能希望在自己的平台上进行测试,以确保它适合您。

    下面的命令是从网上各种来源拼凑而成的。

    docker volume create \
        --driver local \
        --opt o=size=20m \
        --opt type=tmpfs \
        --opt device=tmpfs \
        hello-volume
    

    docker service create \
        --mount source=hello-volume,target=/myvol \
        alpine \
        sleep 10000
    

    我们可以通过在该服务中的单个容器上获取一个外壳来确保容器已安装:

    docker exec -it amazing_feynman.1.lpsgoyv0jrju6fvb8skrybqap
    / # ls - /myvol
    total 0
    

    好的,太好了。所以,在这个shell中,让我们尝试以5m的增量慢慢地覆盖这个磁盘。我们可以看到它在第五次尝试中失败了,这是我们所期望的:

    / # cd /myvol
    /myvol # ls
    /myvol # dd if=/dev/zero of=image1 bs=1M count=5
    5+0 records in
    5+0 records out
    /myvol # dd if=/dev/zero of=image2 bs=1M count=5
    5+0 records in
    5+0 records out
    /myvol # ls -l
    total 10240
    -rw-r--r--    1 root     root       5242880 Sep 16 13:11 image1
    -rw-r--r--    1 root     root       5242880 Sep 16 13:12 image2
    /myvol # dd if=/dev/zero of=image3 bs=1M count=5
    5+0 records in
    5+0 records out
    /myvol # dd if=/dev/zero of=image4 bs=1M count=5
    5+0 records in
    5+0 records out
    /myvol # ls -l
    total 20480
    -rw-r--r--    1 root     root       5242880 Sep 16 13:11 image1
    -rw-r--r--    1 root     root       5242880 Sep 16 13:12 image2
    -rw-r--r--    1 root     root       5242880 Sep 16 13:12 image3
    -rw-r--r--    1 root     root       5242880 Sep 16 13:12 image4
    /myvol # dd if=/dev/zero of=image5 bs=1M count=5
    dd: writing 'image5': No space left on device
    1+0 records in
    0+0 records out
    /myvol # 
    

    最后,让我们看看,如果限制只适用于完整磁盘中新打开的文件句柄,是否可以通过一次性覆盖磁盘来获得错误:

    / # cd /myvol
    / # rm *
    /myvol # dd if=/dev/zero of=image1 bs=1M count=21
    dd: writing 'image1': No space left on device
    21+0 records in
    20+0 records out
    

    事实证明我们可以,所以我觉得这很有说服力。

    本尼岛

    卷是用 type device “tmpfs”,听起来像是一个RAM盘。我已经成功地检查了在系统重新启动后,卷是否保持连接和完整,所以至少在目前看来,它看起来不错。

    然而,我要说的是,在组织数据持久性系统时,不要照搬我所拥有的。在将其投入生产之前,请确保该卷足够健壮,适合您的用例,当然,还要确保将其包含在备份过程中。