【问题标题】:How to control file operations made to a volume in docker?如何控制对docker中的卷进行的文件操作?
【发布时间】:2019-11-25 06:33:37
【问题描述】:

情况是我有一个用户空间文件系统,它可以在用户空间提供一堆类似 posix 的界面。像这样:

open
read 
write 
mkdir
...

我想在这个文件系统上创建一个卷并将它传递给一个 docker。我的问题是如何控制 docker 访问此卷的方式,以便可以将其重定向到我的类似 posix 的界面? 现在我的文件系统无法安装在主机上。它是一个完全用户空间的文件系统。 我觉得fuse可以支持这个,但是除非别无选择,否则我不想去那里。

【问题讨论】:

    标签: docker filesystems storage driver volume


    【解决方案1】:

    这里不需要卷。如果您可以从在 docker 中运行的应用程序访问您的 POSIX 接口。您访问它并执行读、写等操作。
    如果您确实需要卷实现,则需要将其存储到另一个卷中,并让看门狗应用程序将更改同步到您的用户文件系统

    【讨论】:

    • 感谢您的回答,也许我不清楚,docker 中的应用程序只能在给定路径上运行,更改 docker 中的所有应用程序可能不可行且不经济。我选择 docker 的原因是支持尽可能多的应用程序,我想如果我可以控制 docker 操作音量并重定向到我的界面的方式,它可能会更容易。
    • 是的。我明白你的意思。但是总有可以构建的解决方案。我的想法是实现一个对所有应用程序容器都通用的容器。这个容器是一个双向实现,它接受来自您所有应用程序的卷请求,并将它们转换为您的 POSIX 调用并获得返回并返回给您的应用程序容器。
    • 谢谢你,另一个容器...... en ,我想我可以忍受,但我的问题仍然存在,我不知道如何控制 docker 访问卷的方式清楚,我不知道如何控制 docker 访问该 docker 中或该 docker 外部的卷的方式(即主机端)
    • docker 如何处理带有容器的卷。当然,一本书应该可以帮助你。您需要阅读 Volumes、Bindmounts 和 tmpfs 挂载。 Docker In Action 必须提供帮助。提示一下,当你映射一个卷时,docker 将这些文件存储在它的卷存储中,当你使用绑定挂载时,你可以将你的任何目录作为卷数据绑定到你的容器。
    • 我尝试了音量驱动,但最后我相信音量驱动只能控制 docker 处理卷本身的方式,而不是 docker 处理其中的文件或目录,你是否暗示我可以做到这一点通过更改 docker 本身并重新编译它?
    【解决方案2】:

    Docker 不实现任何文件或目录访问。作为设计问题,这根本不是 docker 所做的。

    docker 在启动容器时所做的就是创建一堆挂载,以便容器内的进程可以发出它们的常规 POSIX 调用。当容器内的进程调用write()时,该调用直接进入Linux内核,无需docker知晓或干预。

    现在,您的难题中缺少一个必须以一种或另一种方式实现的部分:应用程序调用例如POSIX write() 函数,而您的文件系统无法拦截此 write() 函数。

    所以你有几个选择:

    选项 1:在库中实现您的用户空间文件系统:

    1. 该库将覆盖write() 函数。
    2. 您编译库并将其放在某个目录中,例如/build/artifacts/filesystem.so
    3. 您在运行容器时将该目录用作卷,例如docker run -v /build/artifacts/filesystem.so:/extralibs/filesystem.so ...
    4. 您将此文件系统添加为预加载库:docker run ... --env LD_PRELOAD=/extralibs/filesystem.so ...

    这将使容器中的所有调用使用您的库,因此它应该将所有不相关的文件(例如/bin/bash/etc/passwd 等)转发到真实的文件系统。

    如果您可以控制图像,则可以将其设置为仅使用此 LD_PRELOAD 执行特定命令。

    公平警告:实现一个覆盖系统调用和 libc 的库有很多需要解决的陷阱。一个例子是,如果程序使用例如fprintf(),那么即使fprintf() 调用write(),你也必须覆盖fprintf()

    选项 2:修改应用程序以仅调用您的 filsystem 函数。

    这是假设您可以修改应用程序和 docker 映像。

    如果您的文件系统是服务,请在容器中运行它并发出适当的 RPC。

    如果它需要与其他容器共享,那么文件系统的后备存储可以是一个卷。

    选项 3:让您的用户空间文件系统在容器内本地可用。

    意味着任何命令都可以发出write() 直接进入内核,内核将其重定向到您的文件系统。

    这实质上意味着将您的文件系统实现为 fuse 守护程序,将其挂载到主机上(看看您如何无法将其挂载到容器中),并将其用作 docker 卷。

    如果存在不允许在主机上挂载文件系统的特定限制,那么您需要做很多工作才能使选项 1 起作用。否则,我会建议您使用 fuse 实现文件系统并将其安装在主机上 - 它具有最高的投资回报率。

    【讨论】:

    • 确切地说,如果可执行文件与 C 库静态链接,它将无法工作。
    猜你喜欢
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 2022-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多