github.com/panekj/cli@v0.0.0-20230304125325-467dd2f3797e/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  ---
     5  
     6  <!-- This file is maintained within the docker/cli GitHub
     7       repository at https://github.com/docker/cli/. Make all
     8       pull requests against that repo. If you see this file in
     9       another repository, consider it read-only there, as it will
    10       periodically be overwritten by the definitive file. Pull
    11       requests which include edits to this file in other repositories
    12       will be rejected.
    13  -->
    14  
    15  # Docker Engine managed plugin system
    16  
    17  - [Installing and using a plugin](index.md#installing-and-using-a-plugin)
    18  - [Developing a plugin](index.md#developing-a-plugin)
    19  - [Debugging plugins](index.md#debugging-plugins)
    20  
    21  Docker Engine's plugin system allows you to install, start, stop, and remove
    22  plugins using Docker Engine.
    23  
    24  For information about legacy (non-managed) plugins, refer to
    25  [Understand legacy Docker Engine plugins](legacy_plugins.md).
    26  
    27  > **Note**
    28  >
    29  > Docker Engine managed plugins are currently not supported 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**
    50  >
    51  > This example is intended for instructional purposes only. Once the volume is
    52  > created, your SSH password to the remote host will be exposed as plaintext
    53  > when inspecting the volume. You should delete the volume as soon as you are
    54  > done with the example.
    55  
    56  1.  Install the `sshfs` plugin.
    57  
    58      ```console
    59      $ docker plugin install vieux/sshfs
    60  
    61      Plugin "vieux/sshfs" is requesting the following privileges:
    62      - network: [host]
    63      - capabilities: [CAP_SYS_ADMIN]
    64      Do you grant the above permissions? [y/N] y
    65  
    66      vieux/sshfs
    67      ```
    68  
    69      The plugin requests 2 privileges:
    70  
    71      - It needs access to the `host` network.
    72      - It needs the `CAP_SYS_ADMIN` capability, which allows the plugin to run
    73        the `mount` command.
    74  
    75  2.  Check that the plugin is enabled in the output of `docker plugin ls`.
    76  
    77      ```console
    78      $ docker plugin ls
    79  
    80      ID                    NAME                  TAG                 DESCRIPTION                   ENABLED
    81      69553ca1d789          vieux/sshfs           latest              the `sshfs` plugin            true
    82      ```
    83  
    84  3.  Create a volume using the plugin.
    85      This example mounts the `/remote` directory on host `1.2.3.4` into a
    86      volume named `sshvolume`.
    87  
    88      This volume can now be mounted into containers.
    89  
    90      ```console
    91      $ docker volume create \
    92        -d vieux/sshfs \
    93        --name sshvolume \
    94        -o sshcmd=user@1.2.3.4:/remote \
    95        -o password=$(cat file_containing_password_for_remote_host)
    96  
    97      sshvolume
    98      ```
    99  
   100  4.  Verify that the volume was created successfully.
   101  
   102      ```console
   103      $ docker volume ls
   104  
   105      DRIVER              NAME
   106      vieux/sshfs         sshvolume
   107      ```
   108  
   109  5.  Start a container that uses the volume `sshvolume`.
   110  
   111      ```console
   112      $ docker run --rm -v sshvolume:/data busybox ls /data
   113  
   114      <content of /remote on machine 1.2.3.4>
   115      ```
   116  
   117  6.  Remove the volume `sshvolume`
   118  
   119      ```console
   120      $ docker volume rm sshvolume
   121  
   122      sshvolume
   123      ```
   124  
   125  To disable a plugin, use the `docker plugin disable` command. To completely
   126  remove it, use the `docker plugin remove` command. For other available
   127  commands and options, see the
   128  [command line reference](https://docs.docker.com/engine/reference/commandline/cli/).
   129  
   130  ## Developing a plugin
   131  
   132  #### The rootfs directory
   133  
   134  The `rootfs` directory represents the root filesystem of the plugin. In this
   135  example, it was created from a Dockerfile:
   136  
   137  > **Note:** The `/run/docker/plugins` directory is mandatory inside of the
   138  > plugin's filesystem for docker to communicate with the plugin.
   139  
   140  ```console
   141  $ git clone https://github.com/vieux/docker-volume-sshfs
   142  $ cd docker-volume-sshfs
   143  $ docker build -t rootfsimage .
   144  $ id=$(docker create rootfsimage true) # id was cd851ce43a403 when the image was created
   145  $ sudo mkdir -p myplugin/rootfs
   146  $ sudo docker export "$id" | sudo tar -x -C myplugin/rootfs
   147  $ docker rm -vf "$id"
   148  $ docker rmi rootfsimage
   149  ```
   150  
   151  #### The config.json file
   152  
   153  The `config.json` file describes the plugin. See the [plugins config reference](config.md).
   154  
   155  Consider the following `config.json` file.
   156  
   157  ```json
   158  {
   159    "description": "sshFS plugin for Docker",
   160    "documentation": "https://docs.docker.com/engine/extend/plugins/",
   161    "entrypoint": ["/docker-volume-sshfs"],
   162    "network": {
   163      "type": "host"
   164    },
   165    "interface": {
   166      "types": ["docker.volumedriver/1.0"],
   167      "socket": "sshfs.sock"
   168    },
   169    "linux": {
   170      "capabilities": ["CAP_SYS_ADMIN"]
   171    }
   172  }
   173  ```
   174  
   175  This plugin is a volume driver. It requires a `host` network and the
   176  `CAP_SYS_ADMIN` capability. It depends upon the `/docker-volume-sshfs`
   177  entrypoint and uses the `/run/docker/plugins/sshfs.sock` socket to communicate
   178  with Docker Engine. This plugin has no runtime parameters.
   179  
   180  #### Creating the plugin
   181  
   182  A new plugin can be created by running
   183  `docker plugin create <plugin-name> ./path/to/plugin/data` where the plugin
   184  data contains a plugin configuration file `config.json` and a root filesystem
   185  in subdirectory `rootfs`.
   186  
   187  After that the plugin `<plugin-name>` will show up in `docker plugin ls`.
   188  Plugins can be pushed to remote registries with
   189  `docker plugin push <plugin-name>`.
   190  
   191  ## Debugging plugins
   192  
   193  Stdout of a plugin is redirected to dockerd logs. Such entries have a
   194  `plugin=<ID>` suffix. Here are a few examples of commands for pluginID
   195  `f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62` and their
   196  corresponding log entries in the docker daemon logs.
   197  
   198  ```console
   199  $ docker plugin install tiborvass/sample-volume-plugin
   200  
   201  INFO[0036] Starting...       Found 0 volumes on startup  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   202  ```
   203  
   204  ```console
   205  $ docker volume create -d tiborvass/sample-volume-plugin samplevol
   206  
   207  INFO[0193] Create Called...  Ensuring directory /data/samplevol exists on host...  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   208  INFO[0193] open /var/lib/docker/plugin-data/local-persist.json: no such file or directory  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   209  INFO[0193]                   Created volume samplevol with mountpoint /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   210  INFO[0193] Path Called...    Returned path /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   211  ```
   212  
   213  ```console
   214  $ docker run -v samplevol:/tmp busybox sh
   215  
   216  INFO[0421] Get Called...     Found samplevol                plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   217  INFO[0421] Mount Called...   Mounted samplevol              plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   218  INFO[0421] Path Called...    Returned path /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   219  INFO[0421] Unmount Called... Unmounted samplevol            plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
   220  ```
   221  
   222  #### Using docker-runc to obtain logfiles and shell into the plugin.
   223  
   224  `docker-runc`, the default docker container runtime can be used for debugging
   225  plugins. This is specifically useful to collect plugin logs if they are
   226  redirected to a file.
   227  
   228  ```console
   229  $ sudo runc --root /run/docker/runtime-runc/plugins.moby list
   230  
   231  ID                                                                 PID         STATUS      BUNDLE                                                                                                                                       CREATED                          OWNER
   232  93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25   15806       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25   2018-02-08T21:40:08.621358213Z   root
   233  9b4606d84e06b56df84fadf054a21374b247941c94ce405b0a261499d689d9c9   14992       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/9b4606d84e06b56df84fadf054a21374b247941c94ce405b0a261499d689d9c9   2018-02-08T21:35:12.321325872Z   root
   234  c5bb4b90941efcaccca999439ed06d6a6affdde7081bb34dc84126b57b3e793d   14984       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/c5bb4b90941efcaccca999439ed06d6a6affdde7081bb34dc84126b57b3e793d   2018-02-08T21:35:12.321288966Z   root
   235  ```
   236  
   237  ```console
   238  $ sudo runc --root /run/docker/runtime-runc/plugins.moby exec 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 cat /var/log/plugin.log
   239  ```
   240  
   241  If the plugin has a built-in shell, then exec into the plugin can be done as
   242  follows:
   243  
   244  ```console
   245  $ sudo runc --root /run/docker/runtime-runc/plugins.moby exec -t 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 sh
   246  ```
   247  
   248  #### Using curl to debug plugin socket issues.
   249  
   250  To verify if the plugin API socket that the docker daemon communicates with
   251  is responsive, use curl. In this example, we will make API calls from the
   252  docker host to volume and network plugins using curl 7.47.0 to ensure that
   253  the plugin is listening on the said socket. For a well functioning plugin,
   254  these basic requests should work. Note that plugin sockets are available on the host under `/var/run/docker/plugins/<pluginID>`
   255  
   256  ```console
   257  $ curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/e8a37ba56fc879c991f7d7921901723c64df6b42b87e6a0b055771ecf8477a6d/plugin.sock http:/VolumeDriver.List
   258  
   259  {"Mountpoint":"","Err":"","Volumes":[{"Name":"myvol1","Mountpoint":"/data/myvol1"},{"Name":"myvol2","Mountpoint":"/data/myvol2"}],"Volume":null}
   260  ```
   261  
   262  ```console
   263  $ curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/45e00a7ce6185d6e365904c8bcf62eb724b1fe307e0d4e7ecc9f6c1eb7bcdb70/plugin.sock http:/NetworkDriver.GetCapabilities
   264  
   265  {"Scope":"local"}
   266  ```
   267  
   268  When using curl 7.5 and above, the URL should be of the form
   269  `http://hostname/APICall`, where `hostname` is the valid hostname where the
   270  plugin is installed and `APICall` is the call to the plugin API.
   271  
   272  For example, `http://localhost/VolumeDriver.List`