github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/docs/extend/index.md (about) 1 --- 2 description: Develop and use a plugin with the managed plugin system 3 keywords: "API, Usage, plugins, documentation, developer" 4 title: Managed plugin system 5 --- 6 7 <!-- This file is maintained within the docker/docker Github 8 repository at https://github.com/docker/docker/. Make all 9 pull requests against that repo. If you see this file in 10 another repository, consider it read-only there, as it will 11 periodically be overwritten by the definitive file. Pull 12 requests which include edits to this file in other repositories 13 will be rejected. 14 --> 15 16 # Docker Engine managed plugin system 17 18 * [Installing and using a plugin](index.md#installing-and-using-a-plugin) 19 * [Developing a plugin](index.md#developing-a-plugin) 20 * [Debugging plugins](index.md#debugging-plugins) 21 22 Docker Engine's plugins system allows you to install, start, stop, and remove 23 plugins using Docker Engine. 24 25 For information about the legacy plugin system available in Docker Engine 1.12 26 and earlier, see [Understand legacy Docker Engine plugins](legacy_plugins.md). 27 28 > **Note**: Docker Engine managed plugins are currently not supported 29 on Windows daemons. 30 31 ## Installing and using a plugin 32 33 Plugins are distributed as Docker images and can be hosted on Docker Hub or on 34 a private registry. 35 36 To install a plugin, use the `docker plugin install` command, which pulls the 37 plugin from Docker hub or your private registry, prompts you to grant 38 permissions or capabilities if necessary, and enables the plugin. 39 40 To check the status of installed plugins, use the `docker plugin ls` command. 41 Plugins that start successfully are listed as enabled in the output. 42 43 After a plugin is installed, you can use it as an option for another Docker 44 operation, such as creating a volume. 45 46 In the following example, you install the `sshfs` plugin, verify that it is 47 enabled, and use it to create a volume. 48 49 > **Note**: 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. 50 51 1. Install the `sshfs` plugin. 52 53 ```bash 54 $ docker plugin install vieux/sshfs 55 56 Plugin "vieux/sshfs" is requesting the following privileges: 57 - network: [host] 58 - capabilities: [CAP_SYS_ADMIN] 59 Do you grant the above permissions? [y/N] y 60 61 vieux/sshfs 62 ``` 63 64 The plugin requests 2 privileges: 65 - It needs access to the `host` network. 66 - It needs the `CAP_SYS_ADMIN` capability, which allows the plugin to run 67 the `mount` command. 68 69 2. Check that the plugin is enabled in the output of `docker plugin ls`. 70 71 ```bash 72 $ docker plugin ls 73 74 ID NAME TAG DESCRIPTION ENABLED 75 69553ca1d789 vieux/sshfs latest the `sshfs` plugin true 76 ``` 77 78 3. Create a volume using the plugin. 79 This example mounts the `/remote` directory on host `1.2.3.4` into a 80 volume named `sshvolume`. 81 82 This volume can now be mounted into containers. 83 84 ```bash 85 $ docker volume create \ 86 -d vieux/sshfs \ 87 --name sshvolume \ 88 -o sshcmd=user@1.2.3.4:/remote \ 89 -o password=$(cat file_containing_password_for_remote_host) 90 91 sshvolume 92 ``` 93 4. Verify that the volume was created successfully. 94 95 ```bash 96 $ docker volume ls 97 98 DRIVER NAME 99 vieux/sshfs sshvolume 100 ``` 101 102 5. Start a container that uses the volume `sshvolume`. 103 104 ```bash 105 $ docker run --rm -v sshvolume:/data busybox ls /data 106 107 <content of /remote on machine 1.2.3.4> 108 ``` 109 110 6. Remove the volume `sshvolume` 111 ```bash 112 docker volume rm sshvolume 113 114 sshvolume 115 ``` 116 To disable a plugin, use the `docker plugin disable` command. To completely 117 remove it, use the `docker plugin remove` command. For other available 118 commands and options, see the 119 [command line reference](../reference/commandline/index.md). 120 121 ## Service creation using plugins 122 123 In swarm mode, it is possible to create a service that allows for attaching 124 to networks or mounting volumes. Swarm schedules services based on plugin availability 125 on a node. In this example, a volume plugin is installed on a swarm worker and a volume 126 is created using the plugin. In the manager, a service is created with the relevant 127 mount options. It can be observed that the service is scheduled to run on the worker 128 node with the said volume plugin and volume. 129 130 In the following example, node1 is the manager and node2 is the worker. 131 132 1. Prepare manager. In node 1: 133 134 ```bash 135 $ docker swarm init 136 Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager. 137 ``` 138 139 2. Join swarm, install plugin and create volume on worker. In node 2: 140 141 ```bash 142 $ docker swarm join \ 143 --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 144 192.168.99.100:2377 145 ``` 146 147 ```bash 148 $ docker plugin install tiborvass/sample-volume-plugin 149 latest: Pulling from tiborvass/sample-volume-plugin 150 eb9c16fbdc53: Download complete 151 Digest: sha256:00b42de88f3a3e0342e7b35fa62394b0a9ceb54d37f4c50be5d3167899994639 152 Status: Downloaded newer image for tiborvass/sample-volume-plugin:latest 153 Installed plugin tiborvass/sample-volume-plugin 154 ``` 155 156 ```bash 157 $ docker volume create -d tiborvass/sample-volume-plugin --name pluginVol 158 ``` 159 160 3. Create a service using the plugin and volume. In node1: 161 162 ```bash 163 $ docker service create --name my-service --mount type=volume,volume-driver=tiborvass/sample-volume-plugin,source=pluginVol,destination=/tmp busybox top 164 165 $ docker service ls 166 z1sj8bb8jnfn my-service replicated 1/1 busybox:latest 167 ``` 168 docker service ls shows service 1 instance of service running. 169 170 4. Observe the task getting scheduled in node 2: 171 172 ```bash 173 {% raw %} 174 $ docker ps --format '{{.ID}}\t {{.Status}} {{.Names}} {{.Command}}' 175 83fc1e842599 Up 2 days my-service.1.9jn59qzn7nbc3m0zt1hij12xs "top" 176 {% endraw %} 177 ``` 178 179 ## Developing a plugin 180 181 #### The rootfs directory 182 The `rootfs` directory represents the root filesystem of the plugin. In this 183 example, it was created from a Dockerfile: 184 185 >**Note:** The `/run/docker/plugins` directory is mandatory inside of the 186 plugin's filesystem for docker to communicate with the plugin. 187 188 ```bash 189 $ git clone https://github.com/vieux/docker-volume-sshfs 190 $ cd docker-volume-sshfs 191 $ docker build -t rootfsimage . 192 $ id=$(docker create rootfsimage true) # id was cd851ce43a403 when the image was created 193 $ sudo mkdir -p myplugin/rootfs 194 $ sudo docker export "$id" | sudo tar -x -C myplugin/rootfs 195 $ docker rm -vf "$id" 196 $ docker rmi rootfsimage 197 ``` 198 199 #### The config.json file 200 201 The `config.json` file describes the plugin. See the [plugins config reference](config.md). 202 203 Consider the following `config.json` file. 204 205 ```json 206 { 207 "description": "sshFS plugin for Docker", 208 "documentation": "https://docs.docker.com/engine/extend/plugins/", 209 "entrypoint": ["/go/bin/docker-volume-sshfs"], 210 "network": { 211 "type": "host" 212 }, 213 "interface" : { 214 "types": ["docker.volumedriver/1.0"], 215 "socket": "sshfs.sock" 216 }, 217 "linux": { 218 "capabilities": ["CAP_SYS_ADMIN"] 219 } 220 } 221 ``` 222 223 This plugin is a volume driver. It requires a `host` network and the 224 `CAP_SYS_ADMIN` capability. It depends upon the `/go/bin/docker-volume-sshfs` 225 entrypoint and uses the `/run/docker/plugins/sshfs.sock` socket to communicate 226 with Docker Engine. This plugin has no runtime parameters. 227 228 #### Creating the plugin 229 230 A new plugin can be created by running 231 `docker plugin create <plugin-name> ./path/to/plugin/data` where the plugin 232 data contains a plugin configuration file `config.json` and a root filesystem 233 in subdirectory `rootfs`. 234 235 After that the plugin `<plugin-name>` will show up in `docker plugin ls`. 236 Plugins can be pushed to remote registries with 237 `docker plugin push <plugin-name>`. 238 239 240 ## Debugging plugins 241 242 Stdout of a plugin is redirected to dockerd logs. Such entries have a 243 `plugin=<ID>` suffix. Here are a few examples of commands for pluginID 244 `f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62` and their 245 corresponding log entries in the docker daemon logs. 246 247 ```bash 248 $ docker plugin install tiborvass/sample-volume-plugins 249 250 INFO[0036] Starting... Found 0 volumes on startup plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 251 ``` 252 253 ```bash 254 $ docker volume create -d tiborvass/sample-volume-plugins samplevol 255 256 INFO[0193] Create Called... Ensuring directory /data/samplevol exists on host... plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 257 INFO[0193] open /var/lib/docker/plugin-data/local-persist.json: no such file or directory plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 258 INFO[0193] Created volume samplevol with mountpoint /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 259 INFO[0193] Path Called... Returned path /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 260 ``` 261 262 ```bash 263 $ docker run -v samplevol:/tmp busybox sh 264 265 INFO[0421] Get Called... Found samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 266 INFO[0421] Mount Called... Mounted samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 267 INFO[0421] Path Called... Returned path /data/samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 268 INFO[0421] Unmount Called... Unmounted samplevol plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 269 ``` 270 271 #### Using docker-runc to obtain logfiles and shell into the plugin. 272 273 `docker-runc`, the default docker container runtime can be used for debugging 274 plugins. This is specifically useful to collect plugin logs if they are 275 redirected to a file. 276 277 ```bash 278 $ docker-runc list 279 ID PID STATUS BUNDLE CREATED 280 f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 2679 running /run/docker/libcontainerd/f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 2017-02-06T21:53:03.031537592Z 281 r 282 ``` 283 284 ```bash 285 $ docker-runc exec f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 cat /var/log/plugin.log 286 ``` 287 288 If the plugin has a built-in shell, then exec into the plugin can be done as 289 follows: 290 ```bash 291 $ docker-runc exec -t f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 sh 292 ``` 293 294 #### Using curl to debug plugin socket issues. 295 296 To verify if the plugin API socket that the docker daemon communicates with 297 is responsive, use curl. In this example, we will make API calls from the 298 docker host to volume and network plugins using curl 7.47.0 to ensure that 299 the plugin is listening on the said socket. For a well functioning plugin, 300 these basic requests should work. Note that plugin sockets are available on the host under `/var/run/docker/plugins/<pluginID>` 301 302 303 ```bash 304 curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/e8a37ba56fc879c991f7d7921901723c64df6b42b87e6a0b055771ecf8477a6d/plugin.sock http:/VolumeDriver.List 305 306 {"Mountpoint":"","Err":"","Volumes":[{"Name":"myvol1","Mountpoint":"/data/myvol1"},{"Name":"myvol2","Mountpoint":"/data/myvol2"}],"Volume":null} 307 ``` 308 309 ```bash 310 curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/45e00a7ce6185d6e365904c8bcf62eb724b1fe307e0d4e7ecc9f6c1eb7bcdb70/plugin.sock http:/NetworkDriver.GetCapabilities 311 312 {"Scope":"local"} 313 ``` 314 When using curl 7.5 and above, the URL should be of the form 315 `http://hostname/APICall`, where `hostname` is the valid hostname where the 316 plugin is installed and `APICall` is the call to the plugin API. 317 318 For example, `http://localhost/VolumeDriver.List`