dockerd 不直接加载外部存储插件,而是通过监听 /run/docker/plugins/ 下符合权限(0660,root:docker)和命名规范的 Unix socket 及同级 .json 插件配置文件来发现插件;插件需预先启动、正确实现 RPC 接口并处理 Mountpoint 等字段。

dockerd 启动时如何加载外部存储插件
必须通过 --storage-driver 或 --graph 配合插件注册机制,但注意:Docker 20.10+ 默认禁用非内置驱动,外部存储插件(如 zfs、btrfs、自定义 overlay2 变体)实际依赖插件二进制 + Unix socket 注册,而非直接改 dockerd 参数。
-
dockerd本身不“加载”插件二进制,而是监听/run/docker/plugins/下的 socket 文件;插件需自行启动并监听该路径下的唯一 socket(如/run/docker/plugins/my-storage.sock) - 插件进程必须以 root 运行,且 socket 文件权限需为
0660,属主属组为root:docker,否则dockerd拒绝连接 - 启动顺序关键:先运行插件守护进程,再启动
dockerd;若dockerd先启,它只在初始化阶段扫描一次/run/docker/plugins/,后续新增 socket 不会自动发现
插件 manifest 文件怎么写才被 dockerd 识别
插件必须提供 plugin-spec 格式的 plugin-config.json,放在插件 socket 同级目录下,命名必须是 <plugin-name>.json</plugin-name>(如 my-storage.json),否则 docker plugin ls 看不到。
- manifest 中
Capability字段必须包含"volume"或"network",但存储类插件要生效,还得在Interface里明确声明"Types": ["docker.volume"] -
Entrypoint不是必须的,但若指定,必须是绝对路径;相对路径或未设Entrypoint时,dockerd会尝试执行插件 socket 所在目录的同名可执行文件(易出错) - 常见错误:
docker plugin install报failed to get plugin config: invalid character,基本是 JSON 缩进用了 tab、末尾多逗号、或字段名拼错(比如写成Capabilty)
为什么 docker volume create --driver=my-storage 失败
绝大多数失败不是配置问题,而是插件实现没响应 Get 或 Create RPC 请求,dockerd 默认 5 秒超时后静默放弃。
- 检查插件日志:用
journalctl -u my-storage-plugin或插件自身日志路径,重点看是否收到/VolumeDriver.Create请求及返回状态码(必须是 HTTP 200 + JSON body) - 插件返回的 JSON body 必须含
Err字段(即使为空字符串),缺这个字段会被dockerd当作协议错误丢弃 - 不要在
Create响应里返回绝对路径(如"/var/lib/my-storage/vol-abc");dockerd只认Mountpoint字段,且该路径需由插件确保已存在、可读写、且挂载上下文正确(例如 bind mount 的源路径必须真实存在)
CentOS 7 和 Ubuntu 22.04 上的兼容性差异
核心差异在 systemd socket 激活和 seccomp 默认策略,不是 Docker 版本问题。
- CentOS 7 默认
systemd版本低,不支持SocketUser/SocketGroup,插件 socket 权限必须靠ExecStartPost脚本手动chown root:docker,否则dockerd连不上 - Ubuntu 22.04 默认启用
seccomp,插件若调用mount(2)或setns(2)会被拦截;需在插件 service unit 里加SystemCallFilter=@default @file-system @namespace或禁用 seccomp(不推荐) - 两者都要求内核模块就绪:比如用
zfs插件,zfs.ko必须已加载,且zpool list能看到池;dockerd不检查这个,插件自己得报错
最常被跳过的一步:插件进程退出后 socket 文件残留,导致新实例启动时 bind 失败,报 address already in use —— 要么加 RuntimeDirectoryMode=0755,要么在 service 的 ExecStopPost 里 rm -f /run/docker/plugins/*.sock。










