LoginSignup
48
44

More than 5 years have passed since last update.

docker-plugins の使い方

Last updated at Posted at 2014-11-06

概要

Docker に シンプルな hook の機構をもたらしてくれる docker-plugins の使い方

docker-plugins とは

docker-plugins は Dockerのライフサイクルイベント(docker events)をトリガーに任意のプラグインを実行するのを可能にしてくれる。Docker Remote API の events stream を直接使って hook 処理 を行う事はできるが、git hooks のようにカジュアルにできるようにしたのがポイントだと思う。

利用可能な hooks

  • exists - docker-plugins が events stream を listen し始める前から存在してるコンテナに対して起きるイベント
  • create
  • destroy
  • die
  • export
  • kill
  • pause
  • restart
  • start
  • stop
  • unpause
  • untag - サポートはされているがビルトインのプラグインでは利用しない
  • delete - サポートはされているがビルトインのプラグインでは利用しない

docker-plugins の仕組み

docker-plugins も コンテナとして動かして利用することを前提に作られている。docker-plugins コンテナ起動時にホストの docker socket をマウントすることで、コンテナ内からホストの Docker daemon に対して Docker コンテナ/イメージ の操作を行う。

docker-plugins は以下の 2 つのツール/ライブラリを利用している

plugn

go と bash でできた hook システム。

下記の構造で plugins を作成し、

plugins/
├── available
│   ├── example-plugin1
│   │   ├── hookA
│   │   ├── hookB
│   │   └── plugin.toml
│   └── example-plugin2
│       ├── hookA
│       ├── hookC
│       └── plugin.toml
└── config.toml

hook を trigger する

# plugin を利用可能にする
$ plugn enable <plugin>
$ plugn trigger <hook> (<params>)

$ plugn trigger <hook> コマンドでは、plugn で利用可能な plugins が持つ <hook> という名前のスクリプトを実行する。

使い方例:

# example-plugin1 を利用可能にする
$ plugn enable example-plugin1

# hookA hook をトリガーする
# これで plugins/available/example-plugin1/hookA が引数 "mike" とともに実行される
$ plugn trigger hookA mike

この仕組みで hooks システムを実現している。

dockerhook

docker の events stream を listen し、各イベントが起きると、引数で受け取った hook スクリプトにイベント対象のコンテナ ID を渡して実行する daemon といった感じ。docker-plugins では以下のように利用されている。

dockerhook "/bin/plugn trigger"

hook が実行される流れ

例えば、ビルトインの autoremove プラグインでは、docker コンテナが die すると自動的にそれを docker rm するプラグイン。
処理の流れは以下のようになる:

  1. docker-plugins コンテナを起動
    • コンテナの起動スクリプトにて dockerhook "/bin/plugn trigger" が実行される
    • dockerhook が docker の events stream を listen し始める
  2. 手動でコンテナ A を start する
  3. 手動でコンテナ A を stop する
  4. dockerhook が events stream より die イベントを受け取る
    • dockerhook が plugn trigger die <コンテナID> を実行する
  5. plugn が利用可能なプラグインの中の die スクリプトを実行する
    • autoremove プラグインの die スクリプトで $ docker rm $1 が実行され、コンテナ A が rm される

インストール

$ docker pull progrium/plugins

ビルトインプラグイン

$ docker run --rm progrium/plugins plugn list
  autoremove           1.0   disabled   Removes any container that dies, including stops and kills
  envhooks             1.0   disabled   Evaluates hook code from environ variables ENVHOOKS_<EVENT>
  timeout              1.0   disabled   Kills containers with TIMEOUT set after TIMEOUT seconds
  webhooks             1.0   disabled   Hits WEBHOOKS_URL or WEBHOOKS_<EVENT>_URL with a POST for each event

autoremove

コンテナの die イベント時に、そのコンテナを docker rm するプラグイン。

docker-plugins コンテナを起動する。

$ docker run \
  --rm \
  -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e "ENABLE=autoremove" \
  progrium/plugins

  autoremove           1.0   enabled    Removes any container that dies, including stops and kills
  envhooks             1.0   disabled   Evaluates hook code from environ variables ENVHOOKS_<EVENT>
  timeout              1.0   disabled   Kills containers with TIMEOUT set after TIMEOUT seconds
  webhooks             1.0   disabled   Hits WEBHOOKS_URL or WEBHOOKS_<EVENT>_URL with a POST for each event

2014/11/06 01:26:04 info: listening for Docker events...

nginx コンテナを起動し、

$ docker run -d nginx:1.7.7
d81e0ef17250fc4fe095a99fb1cd7210c735bce6fd5b4f2afe615444c3e34260

$ docker ps | grep nginx
5522df9fa283        nginx:1.7.7                      "nginx -g 'daemon of   11 seconds ago      Up 11 seconds       443/tcp, 80/tcp          nginx

nginx コンテナを stop または kill してみると

$ docker stop nginx
nginx

# rm されてる
$ docker ps | grep nginx

timeout

TIMEOUT 経過するとそのコンテナを docker kill するプラグイン

$ docker run \
  --rm \
  -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e "ENABLE=timeout" \
  progrium/plugins
$ docker run -d --name nginx -e TIMEOUT=5 nginx:1.7.7
# 起動直後
$ docker ps -a | grep nginx
c7b92e079d98        nginx:1.7.7  "nginx -g 'daemon of   4 seconds ago       Up 4 seconds             443/tcp, 80/tcp          nginx

# 5 秒後
$ docker ps -a | grep nginx
c7b92e079d98        nginx:1.7.7  "nginx -g 'daemon of   14 seconds ago      Exited (-1) 9 seconds ago                            nginx

envhooks

利用可能な hooks ごとにシェルコマンドが実行する。

die イベント時にログに dead と出力する例

$ docker run \
  --rm \
  -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e "ENABLE=envhooks" \
  -e "DEBUG=true" \
  -e "ENVHOOKS_DIE=echo dead \$1" \
  progrium/plugins
$ docker run -d --name nginx -e TIMEOUT=5 nginx:1.7.7
0e6ffc2eb50fa0487ef94942997cdac56769b6a4bb18fc976a2c1fc14aae8840

kill する

$ docker kill

docker-plugins のログ

2014/11/06 04:26:46 info: trigger: 0e6ffc2eb50f die
2014/11/06 04:26:46 info: trigger: 0e6ffc2eb50f kill
dead 0e6ffc2eb50fa0487ef94942997cdac56769b6a4bb18fc976a2c1fc14aae8840

webhooks

各イベントごとに WEBHOOKS_URL または WEBHOOKS_<EVENT>_URL へ POST する

$ docker run \
  --rm \
  -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e "ENABLE=webhooks" \
  -e "WEBHOOKS_URL=http://requestb.in/151o37b1" \
  progrium/plugins

autoremove と timeout の組み合わせ

$ docker run \
  --rm \
  -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e "ENABLE=autoremove timeout" \
  progrium/plugins
$ docker run -d --name nginx -e TIMEOUT=5 nginx:1.7.7

5 秒後にはコンテナが timeout プラグインにより kill された後 autoremove プラグインにより rm される

プラグイン

プラグインのインストール

progrium/docker-plugin-demo の形式でリポジトリを作り、コンテナ起動時に INSTALL で指定するとプラグインをインストールできる。

$ docker run --rm -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e "INSTALL=https://github.com/progrium/docker-plugin-demo.git"
  -e "ENABLE=docker-plugin-demo" \
  progrium/plugins

Cloning into 'docker-plugin-demo'...
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 7 (delta 1), reused 7 (delta 1)
Unpacking objects: 100% (7/7), done.
Checking connectivity... done.
Starting docker-plugins with:
  autoremove           1.0   disabled   Removes any container that dies, including stops and kills
  docker-plugin-demo   1.0   enabled    Just a demo
  envhooks             1.0   disabled   Evaluates hook code from environ variables ENVHOOKS_<EVENT>
  timeout              1.0   disabled   Kills containers with TIMEOUT set after TIMEOUT seconds
  webhooks             1.0   disabled   Hits WEBHOOKS_URL or WEBHOOKS_<EVENT>_URL with a POST for each event

(このプラグインは DEMO_TOKEN 設定しないと動かない)

プラグインの作成

コンテナの起動時にコンテナ情報を etcd に登録し、終了時に削除する簡易なプラグインを作ってみる

$ mkdir register && cd register
$ git init
#!/bin/bash
# start

DOCKER_IMAGE="$(/bin/docker inspect $1 | jq -r '.[].Config.Image')"
etcdctl set /containers/$1 $DOCKER_IMAGE
#!/bin/bash
# die

DOCKER_IMAGE="$(/bin/docker inspect $1 | jq -r '.[].Config.Image')"
etcdctl rm /containers/$1 $DOCKER_IMAGE
[plugin]
name = "register"
description = "Register container to etcd"
version = "1.0"
maintainer_name = "Seigo Uchida"
maintainer_email = "spesnova@gmail.com"

[plugin.config]

[plugin.compatibility]
$ git add .
$ git commit -m "Initial commit"

docker-plugins 起動

$ docker run \
  --rm \
  -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /home/core/register:/tmp/register \
  -v /usr/bin/etcdctl:/usr/bin/etcdctl:r \
  -e "ETCDCTL_PEERS=http://172.17.8.101:4001" \
  -e "INSTALL=/tmp/register" \
  -e "ENABLE=register" \
  -e "DEBUG=true" \
  progrium/plugins
# nginx コンテナを起動すると..
$ docker run -d --name nginx nginx:1.7.7
5a840eb25b12dba53f111068b270c04e94c36babb61a2adbbdc209f02a19caf4

# etcd にキーが追加されてる
$ etcdctl ls /containers
/containers/5a840eb25b12dba53f111068b270c04e94c36babb61a2adbbdc209f02a19caf4

# イメージ名が取得出来る
$ etcdctl get /containers/5a840eb25b12dba53f111068b270c04e94c36babb61a2adbbdc209f02a19caf4
nginx:1.7.7

# nginx コンテナを kill すると..
$ docker kill nginx

# キーが削除されている
$ etcdctl ls /containers

メモと感想

ちょっとしたことやるのに向いている気がする

plugin.toml と hook スクリプト の 2 ファイル作れば好きな hook が仕込めるので楽。
逆に、複雑なことをやろうとすると大変。$ docker inspect <コンテナID>jq でパースした後 bash で結構色々がんばる必要があると思う。

REF

48
44
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
48
44