Docker の Volume plugin で NFS や Glusterfs を利用する

Docker 1.8 では Volume と Network 二種類のプラグイン構造が導入されました。
これを使えば難しかったボリュームの永続化や、コンテナ間の仮想ネットワークが実現できるという触れ込みです。

そろっとこのプラグインとやらを使ってみるかと思い、いくつかリリースされている Volume Plugin から試してみることにしました。

# これまで

コンテナを終了、再起動してもデータを永続化するためにボリュームを使ってきました。これはホストのファイルシステムの一部をコンテナ内にマウントする様な仕組みです。
ボリュームで永続化ができるようになりましたが、ホストとコンテナの内部が密接に関係してしまいコンテナのポータビリティが失われるという問題がありました。

なのでボリュームマウントするのはネットワークファイルシステムにしたいという要求がわいてくるのですが、これも一筋縄ではいかなかった様に思います。
動かしたいコンテナにむけてあらかじめホストでマウントしておくというあたりがコンテナのメリットを損なっています。

以前はコンテナ内部で GlusterFS client を用いて GlusterFS のボリュームをマウントしていました。
http://qiita.com/rerofumi/items/454ea9578b78647f93ce
そこそこ使いやすかったのですが、これもシステム権限をコンテナに与えるとかちょっと無理した感じがします。

# Volume Plugin

そういったボリュームの問題に対する Docker からの解が Volume Plugin となります。

使えるプラグインのリストが以下に載っています
https://docs.docker.com/engine/extend/plugins/

個人的に興味があるのは、GlusterFS をマウントする "GlusterFS plugin" と、NFS をマウントする "Netshare plugin" です。
これらを使って Volume Plugin の使い方を理解していきたいと思います。

## Volume Plugin の仕組み

実際に使って得た知見を先に書いてしまいますが、Volume Plugin はネットワークファイルシステムと直接オンライン通信するものではありませんでした。
Docker Engine がコンテナを起動する際に、Volume Plugin にボリュームの準備を指示します。プラグインはそれを受けたらホストのネットワークファイルシステム機構を用いてテンポラリディレクトリにファイルシステムをマウントします。そして Docker Engine にそのディレクトリ位置を伝えるといった役割となります。
なので Docker Engine からみたらこれまで通りホストのボリュームをコンテナにマウントしているに過ぎません。

コンテナ起動時の引数でネットワークボリューム位置を指定できるとか、ホストのどこにマウントされたかの管理はプラグインが行うとかでシステムの固定化は減りますので便利になっているとは思います。
また、この機構により Docker daemon が起動した後にマウントしたファイルシステムでも問題がないことが保証されますので、昔あったNFSマウントが空っぽで見えない不具合とかには出会わずにすむというものです。

そういった仕組みですので、ホストにはプラグインがマウントするファイルシステムがあらかじめインストールしてあるということが前提となります。

# docker-volume-glusterfs

https://github.com/calavera/docker-volume-glusterfs

下記手順でビルドします。Docker 本体もフェッチしますので結構時間がかかります。

```
 # go get github.com/calavera/docker-volume-glusterfs
```

あらかじめ Docker engine のホストには Gluster FS が利用できる環境(サーバー、クライアント両方？)を整えておきます。

docker-volume-glusterfs という実行ファイルはバックグラウンド起動させるものですので、常用する場合は initd なり systemd なりで起動するようにしてください。

```
 # docker-volume-glusterfs -servers gfs-1:gfs-2:gfs-3
```

```-servers``` を指定してプラグインを起動しますが、このコマンドは帰ってきません。バックグラウンドで起動させておいてください。
docker で ```--volume-driver glusterfs``` オプションを指定すると起動中の docker-volume-glusterfs にアクセスすることになります。

```
 # docker run --volume-driver glusterfs --volume datastore:/data debian bash
```

コンテナの起動時に ```--volume-driver glusterfs``` でプラグインを ```--volume``` で GlusterFS の datastore 名を指定することで、コンテナ内にマウントできます。
正確には docker-volume-glusterfs が datastore をホストの /var/lib 下にマウントし、そのディレクトリ名をボリュームとしてコンテナに渡します。

# docker-volume-netshare

https://github.com/gondor/docker-volume-netshare

このプラグインは NFS, AWS EFS, CIFS と三種類のネットワークファイルシステムに対応していますが、実際は同時に 1つを選択して利用します。
今回は NFS を試しました。

バイナリが配布されているのでそれをダウンロードできます。私は Debian Package をダウンロードしてインストールしました。systemd 設定までされますので、あとは ```systemctl start``` なり ```systemctl enable``` なりするだけです。

基本的には docker-volume-glusterfs と同じく docker-volume-netshare を起動するとプラグインとして待ち受け続けます。バックグラウンドで動作させてください。
Debian Package の場合は /etc/default/docker-volume-netshare に設定ファイルが置かれますのでこれを編集してください。デフォルトでは nfs が有効になっています。

```
 # docker-volume-netshare nfs
```

で NFS プラグインになるのですが、このとき強制で NFS v4 を使おうとします。
NFS v4 未対応の環境では接続エラーになってしまいますのでオプションを付与して v3 を指定してください。

```
 # docker-volume-netshare nfs -v 3
```

個人用 NAS とかがある場合は CIFS も使い手がありそうです。


# おわりに

Docker engine の Volume Plugin とはなんぞや？というあたりから始まっての自分自身が納得した範囲でのメモとなります。
案外シンプルな仕組みなんだなということが分かるとそれにそったシステム構成の仕方が見えてくるのではないでしょうか。