首页
/ 如何用 rclone serve docker 把任意云存储以 Docker 卷插件方式提供给容器挂载?

如何用 rclone serve docker 把任意云存储以 Docker 卷插件方式提供给容器挂载?

2026-09-08 19:10:55作者:苗圣禹Peter

rclone 可以通过 rclone serve docker 命令实现 Docker 的卷插件(volume plugin)API,让 docker daemon 直接把它背后的任意云存储(SFTP、Google Drive、S3 等)当作一个具名卷来创建和挂载,容器内看到的就像普通目录。这条功能自 rclone v1.56 引入,主要文档在 docs/content/docker.mddocs/content/commands/rclone_serve_docker.md

插件必须与 docker daemon 运行在同一台主机上(Swarm 集群则是每个节点都要装),因为负责把远端文件系统挂载进容器的就是它。

前提条件

按文档要求,主机上需要准备:

  • Docker Engine >= 19.03.15(托管插件模式的要求);
  • FUSE 驱动,rclone 挂载所必需(Ubuntu 示例命令):
sudo apt-get -y install fuse3
  • 插件的两个固定目录。插件不会自动创建它们,必须在安装前准备好:
    • /var/lib/docker-plugins/rclone/config:存放 rclone.conf即使为空也必須存在
    • /var/lib/docker-plugins/rclone/cache:存放插件状态文件和可选的 VFS 缓存。
sudo mkdir -p /var/lib/docker-plugins/rclone/config
sudo mkdir -p /var/lib/docker-plugins/rclone/cache
  • 托管模式只能装在 Linux;MacOS 和 Windows 不支持原生 Docker 插件,文档明确要求在这些系统上改用托管模式(managed plugin)。

安装插件:托管模式(推荐主路径)

托管插件就是一个由 docker daemon 拉起的特殊容器,内部运行 rclone serve docker,config 和 cache 目录在启动时 bind mount 进去,docker daemon 通过容器内创建的 unix socket 与它通信。插件镜像在 Docker Hub 上发布,镜像名是 rclone/docker-volume-rclone

安装命令(amd64 换成你的架构):

docker plugin install rclone/docker-volume-rclone:amd64 --grant-all-permissions --alias rclone
docker plugin list

当前可用的架构 tag 只有三个:amd64arm64arm-v7。要指定版本时用 ARCHITECTURE-VERSION 形式的 tag,例如 arm64 上的 v1.56.2 写作 rclone/docker-volume-rclone:arm64-1.56.2(注意去掉了 v)。latest tag 目前是 amd64 的别名;非 Intel 架构不能省略架构名,必须写全 tag,否则插件起不来。

安装时可以一次性带上插件参数:

docker plugin install rclone/docker-volume-rclone:amd64 \
       --alias rclone --grant-all-permissions \
       args="-v --allow-other" config=/etc/rclone

安装后如果插件处于未启用状态,可以用 docker plugin set 调整这几项设置:argsconfigcacheHTTP_PROXYHTTPS_PROXYNO_PROXYRCLONE_VERBOSE。示例:

docker plugin disable rclone
docker plugin set rclone RCLONE_VERBOSE=2 config=/etc/rclone args="--vfs-cache-mode=writes --allow-other"
docker plugin enable rclone
docker plugin inspect rclone

几个文档明确指出的细节:

  • argsrclone serve docker 的命令行参数,支持 serve docker flags、通用 rclone flags,也包括后端参数(作为建卷时的默认值)。docker 存在一个 bug:args 为空值时插件会失败,所以至少要给 args="-v" 这样的非空值。
  • config=/host/dir 指向 rclone.conf 所在目录。文件本身不存在不报错,但目录必须存在。插件会周期性改写该文件(例如续期存储访问 token),要避免主机上其他 rclone 实例同时改动它导致文件损坏。SFTP 私钥等文件也可以放这里,但注意它在插件容器内的固定路径是 /data/config,比如主机上的 sftp-box1.key 对应的卷选项要写成 -o sftp-key-file=/data/config/sftp-box1.key
  • cache=/host/dir 指向缓存目录,VFS 缓存和 docker-plugin.state 状态文件都在里面。
  • Swarm 集群里要自行保证各节点插件设置一致,文档没有提供自动同步手段。

如果 docker 拒绝 disable 插件,说明有活动卷、容器或 swarm service 还在使用它,需要先把它们找出来停掉。

安装插件:Linux 上以 systemd 服务运行(可选方案)

文档提示:大多数情况应优先用托管模式,且只有 Linux 可以走这条路。做法是把 rclone 本身安装到主机后(先直接跑一次 rclone serve docker 可以做测试),用仓库中 contrib/docker-plugin/systemd/docker-volume-rclone.servicecontrib/docker-plugin/systemd/docker-volume-rclone.socket 这两个 systemd 配置(文档正文中给出的下载文件名写的是 docker-volume-plugin.service/.socket,以仓库实际文件名 docker-volume-rclone.* 为准),放入 /etc/systemd/system/

service 文件实际内容很简短,核心是 ExecStart=/usr/bin/rclone serve docker,并通过 ExecStartPre 自动创建三个目录(/var/lib/docker-volumes/rclone、config 和 cache 目录),环境变量固定为 RCLONE_CONFIG=/var/lib/docker-plugins/rclone/config/rclone.confRCLONE_CACHE_DIR=/var/lib/docker-plugins/rclone/cacheRCLONE_VERBOSE=1;socket 文件监听 /run/docker/plugins/rclone.sock

该节所有命令都要以 root 执行。创建目录:

mkdir -p /var/lib/docker-volumes/rclone
mkdir -p /var/lib/docker-plugins/rclone/config
mkdir -p /var/lib/docker-plugins/rclone/cache

文档给了两种启动方式。socket 激活方式:

systemctl daemon-reload
systemctl start docker-volume-rclone.service
systemctl enable docker-volume-rclone.socket
systemctl start docker-volume-rclone.socket
systemctl restart docker

或直接启动 service:systemctl daemon-reloadsystemctl enable docker-volume-rclone.service(开机自启)、systemctl start docker-volume-rclone.servicesystemctl restart docker。最后一步是让 docker daemon 检测到新的插件 socket——托管模式下不需要这一步,因为 docker 自己知道插件状态变化。另外注意:如果之后改变监听 socket,必须重启 docker daemon 才会重新连接,重启前所有卷相关的 docker 命令都会超时等待旧 socket。

rclone serve docker 直接以命令行方式运行只支持 Linux,不支持 Windows 和 MacOS。默认监听 unix socket /run/docker/plugins/rclone.sock;若用 --socket-addr 指定 TCP 地址,rclone 会额外创建一个 /etc/docker/plugins/rclone.spec 小文件记录 socket 地址(文档中的测试示例):

sudo rclone serve docker --base-dir /tmp/rclone-volumes --socket-addr localhost:8787 -vv

创建卷:remote、type/path 与挂载参数

卷通过 docker volume create 创建,-d rclone 指定 rclone 驱动(即使插件是按全名 rclone/docker-volume-rclone 安装的,只要安装时给了 --alias rclone,就可以用短名):

docker volume create vol1 -d rclone -o remote=storj: -o vfs-cache-mode=full
docker volume create vol2 -d rclone -o remote=:storj,access_grant=xxx:heimdall
docker volume create vol3 -d rclone -o type=storj -o path=heimdall -o storj-access-grant=xxx -o poll-interval=0

文档给出了三种指定后端的方式:

  • remote(可别名 fs,避免与 crypt、alias 这类后端自己的 remote 参数混淆):指向配置文件里已存在的 remote 名,带尾随冒号,可再带远端路径,如 -o remote=storj:
  • remote=:backend:dir/subdir 即时(无配置)语法,或等价的 -o type=backend -o path=dir/subdirpath 部分可省略。拆成两个选项在脚本里更方便参数化。
  • 后端参数直接作为 -o 选项传入。规则是:去掉命令行的 -- 前缀,短横线可以换成下划线。例如 --vfs-cache-mode full 写作 -o vfs-cache-mode=full-o vfs_cache_mode=full;无值布尔 flag 要补 true,例如 --allow-other 写作 -o allow-other=true

一个限制要注意:参数只能给被 remote 直接引用的那个后端。如果它自身是 alias、chunker、crypt 这类包装后端,无法通过卷选项给它内部引用的远端传参——rclone 连接串解析器的限制。绕法是给插件喂 rclone.conf,或者用插件参数(args)设默认值。

如果所有选项都是静态的,甚至可以完全不跑 rclone config、不建 rclone.conf(但 config 目录仍须存在)。文档的 SFTP 示例:

docker volume create firstvolume -d rclone -o type=sftp -o sftp-host=_hostname_ -o sftp-user=_username_ -o sftp-pass=_password_ -o allow-other=true

其中 _hostname__username__password_ 是文档里的占位符,替换为你自己的主机名和 SSH 凭据(最简单可用 localhost);也可以加 -o path=/home/username 把远端路径改为主机家目录。

OAuth 类后端的 token 配置

像 Google Drive 这类需要 access token 的后端,token 可以通过浏览器设置并由 rclone 定期续期,但托管插件没有浏览器。文档的解法是在另一台带浏览器和图形界面的机器上运行 rclone config 建好 Google Drive remote,然后把生成的 rclone.conf 传到集群每台节点,保存为 /var/lib/docker-plugins/rclone/config/rclone.conf(该位置默认只有 root 可写)。文档中的配置示例:

[gdrive]
type = drive
scope = drive
drive_id = 1234567...
root_folder_id = 0Abcd...
token = {"access_token":...}

验证挂载结果

单机场景,创建一个测试容器把卷挂进去(ubuntu:latest 是文档示例镜像,--workdir /mnt 让 shell 直接落在挂载点):

docker run --rm -it -v firstvolume:/mnt --workdir /mnt ubuntu:latest bash

如果一切正常,你会进入新容器并且工作目录就是挂载的远端;容器内输入 ls 能看到远端目录内容,exit 退出后容器停止,但卷保留、可复用。

用 CLI 检查卷本身:

docker volume list
docker volume inspect vol1

Swarm 场景,文档用 example.yml(compose v3 格式)描述一个 heimdall 服务,卷声明如下:

version: '3'
services:
  heimdall:
    image: linuxserver/heimdall:latest
    ports: [8080:80]
    volumes: [configdata:/config]
volumes:
  configdata:
    driver: rclone
    driver_opts:
      remote: 'gdrive:heimdall'
      allow_other: 'true'
      vfs_cache_mode: full
      poll_interval: 0

然后 docker stack deploy example -c ./example.yml 部署。几秒后 docker 会把栈分发到集群、在节点上创建 example_heimdall 服务(端口 8080),并向节点上的 rclone 插件请求 example_configdata 卷。验证命令:

docker service ls
docker service ps example_heimdall
docker volume ls

YAML 写法上有几个文档特别强调的坑:

  • 布尔值必须加引号写成 'true'"false",这两个词被 YAML 保留;
  • remote 值以冒号结尾时必须加引号,如 remote: "storage_box:"
  • 含双引号和花括号的 JSON token 必须用单引号整体包住;
  • YAML 里选项名习惯用 _ 而不是 -

另外注意:栈删除时(docker stack remove example)集群节点上按需创建的卷不会自动删除,需要逐节点手动 docker volume remove example_configdata

用 healthcheck 验证挂载可用性

docker 卷插件协议没有让插件向 daemon 上报卷可用/不可用的通道。文档给出的替代做法是在消费容器上配 healthcheck 探测挂载点是否响应(/path/to/rclone/mount 替换为实际挂载路径):

services:
  my_service:
    image: my_image
    healthcheck:
      test: ls /path/to/rclone/mount || exit 1
      interval: 1m
      timeout: 15s
      retries: 3
      start_period: 15s

重启与升级插件

插件重启(例如 docker plugin disable rclone && docker plugin enable rclone、升级插件、主机重启)时,rclone 会读取 docker-plugin.state 文件,在后台恢复之前的卷和挂载;socket 本身会立刻开始提供服务,慢或不可达的远端不会卡住插件启动。

但有一个必须知道的后果:重启插件必然停掉并重建 FUSE 挂载进程。已经在运行、且在 rclone 卷上持有打开文件句柄的容器,会一直对着旧的死挂载,报 transport endpoint is not continuous(文档原文措辞为 transport endpoint is not connected),直到容器重启。文档的建议:

  • 重启或升级插件后,把正在使用 rclone 卷的容器都重启一遍(如 docker restart <container>),或者提前停掉、事后启动;
  • 持续打开文件的应用受影响最大,文档点名了 Grafana、Prometheus、SQLite 类应用,应始终重启。

修改卷选项的坑

Docker CLI 没有 docker volume update。对已存在的卷重跑 docker volume create 并给新选项不会生效,也不报错,这是文档明确指出的 docker 陷阱。正确做法是先删再建:

docker volume remove my_vol
docker volume create my_vol -d rclone -o opt1=new_val1 ...

然后用 docker volume listdocker volume inspect my_vol 确认设置已更新。如果 docker 拒绝删除该卷,先找出使用它的容器或 swarm service 并停掉。

排查与安全边界

排查

文档给出的诊断顺序:

  • 查看托管插件设置与状态:docker plugin listdocker plugin inspect rclone(注意 docker 包括 20.10.7 在内只显示 args 的默认值,不显示实际值)。
  • 插件输出进入 docker daemon 日志:journalctl --unit docker。docker 会把插件行显示为 errors,实际级别要看封装在消息串里的内容。
  • 打印插件内真实版本:
PLUGID=$(docker plugin list --no-trunc | awk '/rclone/{print$1}')
sudo runc --root /run/docker/runtime-runc/plugins.moby exec $PLUGID rclone version

甚至可以用 runc 进入插件容器的 shell:sudo runc --root /run/docker/runtime-runc/plugins.moby exec --tty $PLUGID bash

  • 用 curl 检查插件 socket 连通性(PLUGID 取自 docker plugin list --no-trunc 输出,需替换):
sudo curl -H Content-Type:application/json -XPOST -d {} --unix-socket /run/docker/plugins/$PLUGID/rclone.sock http://localhost/Plugin.Activate
  • 最后手段:清除插件状态。文档特别警告——现有的 rclone docker 卷大概率都要重建,因为重装不清理状态文件正是为了便于恢复:
docker plugin disable rclone # disable the plugin to ensure no interference
sudo rm /var/lib/docker-plugins/rclone/cache/docker-plugin.state # removing the plugin state
docker plugin enable rclone # re-enable the plugin afterward

安全边界

  • 插件 API 接受 remote(即 fs)选项,解析方式与 rclone 连接串完全一致。连接串是受信任配置:可以带内联后端选项,而某些后端会用这些选项执行本地命令(文档举例 sftp 后端的 ssh 选项会拉起外部二进制)。任何能向插件 socket 发请求的人,都能以运行 rclone serve docker 的用户身份(通常是 root)执行任意命令。socket 访问要按这个级别对待,只暴露给可信调用方。
  • 默认 unix socket /run/docker/plugins/rclone.sock0660 创建,属主 root,属组为 --socket-gid 指定的组(默认取进程 GID),只有 root 和该组成员(通常就是 docker daemon)能访问。不要放宽权限,也不要把这个组给不受信用户。
  • --socket-addr 监听 TCP socket 时没有认证,任何能打开该端口的人都可访问 API,文档要求绑定到 loopback 或其他可信地址并用防火墙保护。持有 docker daemon 访问权本身已等价于主机 root,这里的顾虑是把 socket 暴露得比 daemon 本身更广。

挂载方法选项

mount-type(别名 mount_type)决定挂载方式,一般取 mountcmountmount2 之一。注意:托管插件目前不支持 cmountmount2 很少需要。该选项默认取第一个找到的方式,通常是 mount,一般不用显式指定。persist 是一个保留的布尔选项,文档说明其用途是将来允许把即时远端持久化到插件的 rclone.conf 中。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391