Docker でデータのポータビリティをあげ永続化しよう

# Docker でデータのポータビリティをあげ永続化しよう

こんにちは、Docker 0.91 が出ましたね。
CoreOS でのデータの置き場所をどうすべきか考えていた時に、CoreOS-devで出ていた話です。
なので知っている人は知ってるかも知れません。

全てにおいて使えるパターンではないのですが、運用形態のひとつとして紹介します。
（もちろん、Dockerはどんどん進化しているのでこのパターンは陳腐化する可能性もあります）

## データの永続化の問題

Docker で悩ましいのはデータの永続化をどうするか？というとこでしょうか.
例：mysql のコンテナを立ち上げる

```
sudo docker run -d -v /var/host_lib/mysql:/var/lib/mysql me/mysql_5_5
```

`-v` オプションをつけて `mysql` のデータを永続化していますね。
さてこれはこれでよいのですが、Docker の旨みを活かせていませんね。
Docker の特徴はコンテナであり、コンテナにするとポータビリティがあげられるわけです。
上記の方法だと Volume でホストにべったり実データが張り付いてしまい、データ自体のポータビリティが下がっ
てしまいます。
また、Docker 内で閉じていない場合、うっかり誰かがデータを削除してしまうかも知れません。

## Data-only Container Pattern

そこで、データのみを格納するコンテナを作成し、データ部のポータビリティをあげてみましょう。
では早速、Dockerfile を書いていきます。
今回はざっくりと動作の確認をするため、シンプルなもので試しています。

データ格納コンテナのDockerfile

```dockerfile
FROM busybox
VOLUME /opt
CMD /bin/sh
```

build.

```
sudo docker build -t me/storage .
```

run.

```
sudo docker run -i -t --name my_data me/storage
```

あるいは 以下一行でもよいでしょう。

```
sudo docker run -i -t -v /opt --name my_data busybox /bin/sh
```

今回は`--name`オプションで任意の名前をつけています。
`--name`はユニークである必要があるので気をつけましょう。
VOLUME で /opt を指定しています。なので/opt以下を格納するコンテナになります。
ではデータ格納コンテナを使ってみます。
別ターミナルなどから以下のコマンドで使ってみましょう。

```
sudo docker run -t -i --volumes-from my_data ubuntu /bin/bash
```

`--volumes-from` で先ほどのコンテナを指定しています。
これで先ほどのデータ格納コンテナとつながりました。
/opt が接続されているので確認してみましょう。

```
root@f2c68ec76ba3:/# touch /opt/test
root@f2c68ec76ba3:/# ls -al /opt/
total 8
drwx------  2 root root 4096 Mar 27 00:34 .
drwxr-xr-x 33 root root 4096 Mar 27 00:34 ..
-rw-r--r--  1 root root    0 Mar 27 00:34 test
root@f2c68ec76ba3:/# touch /opt/testa
root@f2c68ec76ba3:/# ls -al /opt/
total 8
drwx------  2 root root 4096 Mar 27 00:35 .
drwxr-xr-x 33 root root 4096 Mar 27 00:34 ..
-rw-r--r--  1 root root    0 Mar 27 00:34 test
-rw-r--r--  1 root root    0 Mar 27 00:35 testa
root@f2c68ec76ba3:/#
```

データ格納コンテナ側からも見てみます。

```
/ # ls -al /opt
total 8
drwx------    2 root     root          4096 Mar 27 00:35 .
drwxr-xr-x   30 root     root          4096 Mar 27 00:34 ..
-rw-r--r--    1 root     root             0 Mar 27 00:34 test
-rw-r--r--    1 root     root             0 Mar 27 00:35 testa
/ # 
```

できてますね。
データ格納コンテナを`Ctrl+D`などで落としてみましょう。
使用している側のコンテナに戻って以下を実行してみましょう。

```
root@f2c68ec76ba3:/# touch /opt/hoge-
root@f2c68ec76ba3:/# ls -al /opt/
total 8
drwx------  2 root root 4096 Mar 27 00:38 .
drwxr-xr-x 33 root root 4096 Mar 27 00:34 ..
-rw-r--r--  1 root root    0 Mar 27 00:38 hoge-
-rw-r--r--  1 root root    0 Mar 27 00:34 test
-rw-r--r--  1 root root    0 Mar 27 00:35 testa
```

そうです。当たり前ですがデータ格納コンテナは`run`で走らせてなくてもよいのです。
落としたコンテナを`start`で再度起こして中身を見てみましょう。
`docker ps -a`で確認して起動します。

```
sudo docker start <CONTAINER_ID>
sudo docker attach <CONTAINER_ID>

/ # ls -al /opt/
total 8
drwx------    2 root     root          4096 Mar 27 00:38 .
drwxr-xr-x   30 root     root          4096 Mar 27 01:02 ..
-rw-r--r--    1 root     root             0 Mar 27 00:38 hoge-
-rw-r--r--    1 root     root             0 Mar 27 00:34 test
-rw-r--r--    1 root     root             0 Mar 27 00:35 testa
/ #
```

問題ありませんね。
これでポータビリティを確保しつつ、データの永続化を実現出来ました。
データ格納コンテナのデータのバックアップや確認は`docker cp`を使ってホスト側にもってくることで可能です。
また`export`してアーカイブ化してしまうのも手でしょう。
アーカイブしたものを別ホストで展開すれば別ホストでも使用できます。

これを応用すればmysqlのコンテナと複数のデータ格納コンテナを使用してmysql環境をバンバン立ち上げること
ができます。
またnameを変えるだけでデータを切り替えることができるのでテストなどでも使えるかも知れません。
必要に応じて`commit`してregistryにpushして配布するなども場合によってはいいかも知れませんね。

先日書いた以下の記事の開発するプロジェクトデータ部をコンテナに追い出すのもよいでしょう。
[Docker で開発環境も使い捨てにしよう！ ](http://qiita.com/mopemope/items/495ab1f74bcbef0f88bb)

データ格納コンテナは走らせてなくてもよいのですが、うっかり削除する可能性もあるので走らせておくとよい
でしょう。