DockerCLI/docs/extend/index.md

10 KiB

description keywords title
Develop and use a plugin with the managed plugin system API, Usage, plugins, documentation, developer Managed plugin system

Docker Engine managed plugin system

Docker Engine's plugin system allows you to install, start, stop, and remove plugins using Docker Engine.

For information about the legacy plugin system available in Docker Engine 1.12 and earlier, see Understand legacy Docker Engine plugins.

Note: Docker Engine managed plugins are currently not supported on Windows daemons.

Installing and using a plugin

Plugins are distributed as Docker images and can be hosted on Docker Hub or on a private registry.

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.

To check the status of installed plugins, use the docker plugin ls command. Plugins that start successfully are listed as enabled in the output.

After a plugin is installed, you can use it as an option for another Docker operation, such as creating a volume.

In the following example, you install the docker4x/cloudstor plugin, verify that it is enabled, and use it to create a volume.

  1. Install the sshfs plugin.

    $ docker plugin install docker4x/cloudstor:17.05.0-ce-azure2 \
      --alias cloudstor:azure \
      CLOUD_PLATFORM=AZURE \
      AZURE_STORAGE_ACCOUNT_KEY="mmpwuGgnSKHodND...." \
      AZURE_STORAGE_ACCOUNT="myswarmstorage"
    
    Plugin "docker4x/cloudstor:17.06.0-ce-azure2" is requesting the following privileges:
     - network: [host]
     - mount: [/dev]
     - allow-all-devices: [true]
    services:
     - capabilities: [CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH]
    Do you grant the above permissions? [y/N] y
    17.06.0-ce-azure2: Pulling from docker4x/cloudstor
    68b66459b745: Verifying Checksum
    68b66459b745: Download complete
    Digest: sha256:aa2ae6026e8f5c84d3992e239ec7eec2c578090f10528a51bd8c311d5da48c7a
    Status: Downloaded newer image for docker4x/cloudstor:17.05.0-ce-azure2
    Installed plugin docker4x/cloudstor:17.06.0-ce-azure2
    

    The plugin requests 4 privileges:

    • It needs access to the host network.
    • It needs access to the /dev mount.    - It needs access to allow-all-devices.    - It needs the CAP_SYS_ADMIN capability, which allows the plugin to run the mount command.    - It needs the CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCHcapabilities, which allows the plugin to bypass file read, write, and execute permission checks.
  2. Check that the plugin is enabled in the output of docker plugin ls.

    $ docker plugin ls
    
    ID                  NAME                DESCRIPTION                       ENABLED
    7e08f3d484c9        cloudstor:azure     cloud storage plugin for Docker   true
    
  3. Create a volume using the plugin. This example mounts the /remote directory on host 1.2.3.4 into a volume named sshvolume.

    This volume can now be mounted into containers.

    $ docker volume create \
      -d cloudstor:azure \
      --name cloudstorvolume
    
    cloudstorvolume
    
  4. Verify that the volume was created successfully.

    $ docker volume ls
    
    DRIVER              NAME
    cloudstor:azure     cloudstorevolume
    
  5. Start a container that uses the volume cloudstorevolume.

    $ docker run --rm -v cloudstorevolume:/data busybox sh -c 'echo test > /data/test'
    $ docker run --rm -v cloudstorevolume:/data busybox cat /data/test
    test
    
  6. Remove the volume cloudstorevolume

    docker volume rm cloudstorevolume
    
    cloudstorevolume
    

To disable a plugin, use the docker plugin disable command. To completely remove it, use the docker plugin remove command. For other available commands and options, see the command line reference.

Developing a plugin

The rootfs directory

The rootfs directory represents the root filesystem of the plugin. In this example, it was created from a Dockerfile:

Note: 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

The config.json file

The config.json file describes the plugin. See the plugins config reference.

Consider the following config.json file.

{
	"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"]
	}
}

This plugin is a volume driver. It requires a host network and the CAP_SYS_ADMIN capability. It depends upon the /docker-volume-sshfs entrypoint and uses the /run/docker/plugins/sshfs.sock socket to communicate with Docker Engine. This plugin has no runtime parameters.

Creating the plugin

A new plugin can be created by running docker plugin create <plugin-name> ./path/to/plugin/data where the plugin data contains a plugin configuration file config.json and a root filesystem in subdirectory rootfs.

After that the plugin <plugin-name> will show up in docker plugin ls. Plugins can be pushed to remote registries with docker plugin push <plugin-name>.

Debugging plugins

Stdout of a plugin is redirected to dockerd logs. Such entries have a plugin=<ID> suffix. Here are a few examples of commands for pluginID f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 and their corresponding log entries in the docker daemon logs.

$ 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

Using docker-runc to obtain logfiles and shell into the plugin.

docker-runc, 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.

$ docker-runc list
ID                                                                 PID         STATUS      BUNDLE                                                                                       CREATED
f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62   2679        running     /run/docker/libcontainerd/f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62	2017-02-06T21:53:03.031537592Z
r
$ docker-runc exec f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 cat /var/log/plugin.log

If the plugin has a built-in shell, then exec into the plugin can be done as follows:

$ docker-runc exec -t f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 sh

Using curl to debug plugin socket issues.

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 /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"}

When using curl 7.5 and above, the URL should be of the form http://hostname/APICall, where hostname is the valid hostname where the plugin is installed and APICall is the call to the plugin API.

For example, http://localhost/VolumeDriver.List