Docker Engine 管理的插件系统

Docker Engine 的插件系统允许您使用 Docker Engine 安装、启动、停止和移除插件。

有关旧版(非托管)插件的信息,请参阅 了解旧版 Docker Engine 插件

注意

Windows 守护进程目前不支持由 Docker Engine 管理的插件。

安装和使用插件

插件以 Docker 镜像的形式分发,可以托管在 Docker Hub 上或私有注册表中。

To install a plugin, use the docker plugin install command, which pulls the plugin from Docker Hub or your private registry, prompts you to grant permissions or capabilities if necessary, and enables the plugin.

要检查已安装插件的状态,请使用 docker plugin ls 命令。 成功启动的插件将在输出中列为“已启用”。

安装插件后,您可以将其用作其他 Docker 操作的选项,例如创建卷。

在下面的示例中,您安装 sshfs 插件,验证其是否已启用,然后使用它来创建卷。

注意

本示例仅用于教学目的。一旦创建卷,在检查该卷时,您访问远程主机的 SSH 密码将以明文形式暴露。请在完成示例后立即删除该卷。

  1. 安装 sshfs 插件。

    $ docker plugin install vieux/sshfs
    
    Plugin "vieux/sshfs" is requesting the following privileges:
    - network: [host]
    - capabilities: [CAP_SYS_ADMIN]
    Do you grant the above permissions? [y/N] y
    
    vieux/sshfs
    

    该插件申请了以下两项权限:

    • 它需要访问 host 网络。
    • 它需要 CAP_SYS_ADMIN 能力,这允许插件运行 mount 命令。
  2. 检查插件是否在 docker plugin ls 的输出中已启用。

    $ docker plugin ls
    
    ID                    NAME                  TAG                 DESCRIPTION                   ENABLED
    69553ca1d789          vieux/sshfs           latest              the `sshfs` plugin            true
    
  3. 使用插件创建卷。 此示例将主机 1.2.3.4 上的 /remote 目录挂载到一个名为 sshvolume 的卷中。

    此卷现在可以挂载到容器中。

    $ docker volume create \
      -d vieux/sshfs \
      --name sshvolume \
      -o sshcmd=user@1.2.3.4:/remote \
      -o password=$(cat file_containing_password_for_remote_host)
    
    sshvolume
    
  4. 验证卷是否已成功创建。

    $ docker volume ls
    
    DRIVER              NAME
    vieux/sshfs         sshvolume
    
  5. 启动一个使用卷 sshvolume 的容器。

    $ docker run --rm -v sshvolume:/data busybox ls /data
    
    <content of /remote on machine 1.2.3.4>
    
  6. 删除卷 sshvolume

    $ docker volume rm sshvolume
    
    sshvolume
    

要禁用插件,请使用 docker plugin disable 命令。要完全 移除它,请使用 docker plugin remove 命令。有关其他可用 命令和选项,请参阅

开发插件

The rootfs 目录

rootfs 目录代表插件的根文件系统。在本例中,它是由 Dockerfile 创建的:

注意

The /run/docker/plugins directory is mandatory inside of the plugin's filesystem for Docker to communicate with the plugin.

$ git clone https://github.com/vieux/docker-volume-sshfs
$ cd docker-volume-sshfs
$ docker build -t rootfsimage .
$ id=$(docker create rootfsimage true) # id was cd851ce43a403 when the image was created
$ sudo mkdir -p myplugin/rootfs
$ sudo docker export "$id" | sudo tar -x -C myplugin/rootfs
$ docker rm -vf "$id"
$ docker rmi rootfsimage

config.json 文件

config.json 文件描述了插件。请参阅 插件配置参考

考虑以下 config.json 文件。

{
  "description": "sshFS plugin for Docker",
  "documentation": "https://docs.docker.com/engine/extend/plugins/",
  "entrypoint": ["/docker-volume-sshfs"],
  "network": {
    "type": "host"
  },
  "interface": {
    "types": ["docker.volumedriver/1.0"],
    "socket": "sshfs.sock"
  },
  "linux": {
    "capabilities": ["CAP_SYS_ADMIN"]
  }
}

该插件是一个卷驱动程序。它需要 host 网络和 CAP_SYS_ADMIN 权限。它依赖于 /docker-volume-sshfs 入口点,并使用 /run/docker/plugins/sshfs.sock 套接字与 Docker Engine 进行通信。此插件没有运行时参数。

创建插件

可以通过运行 docker plugin create <plugin-name> ./path/to/plugin/data 来创建一个新的插件,其中插件数据包含一个插件配置文件 config.json 和一个位于子目录 rootfs 中的根文件系统。

之后,插件 <plugin-name> 将显示在 docker plugin ls 中。 可以使用 docker plugin push <plugin-name> 将插件推送到远程注册表。

调试插件

插件的标准输出(Stdout)会被重定向到 dockerd 日志中。此类条目带有 plugin=<ID>后缀。以下是针对插件ID f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62的几条命令示例,以及它们在 Docker 守护进程日志中对应的日志条目。

$ docker plugin install tiborvass/sample-volume-plugin

INFO[0036] Starting...       Found 0 volumes on startup  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
$ docker volume create -d tiborvass/sample-volume-plugin samplevol

INFO[0193] Create Called...  Ensuring directory /data/samplevol exists on host...  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193] open /var/lib/docker/plugin-data/local-persist.json: no such file or directory  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193]                   Created volume samplevol with mountpoint /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193] Path Called...    Returned path /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
$ docker run -v samplevol:/tmp busybox sh

INFO[0421] Get Called...     Found samplevol                plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Mount Called...   Mounted samplevol              plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Path Called...    Returned path /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Unmount Called... Unmounted samplevol            plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62

使用 runc 获取日志文件并进入插件的 shell。

使用 runc(默认的 Docker 容器运行时)来调试插件,方法是收集重定向到文件的插件日志。

$ sudo runc --root /run/docker/runtime-runc/plugins.moby list

ID                                                                 PID         STATUS      BUNDLE                                                                                                                                       CREATED                          OWNER
93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25   15806       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25   2018-02-08T21:40:08.621358213Z   root
9b4606d84e06b56df84fadf054a21374b247941c94ce405b0a261499d689d9c9   14992       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/9b4606d84e06b56df84fadf054a21374b247941c94ce405b0a261499d689d9c9   2018-02-08T21:35:12.321325872Z   root
c5bb4b90941efcaccca999439ed06d6a6affdde7081bb34dc84126b57b3e793d   14984       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/c5bb4b90941efcaccca999439ed06d6a6affdde7081bb34dc84126b57b3e793d   2018-02-08T21:35:12.321288966Z   root
$ sudo runc --root /run/docker/runtime-runc/plugins.moby exec 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 cat /var/log/plugin.log

如果插件内置了 shell,则可以通过以下方式执行到插件中:

$ sudo runc --root /run/docker/runtime-runc/plugins.moby exec -t 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 sh

使用 curl 调试插件套接字问题。

要验证 Docker 守护进程通信的插件 API socket 是否响应,可以使用 curl。在本示例中,我们将使用 curl 7.47.0 从 Docker 主机向存储卷和网络插件发送 API 请求,以确保该插件正在指定的 socket 上监听。对于功能正常的插件,这些基本请求应该能够成功执行。请注意,插件 socket 在主机上位于 /var/run/docker/plugins/<pluginID> 下可用。

$ curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/e8a37ba56fc879c991f7d7921901723c64df6b42b87e6a0b055771ecf8477a6d/plugin.sock http:/VolumeDriver.List

{"Mountpoint":"","Err":"","Volumes":[{"Name":"myvol1","Mountpoint":"/data/myvol1"},{"Name":"myvol2","Mountpoint":"/data/myvol2"}],"Volume":null}
$ curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/45e00a7ce6185d6e365904c8bcf62eb724b1fe307e0d4e7ecc9f6c1eb7bcdb70/plugin.sock http:/NetworkDriver.GetCapabilities

{"Scope":"local"}

当使用 curl 7.5 及以上版本时,URL 应采用以下格式 http://hostname/APICall,其中 hostname 是安装插件的有效主机名,而 APICall 是对插件 API 的调用。

例如,http://localhost/VolumeDriver.List