如何控制对Docker中的卷进行的文件操作? [英] How to control file operations made to a volume in docker?

查看:129
本文介绍了如何控制对Docker中的卷进行的文件操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 打开


mkdir
...

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

解决方案

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_LIBRARY_PATH = / extralibs ...

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



如果您可以控制图像,则可以将其设置为仅使用此 LD_LIBRARY_PATH 执行。



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



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



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



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



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



选项3 :使用户空间文件系统在容器中本地可用。



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

这实际上意味着将文件系统实现为保险丝守护程序,将其安装在主机上(了解如何无法将其安装在包含er),并将其用作docker卷。



如果存在特定的限制,即不允许在主机上挂载文件系统,那么您有很多使选项1起作用的工作量。否则,我建议您使用保险丝实现文件系统并将其安装在主机上-它具有最高的ROI。


The situation is that I have a user space file system which can provide a bunch of posix like interface in user space. Like this:

open
read 
write 
mkdir
...

I want to make a volume on this file system and pass it to a docker. My question is how can I control the way docker access this volume so that it can be redirected to my posix like interface? Right now my file system can't be mounted on the host. It is a completely user space file system. I think fuse can support this, but I don't want to go there unless I have no choice.

解决方案

Docker does not implement any file or directory access. It's simply not what docker does, as a matter of design.

All docker does when launching a container is to create a bunch of mounts in such a way that the processes inside the container can issue their regular POSIX calls. When a process inside a container calls write(), the call goes directly to the Linux kernel, without docker's knowledge or intervention.

Now, there's a missing piece in your puzzle that has to be implemented one way or another: The application calls e.g. POSIX write() function, and your filesystem is not able to intercept this write() function.

So you have a couple of options:

Option 1: Implement your userspace filesystem in a library:

  1. The library would override the write() function.
  2. You compile the library and put it in some directory e.g. /build/artifacts/filesystem.so.
  3. You use that directory as a volume when running the container, e.g. docker run -v /build/artifacts/filesystem.so:/extralibs/filesystem.so ...
  4. you add this filesystem as a preloaded library: docker run ... --env LD_LIBRARY_PATH=/extralibs ...

This will make all calls in the container use your library, so it should forward all the irrelevant files (e.g. /bin/bash, /etc/passwd etc.) to the real filesystem.

If you have control over the images, then you can set it up such that only particular commands execute with this LD_LIBRARY_PATH.

Fair warning: implementing a library which overrides system calls and libc has a lot of pitfalls that you'll need to work around. One example is that if the program uses e.g. fprintf(), then you have to override fprintf() as well, even though fprintf() calls write().

Option 2: Modify the application to just call your filsystem functions.

This is assuming you can modify the application and the docker image.

If your filesystem is a service, run it in the container and issue the appropriate RPCs.

If it needs to be shared with other containers, then the backing store for your filesystem can be a volume.

Option 3: Make your userspace filesystem available natively within the container.

Meaning any command can issue a write() that goes to the kernel directly, and the kernel redirects it to your filesystem.

This essentially means implementing your filesystem as a fuse daemon, mounting it on the host (seeing how you can't mount it inside containers), and using it as a docker volume.

If there's a specific limitation that you're not allowed to mount your filesystem on the host, then you have a lot of work to do to make option 1 work. Otherwise I would advise you to implement your filesystem with fuse and mount it on the host - it has the highest ROI.

这篇关于如何控制对Docker中的卷进行的文件操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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