FUSE 是什么?一篇文章搞懂 FUSE 的作用以及如何配合 Docker 使用
一、FUSE 是什么?
FUSE 的英文全称是 Filesystem in Userspace,中文叫用户态文件系统。
这个名字听起来比较复杂,但其实理解起来很简单。
FUSE 的核心作用,就是让一些原本不能直接当成本地磁盘使用的存储资源,可以像普通文件夹一样访问。
举个例子:
假设你有两台服务器:
- 服务器 A:运行 Docker 容器,负责处理文件。
- 服务器 B:存放大量文件,比如图片、视频和文档。
现在,你希望服务器 A 上的程序可以直接访问服务器 B 的文件。
通常,程序可能需要通过 SSH、SFTP 或其他接口去读取远程文件。
但是使用 FUSE 相关工具后,就可以把服务器 B 的目录挂载到服务器 A 的一个本地目录中。
例如:
服务器 B(真实存储)
/home/demo/shared/
├── test.txt
├── image.jpg
└── video.mp4
|
| SSHFS(基于 FUSE)
↓
服务器 A(挂载后的目录)
/mnt/remote-files/
├── test.txt
├── image.jpg
└── video.mp4
虽然这些文件实际上保存在服务器 B,但服务器 A 上的程序可以像读取本地文件一样读取它们。
例如:
cat /mnt/remote-files/test.txt
这样就不用在业务代码中专门编写 SFTP 下载逻辑了。
注意:FUSE 本身并不负责存储文件,而是提供一种文件系统实现机制。真正实现远程文件访问的是 SSHFS 等基于 FUSE 的工具。
二、FUSE 和 Docker 有什么关系?
先理解一个概念:Docker 本身就支持目录挂载。
例如:
docker run -v /data:/app/data nginx
这条命令的含义是:
把宿主机上的 /data 目录挂载到 Docker 容器内部的 /app/data 目录。
这样 Docker 容器就可以读取宿主机上的文件。
那既然 Docker 已经支持目录挂载,为什么还需要 FUSE 呢?
因为两者解决的问题不一样。
- Docker:负责运行容器,并把宿主机目录映射到容器。
- FUSE:可以配合其他工具,将远程存储等资源变成宿主机能够访问的文件目录。
我们来看一个场景。
假设文件存储在另一台服务器上:
远程服务器
192.168.1.20
|
| SSHFS + FUSE
↓
Docker 宿主机
/mnt/remote-files
|
| Docker -v 目录挂载
↓
Docker 容器
/app/data
整个过程可以理解为两个步骤:
第一步:FUSE 负责让宿主机访问远程文件。
第二步:Docker 负责将宿主机上的文件目录提供给容器使用。
这样,Docker 容器就能像访问本地文件一样访问远程服务器上的文件了。
这里有一个非常重要的知识点:
FUSE 和 Docker 并不是必须一起使用。 如果文件本来就在宿主机上,直接使用 Docker 的 -v 挂载即可,没有必要增加 FUSE。
三、实际操作:通过 FUSE 让 Docker 访问远程文件
下面通过一个简单例子进行演示。
假设我们有两台 Linux 服务器。
| 服务器 | IP 地址 | 用途 |
|---|---|---|
| A | 192.168.1.10 | Docker 宿主机 |
| B | 192.168.1.20 | 存储文件 |
我们的目标是:
让服务器 A 上的 Docker 容器,直接读取服务器 B 上的文件。
本示例使用 Ubuntu Linux,服务器 A 已安装 Docker,服务器 B 已开启 SSH/SFTP 服务。
第一步:安装 SSHFS
首先连接到服务器 A。
安装 SSHFS:
sudo apt update
sudo apt install sshfs -y
这里需要解释两个概念:
- FUSE:提供文件系统机制。
- SSHFS:基于 FUSE 实现的远程文件系统,可以通过 SSH/SFTP 访问远程服务器上的文件。
简单理解:
FUSE 提供基础能力,SSHFS 负责具体实现远程文件挂载。
第二步:创建挂载目录
在服务器 A 上创建目录:
sudo mkdir -p /mnt/remote-files
这个目录就是我们准备放远程文件的位置。
注意:这里并不需要把远程文件下载过来。
第三步:挂载远程服务器目录
假设服务器 B 上有以下目录:
/home/demo/shared/
├── test.txt
└── image.jpg
并且存在具有目录读取权限的 SSH 用户 demo。
在服务器 A 上执行:
sudo sshfs demo@192.168.1.20:/home/demo/shared /mnt/remote-files -o ro
参数解释:
| 参数 | 说明 |
|---|---|
| demo | 远程服务器 SSH 用户名 |
| 192.168.1.20 | 远程服务器 IP |
| /home/demo/shared | 远程文件目录 |
| /mnt/remote-files | 本地挂载目录 |
| -o ro | 只读挂载,避免误修改文件 |
首次连接时,SSH 可能要求确认服务器身份,并输入远程用户密码或使用配置好的 SSH 密钥。
挂载成功后,执行:
ls /mnt/remote-files
假设结果为:
test.txt
image.jpg
说明服务器 A 已经可以读取服务器 B 上的文件。
到这一步,FUSE 的工作就完成了。
第四步:让 Docker 容器访问文件
现在我们在服务器 A 上运行一个 Docker 容器。
执行:
docker run --rm -it \
-v /mnt/remote-files:/app/data:ro \
alpine sh
这里使用的是一个很小的 Alpine Linux 镜像。
参数解释:
--rm:容器退出后自动删除容器。-it:进入容器交互终端。-v:把宿主机目录挂载到容器内部。:ro:只读挂载。alpine:运行的 Docker 镜像。sh:进入容器命令行。
进入容器后执行:
ls /app/data
假设输出:
test.txt
image.jpg
再执行:
cat /app/data/test.txt
这样,Docker 容器就可以直接读取远程服务器上的文件内容了。
最后执行:
exit
退出容器。
整个过程没有把远程文件复制进 Docker 镜像,也没有要求业务程序主动调用 SFTP 接口。
Docker 容器只需要按照普通文件的方式进行读取即可。
第五步:取消挂载
当 Docker 容器退出后,如果不再需要远程目录,可以在服务器 A 上执行:
sudo umount /mnt/remote-files
这样就取消了远程目录的挂载。
注意:取消挂载不会删除远程服务器上的原始文件。
四、FUSE 和 Docker Volume 有什么区别?
这是比较容易混淆的地方。
| 对比项 | FUSE | Docker Volume | Docker Bind Mount |
|---|---|---|---|
| 主要作用 | 实现文件系统访问 | 管理容器数据存储 | 将宿主机路径映射到容器 |
| 是否属于 Docker | 否 | 是 | 是 |
| 是否支持远程存储 | 可以通过 SSHFS 等工具实现 | 取决于驱动 | 可以挂载宿主机已接入的远程文件系统 |
| 典型应用 | 远程文件、对象存储访问 | 数据持久化 | 共享宿主机文件 |
例如:
场景一:普通 Docker 文件挂载
docker run -v /data:/app/data nginx
宿主机本来就有 /data 目录,直接挂载即可。
不需要 FUSE。
场景二:Docker 访问远程文件
远程文件
↓
SSHFS / FUSE
↓
宿主机挂载目录
↓
Docker Bind Mount
↓
容器内部目录
这种情况下,FUSE 就发挥作用了。
另外,Docker Volume 还可以通过第三方存储驱动使用远程存储,并不是所有远程存储场景都必须使用 FUSE。
五、FUSE 还能用来做什么?
除了 SSHFS,FUSE 还可以配合其他工具使用。
1. 访问对象存储
例如:
- MinIO
- Amazon S3
- 其他兼容 S3 协议的对象存储
可以通过支持 FUSE 的工具(例如 s3fs、rclone mount),把对象存储挂载成文件目录。
假设原来业务程序需要调用 MinIO 的 API 才能访问文件。
通过挂载之后,程序可能直接访问:
/app/data/test.pdf
就像访问本地文件一样。
不过,对象存储和本地磁盘的行为并不完全一致,性能、文件修改和一致性等方面可能存在区别。
2. AI 智能体沙箱
比如,一个 AI Agent 需要执行 Python 代码,读取用户上传的文件。
可以采用这样的结构:
文件存储服务
|
| FUSE 挂载
↓
宿主机文件目录
|
| Docker 挂
浙公网安备 33010602011771号