Docker 插件 API

Docker 插件是进程外的扩展,可以为 Docker Engine 添加功能。

本文档描述了 Docker Engine 插件 API。要查看 Docker Engine 管理的插件信息,请参考 Docker Engine 插件系统

此页面面向想要开发自己的 Docker 插件的人员。如果您只想了解或使用 Docker 插件,请查看 此处

什么是插件

插件是在与 Docker 守护程序相同或不同的主机上运行的进程,它通过将文件放置在 插件发现 中描述的守护程序主机上的一个插件目录中来注册自身。

插件具有易于理解的名称,这些名称是简短的小写字符串。例如,flockerweave

插件可以在容器内或容器外运行。目前建议在容器外运行它们。

插件发现

每当用户或容器尝试按名称使用插件时,Docker 都会通过查找插件目录中的插件来发现插件。

插件目录中可以放置三种类型的文件。

  • .sock 文件是 Unix 域套接字。
  • .spec 文件是包含 URL 的文本文件,例如 unix:///other.socktcp://localhost:8080
  • .json 文件是包含插件完整 json 规范的文本文件。

具有 Unix 域套接字文件的插件必须与 Docker 守护程序运行在同一主机上。如果您指定远程 URL,则具有 .spec.json 文件的插件可以在不同的主机上运行。

Unix 域套接字文件必须位于 /run/docker/plugins 下,而规范文件可以位于 /etc/docker/plugins/usr/lib/docker/plugins 下。

文件名(不包括扩展名)决定了插件名称。

例如,flocker 插件可能会在 /run/docker/plugins/flocker.sock 创建一个 Unix 套接字。

如果您想将定义彼此隔离,可以将每个插件定义到一个单独的子目录中。例如,您可以将 flocker 套接字创建在 /run/docker/plugins/flocker/flocker.sock 下,并且只将 /run/docker/plugins/flocker 挂载到 flocker 容器内。

Docker 始终首先在 /run/docker/plugins 中搜索 Unix 套接字。如果套接字不存在,它会在 /etc/docker/plugins/usr/lib/docker/plugins 下检查规范或 json 文件。一旦找到具有给定名称的第一个插件定义,目录扫描就会停止。

JSON 规范

这是插件的 JSON 格式

{
  "Name": "plugin-example",
  "Addr": "https://example.com/docker/plugin",
  "TLSConfig": {
    "InsecureSkipVerify": false,
    "CAFile": "/usr/shared/docker/certs/example-ca.pem",
    "CertFile": "/usr/shared/docker/certs/example-cert.pem",
    "KeyFile": "/usr/shared/docker/certs/example-key.pem"
  }
}

TLSConfig 字段是可选的,只有在存在此配置时才会验证 TLS。

插件生命周期

插件应该在 Docker 之前启动,并在 Docker 之后停止。例如,当为支持 systemd 的平台打包插件时,您可以使用 systemd 依赖项 来管理启动和关闭顺序。

升级插件时,应首先停止 Docker 守护程序,升级插件,然后重新启动 Docker。

插件激活

当第一次引用插件时——无论是用户按名称引用它(例如 docker run --volume-driver=foo),还是已经配置为使用正在启动的插件的容器——Docker 都会在插件目录中查找指定名称的插件,并使用握手对其进行激活。请参见下面的握手 API。

插件不会在 Docker 守护程序启动时自动激活。相反,它们仅在需要时才按需或延迟激活。

Systemd socket 激活

插件也可以通过 systemd 进行套接字激活。官方的 插件助手 本身支持套接字激活。为了使插件能够被套接字激活,它需要一个 service 文件和一个 socket 文件。

service 文件(例如 /lib/systemd/system/your-plugin.service

[Unit]
Description=Your plugin
Before=docker.service
After=network.target your-plugin.socket
Requires=your-plugin.socket docker.service

[Service]
ExecStart=/usr/lib/docker/your-plugin

[Install]
WantedBy=multi-user.target

socket 文件(例如 /lib/systemd/system/your-plugin.socket

[Unit]
Description=Your plugin

[Socket]
ListenStream=/run/docker/plugins/your-plugin.sock

[Install]
WantedBy=sockets.target

这将允许在 Docker 守护程序连接到它们正在侦听的套接字时(例如,守护程序第一次使用它们时或其中一个插件意外关闭时)实际启动插件。

API 设计

插件 API 基于 HTTP 协议,采用 RPC 风格的 JSON 格式,类似于 Webhook。

请求从 Docker 守护进程流向插件。插件需要实现一个 HTTP 服务器,并将其绑定到“插件发现”部分提到的 Unix 套接字。

所有请求都是 HTTP POST 请求。

API 通过 Accept 头部进行版本控制,目前始终设置为 application/vnd.docker.plugins.v1+json

握手 API

插件通过以下“握手”API 调用来激活。

/Plugin.Activate

请求:空主体

响应

{
    "Implements": ["VolumeDriver"]
}

响应包含此插件实现的 Docker 子系统列表。激活后,插件将收到来自此子系统的事件。

可能的值是

插件重试

尝试调用插件上的方法时,会采用指数退避策略重试,最多重试 30 秒。当将插件打包为容器时,这很有帮助,因为它使插件容器有机会启动,然后再使任何依赖它的用户容器失败。

插件助手

为了简化插件开发,我们为 Docker 当前支持的每种插件类型提供了一个 sdk,位于 docker/go-plugins-helpers