Docker 插件 API

Docker插件是进程外的扩展,它们为Docker引擎增加了功能。

本文档描述了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 套接字。

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

Docker 总是首先在 /run/docker/plugins 中搜索 Unix 套接字。如果套接字不存在,它会在 /etc/docker/plugins/usr/lib/docker/plugins 下检查 spec 或 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 套接字激活

插件也可以通过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,与webhooks非常相似。

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

所有请求都是HTTP POST请求。

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

Handshake API

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

/Plugin.Activate

请求:空主体

响应:

{
    "Implements": ["VolumeDriver"]
}

响应此插件实现的Docker子系统列表。 激活后,插件将从此子系统接收事件。

可能的值为:

插件重试

尝试调用插件上的方法时,会使用指数退避重试,最多持续30秒。这在将插件打包为容器时可能会有所帮助,因为它为插件容器提供了启动的机会,然后再使依赖它们的任何用户容器失败。

插件助手

为了简化插件开发,我们为Docker目前支持的每种插件提供了一个sdk,可以在docker/go-plugins-helpers找到。