Download - Plug-ins: Building, Shipping, Storing, and Running - Nandhini Santhanam and Tibor Vass, Docker
Plugins: Build, Store, and RunNandhini Santhanam Tibor VassEngineering Manager, Docker Software Engineer, Docker
- Plugins are first class citizens (starting Docker 17.03)
- Authorization, Volume, Network, IPAM, Logging
Introduction
SSHFS (SSH Filesystem) is a filesystem client to mount and interact with directories and files located on a remote server or workstation over a normal ssh connection
What is sshfs?
https://en.wikipedia.org/wiki/SSHFS
SSHFS Source code:https://github.com/libfuse/sshfs
vieux/sshfs volume plugin: https://github.com/vieux/docker-volume-sshfs
Running a volume plugin
Prepare directory on ssh host$ docker plugin help
Usage: docker plugin COMMAND
Manage plugins
Options: --help Print usage
Commands: create Create a plugin from a rootfs and configuration. Plugin data directory must contain config.json disable Disable a plugin enable Enable a plugin inspect Display detailed information on one or more plugins install Install a plugin ls List plugins push Push a plugin to a registry rm Remove one or more plugins set Change settings for a plugin upgrade Upgrade an existing plugin
Run 'docker plugin COMMAND --help' for more information on a command.
$ docker plugin install vieux/sshfsPlugin "vieux/sshfs" is requesting the following privileges: - network: [host] - mount: [/var/lib/docker/plugins/] - device: [/dev/fuse] - capabilities: [CAP_SYS_ADMIN]Do you grant the above permissions? [y/N]
Install vieux/sshfs
Install vieux/sshfs$ docker plugin install vieux/sshfsPlugin "vieux/sshfs" is requesting the following privileges: - network: [host] - mount: [/var/lib/docker/plugins/] - device: [/dev/fuse] - capabilities: [CAP_SYS_ADMIN]Do you grant the above permissions? [y/N] ylatest: Pulling from vieux/sshfsb2bcc48d3424: Download completeDigest: sha256:151e6d386ab93a4d9f8ec0befd6c43485fe9e1151fd9784493b147ca621d3d5dStatus: Downloaded newer image for vieux/sshfs:latestInstalled plugin vieux/sshfs
Use vieux/sshfs plugin
$ docker plugin lsID NAME DESCRIPTION ENABLEDdfe9270de30a vieux/sshfs:latest sshFS plugin for Docker true
$ docker volume create -d vieux/sshfs -o sshcmd=user@host:/some/path -o password=”$password” -o port=”$port” mysshvolume
$ docker run -it --rm -v mysshvolume:/remote busybox sh/ # cat /remote/dockerconaustin
- docker plugin install vieux/sshfs
- review permissions
- docker volume create --driver vieux/sshfs [-o …] myvolume
- docker run -v myvolume:/remote busybox
Recap: Running a volume plugin
Misuse the plugin
$ docker volume create -d vieux/sshfs -o sshcmd=user@host:/some/path -o password=”$badpassword” -o port=”$port” mysshvolume
$ docker run -it --rm -v mysshvolume:/remote busybox shdocker: Error response from daemon: error while mounting volume '/var/lib/docker/plugins/cd540062f8b7e667d0e94cef262ff72ce10264fb0dea6c53393b18c840fc7a8e/rootfs': VolumeDriver.Mount: exit status 1.
Check the daemon logs
$ tail -f /var/log/docker.log | grep plugin=Apr 6 23:29:10 moby root: time="2017-04-06T23:29:10Z" level=info msg="read: Connection reset by peer" plugin=3fd525f16cb675325cf99a49455ab05e60d1da53d8b9689c69ea6c7f8619ef17Apr 6 23:29:10 moby root: time="2017-04-06T23:29:10Z" level=info plugin=3fd525f16cb675325cf99a49455ab05e60d1da53d8b9689c69ea6c7f8619ef17Apr 6 23:29:10 moby root: time="2017-04-06T23:29:10Z" level=info msg="exit status 1" plugin=3fd525f16cb675325cf99a49455ab05e60d1da53d8b9689c69ea6c7f8619ef17
$ docker volume rm mysshvolume
$ docker plugin disable vieux/sshfs
$ docker plugin set vieux/sshfs DEBUG=1
$ docker plugin enable vieux/sshfs
$ docker volume create -d vieux/sshfs -o sshcmd=user@host:/some/path -o password=”$badpassword” -o port=”$port” mysshvolume
The DEBUG setting is NOT generic to all plugins, it is defined by this vieux/sshfs plugin (more on this later).
Modify plugin settings
$ docker plugin ls --no-trunc
ID NAME DESCRIPTION ENABLED
9fef4eb6fa883d44e9c1c2901fb598f39f67d50bcc0e1653b4f393807fb80558 vieux/sshfs:latest sshFS plugin for Docker true
$ docker-runc exec -t 9fef4eb6fa883d44e9c1c2901fb598f39f67d50bcc0e1653b4f393807fb80558 sh
/ # echo hi from plugin container
Pro Tip: Access plugin container
- grep plugin=$pluginID docker.log
- if plugin allows it, set higher verbosity withdocker plugin set
- docker-runc exec -t $pluginID sh
Recap: Debugging a plugin
What constitutes a plugin?- Rootfs of plugin container
- JSON description defining what interface it implements, what permissions it needs
- Reference: https://docs.docker.com/engine/extend/config
- Docker bind-mounts the host’s /run/docker/plugins/$pluginID into the container’s /run/docker/plugins
- Each plugin has to listen on a socket inside /run/docker/plugins
$ ls /run/docker/plugins/*/sshfs.sock
How does it work?
Plugins serve via the socket, an HTTP+JSON API specified in the documentation for each plugin type.
Authorization: https://docs.docker.com/engine/extend/plugins_authorizationVolume:https://docs.docker.com/engine/extend/plugins_volume/Network:https://docs.docker.com/engine/extend/plugins_network/IPAM:https://github.com/docker/libnetwork/blob/master/docs/ipam.md
How does it work?
Pro Tip: Use helper packageGo helper package:https://github.com/docker/go-plugins-helpers
For volume plugins:https://godoc.org/github.com/docker/go-plugins-helpers/volume
$ git clone https://github.com/vieux/docker-volume-sshfs$ cd docker-volume-sshfs$ lsDockerfile LICENSE README.md main.goDockerfile.dev Makefile config.json vendor
$ vim main.go
Demo: building vieux/sshfs
Demo: building vieux/sshfs
Config.json defines:
- Type of functionality the plugin provides docker.volumedriver/1.0 in addition to the name of the socket sshfs.sock.
- entrypoint to the binary- a DEBUG environment variable that’s settable by the user- Access to device /dev/fuse- Linux capability CAP_SYS_ADMIN to be able to mount FUSE from the container- Host networking to access the remote host- Bind mount to store state outside the plugin- Last but not least, PropagatedMount: the path inside the container that needs
to be propagated back into docker’s mount namespace
Demo: building vieux/sshfs
Build the sshfs image and extract rootfs
$ docker build -t sshfs .$ docker container create --name tmp sshfs$ mkdir -p ./plugin/rootfs$ docker container export tmp | tar -x -C ./plugin/rootfs
Add plugin config
$ cp config.json ./plugin/
$ ls ./pluginconfig.json rootfs/
Demo: building vieux/sshfs
Create plugin
$ docker plugin create tiborvass/sshfs ./plugin$ docker plugin ls
ID NAME DESCRIPTION ENABLED
f207db14aa5b vieux/sshfs:latest sshFS plugin for Docker true3fd525f16cb6 tiborvass/sshfs:latest sshFS plugin for Docker false
- implement plugin HTTP+JSON API corresponding to the desired plugin type
- containerize plugin + export rootfs- write config.json for plugin
- docker plugin create tiborvass/sshfs ./pluginwhere ./plugin contains:
- config.json- rootfs/
Recap: Building a plugin