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`