summaryrefslogtreecommitdiff
path: root/devdocs/docker/engine%2Fextend%2Findex.html
blob: 52b27035ff244a7769645c49087bebe6a66743fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
 <h1 id="docker-engine-managed-plugin-system">Docker Engine managed plugin system</h1> <ul> <li><a href="index#installing-and-using-a-plugin">Installing and using a plugin</a></li> <li><a href="index#developing-a-plugin">Developing a plugin</a></li> <li><a href="index#debugging-plugins">Debugging plugins</a></li> </ul> <p>Docker Engine’s plugin system allows you to install, start, stop, and remove plugins using Docker Engine.</p> <p>For information about legacy (non-managed) plugins, refer to <a href="legacy_plugins/index">Understand legacy Docker Engine plugins</a>.</p> <blockquote> <p><strong>Note</strong></p> <p>Docker Engine managed plugins are currently not supported on Windows daemons.</p> </blockquote> <h2 id="installing-and-using-a-plugin">Installing and using a plugin</h2> <p>Plugins are distributed as Docker images and can be hosted on Docker Hub or on a private registry.</p> <p>To install a plugin, use the <code class="language-plaintext highlighter-rouge">docker plugin install</code> 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.</p> <p>To check the status of installed plugins, use the <code class="language-plaintext highlighter-rouge">docker plugin ls</code> command. Plugins that start successfully are listed as enabled in the output.</p> <p>After a plugin is installed, you can use it as an option for another Docker operation, such as creating a volume.</p> <p>In the following example, you install the <code class="language-plaintext highlighter-rouge">sshfs</code> plugin, verify that it is enabled, and use it to create a volume.</p> <blockquote> <p><strong>Note</strong></p> <p>This example is intended for instructional purposes only. Once the volume is created, your SSH password to the remote host will be exposed as plaintext when inspecting the volume. You should delete the volume as soon as you are done with the example.</p> </blockquote> <ol> <li> <p>Install the <code class="language-plaintext highlighter-rouge">sshfs</code> plugin.</p> <div class="highlight"><pre class="highlight" data-language="">$ 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
</pre></div>  <p>The plugin requests 2 privileges:</p> <ul> <li>It needs access to the <code class="language-plaintext highlighter-rouge">host</code> network.</li> <li>It needs the <code class="language-plaintext highlighter-rouge">CAP_SYS_ADMIN</code> capability, which allows the plugin to run the <code class="language-plaintext highlighter-rouge">mount</code> command.</li> </ul> </li> <li> <p>Check that the plugin is enabled in the output of <code class="language-plaintext highlighter-rouge">docker plugin ls</code>.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker plugin ls

ID                    NAME                  TAG                 DESCRIPTION                   ENABLED
69553ca1d789          vieux/sshfs           latest              the `sshfs` plugin            true
</pre></div>  </li> <li> <p>Create a volume using the plugin. This example mounts the <code class="language-plaintext highlighter-rouge">/remote</code> directory on host <code class="language-plaintext highlighter-rouge">1.2.3.4</code> into a volume named <code class="language-plaintext highlighter-rouge">sshvolume</code>.</p> <p>This volume can now be mounted into containers.</p> <div class="highlight"><pre class="highlight" data-language="">$ 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
</pre></div>  </li> <li> <p>Verify that the volume was created successfully.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker volume ls

DRIVER              NAME
vieux/sshfs         sshvolume
</pre></div>  </li> <li> <p>Start a container that uses the volume <code class="language-plaintext highlighter-rouge">sshvolume</code>.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker run --rm -v sshvolume:/data busybox ls /data

&lt;content of /remote on machine 1.2.3.4&gt;
</pre></div>  </li> <li> <p>Remove the volume <code class="language-plaintext highlighter-rouge">sshvolume</code></p> <div class="highlight"><pre class="highlight" data-language="">$ docker volume rm sshvolume

sshvolume
</pre></div>  </li> </ol> <p>To disable a plugin, use the <code class="language-plaintext highlighter-rouge">docker plugin disable</code> command. To completely remove it, use the <code class="language-plaintext highlighter-rouge">docker plugin remove</code> command. For other available commands and options, see the <a href="../reference/commandline/cli/index">command line reference</a>.</p> <h2 id="developing-a-plugin">Developing a plugin</h2> <h4 id="the-rootfs-directory">The rootfs directory</h4> <p>The <code class="language-plaintext highlighter-rouge">rootfs</code> directory represents the root filesystem of the plugin. In this example, it was created from a Dockerfile:</p> <blockquote> <p><strong>Note:</strong> The <code class="language-plaintext highlighter-rouge">/run/docker/plugins</code> directory is mandatory inside of the plugin’s filesystem for docker to communicate with the plugin.</p> </blockquote> <div class="highlight"><pre class="highlight" data-language="">$ 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
</pre></div> <h4 id="the-configjson-file">The config.json file</h4> <p>The <code class="language-plaintext highlighter-rouge">config.json</code> file describes the plugin. See the <a href="config/index">plugins config reference</a>.</p> <p>Consider the following <code class="language-plaintext highlighter-rouge">config.json</code> file.</p> <div class="highlight"><pre class="highlight" data-language="">{
	"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"]
	}
}
</pre></div> <p>This plugin is a volume driver. It requires a <code class="language-plaintext highlighter-rouge">host</code> network and the <code class="language-plaintext highlighter-rouge">CAP_SYS_ADMIN</code> capability. It depends upon the <code class="language-plaintext highlighter-rouge">/docker-volume-sshfs</code> entrypoint and uses the <code class="language-plaintext highlighter-rouge">/run/docker/plugins/sshfs.sock</code> socket to communicate with Docker Engine. This plugin has no runtime parameters.</p> <h4 id="creating-the-plugin">Creating the plugin</h4> <p>A new plugin can be created by running <code class="language-plaintext highlighter-rouge">docker plugin create &lt;plugin-name&gt; ./path/to/plugin/data</code> where the plugin data contains a plugin configuration file <code class="language-plaintext highlighter-rouge">config.json</code> and a root filesystem in subdirectory <code class="language-plaintext highlighter-rouge">rootfs</code>.</p> <p>After that the plugin <code class="language-plaintext highlighter-rouge">&lt;plugin-name&gt;</code> will show up in <code class="language-plaintext highlighter-rouge">docker plugin ls</code>. Plugins can be pushed to remote registries with <code class="language-plaintext highlighter-rouge">docker plugin push &lt;plugin-name&gt;</code>.</p> <h2 id="debugging-plugins">Debugging plugins</h2> <p>Stdout of a plugin is redirected to dockerd logs. Such entries have a <code class="language-plaintext highlighter-rouge">plugin=&lt;ID&gt;</code> suffix. Here are a few examples of commands for pluginID <code class="language-plaintext highlighter-rouge">f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62</code> and their corresponding log entries in the docker daemon logs.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker plugin install tiborvass/sample-volume-plugin

INFO[0036] Starting...       Found 0 volumes on startup  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
</pre></div> <div class="highlight"><pre class="highlight" data-language="">$ 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
</pre></div> <div class="highlight"><pre class="highlight" data-language="">$ 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
</pre></div> <h4 id="using-docker-runc-to-obtain-logfiles-and-shell-into-the-plugin">Using docker-runc to obtain logfiles and shell into the plugin.</h4> <p><code class="language-plaintext highlighter-rouge">docker-runc</code>, the default docker container runtime can be used for debugging plugins. This is specifically useful to collect plugin logs if they are redirected to a file.</p> <div class="highlight"><pre class="highlight" data-language="">$ sudo docker-runc --root /var/run/docker/plugins/runtime-root/moby-plugins 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
</pre></div> <div class="highlight"><pre class="highlight" data-language="">$ sudo docker-runc --root /var/run/docker/plugins/runtime-root/moby-plugins exec 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 cat /var/log/plugin.log
</pre></div> <p>If the plugin has a built-in shell, then exec into the plugin can be done as follows:</p> <div class="highlight"><pre class="highlight" data-language="">$ sudo docker-runc --root /var/run/docker/plugins/runtime-root/moby-plugins exec -t 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 sh
</pre></div> <h4 id="using-curl-to-debug-plugin-socket-issues">Using curl to debug plugin socket issues.</h4> <p>To verify if the plugin API socket that the docker daemon communicates with is responsive, use curl. In this example, we will make API calls from the docker host to volume and network plugins using curl 7.47.0 to ensure that the plugin is listening on the said socket. For a well functioning plugin, these basic requests should work. Note that plugin sockets are available on the host under <code class="language-plaintext highlighter-rouge">/var/run/docker/plugins/&lt;pluginID&gt;</code></p> <div class="highlight"><pre class="highlight" data-language="">$ 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}
</pre></div> <div class="highlight"><pre class="highlight" data-language="">$ curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/45e00a7ce6185d6e365904c8bcf62eb724b1fe307e0d4e7ecc9f6c1eb7bcdb70/plugin.sock http:/NetworkDriver.GetCapabilities

{"Scope":"local"}
</pre></div> <p>When using curl 7.5 and above, the URL should be of the form <code class="language-plaintext highlighter-rouge">http://hostname/APICall</code>, where <code class="language-plaintext highlighter-rouge">hostname</code> is the valid hostname where the plugin is installed and <code class="language-plaintext highlighter-rouge">APICall</code> is the call to the plugin API.</p> <p>For example, <code class="language-plaintext highlighter-rouge">http://localhost/VolumeDriver.List</code></p> 
<p><a href="https://docs.docker.com/search/?q=API">API</a>, <a href="https://docs.docker.com/search/?q=Usage">Usage</a>, <a href="https://docs.docker.com/search/?q=plugins">plugins</a>, <a href="https://docs.docker.com/search/?q=documentation">documentation</a>, <a href="https://docs.docker.com/search/?q=developer">developer</a></p>
<div class="_attribution">
  <p class="_attribution-p">
    &copy; 2019 Docker, Inc.<br>Licensed under the Apache License, Version 2.0.<br>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.<br>Docker, Inc. and other parties may also have trademark rights in other terms used herein.<br>
    <a href="https://docs.docker.com/engine/extend/" class="_attribution-link">https://docs.docker.com/engine/extend/</a>
  </p>
</div>