DockerでGlusteFS。分散ファイルシステムの実装。


どうも、千葉です。
今日は、GlusterFSの検証をします。そして、Docker上でやります。
なぜ、Dockerを使うかというと私のDockerスキル向上のためです。
そして、１月の社内勉強会で「Docker冬祭#1」をりやります。
今日はGlusterFSを通して、Dockerをもっと身近に。


## 今回の構成
![aaa.jpg](https://qiita-image-store.s3.amazonaws.com/0/33834/ee1b8028-4b2d-20a8-8e13-d60984ce92ac.jpeg "aaa.jpg")

### ポイント
* ポータビリティを向上させるために、Gluster層とストレージ層に分けます
  Glusterサーバにデータを格納しても良いが、そうすとDcokerのいいところ、ポータビリティ性が激減する
　データに引きづられるコンテナになってしまうため、ここは分離します
　こちらのコンテナは、ボリュームコンテナとして永続化して使います。


## 環境
OS:OS X Yosemite 10.10.1
Dockerのインストール方法は[こちら](http://qiita.com/iron-breaker/items/192561cf6eb7134350c8)から

## サーバの起動
以下、5台をDockerを使って起動していきます。
* client
* gluster1
* gluster1-storage
* gluster2
* gluster2-storage

### Dockerの起動と接続設定
````
$ boot2docker start
$ export DOCKER_HOST=tcp://[Your IP Address]:2376
$ export DOCKER_CERT_PATH=/Users/Jun/.boot2docker/certs/boot2docker-vm
$ export DOCKER_TLS_VERIFY=1
````

### CentOS6のイメージをダウンロード

````
$ docker pull centos:centos6
$ docker images
````
※ちょっと時間かかります

### GlusterFS用のイメージを作成する
GlusterFS用のマスターイメージを作成します。
GlusterFS用のパッケージを入れて保存します。
保存したマスターイメージからGlusterFS用コンテナをバシバシ起動します。

![bbb.jpg](https://qiita-image-store.s3.amazonaws.com/0/33834/d164a3d7-1874-1648-29d8-b03110988d08.jpeg "bbb.jpg")

CentOSのイメージからコンテナを起動し、コンソールに接続します。


````
$ docker run -dti --name GlusterMaster centos:centos6 /bin/bash
$ docker ps
$ docker attach GlusterMaster
````

ここからは、コンテナ上での作業となります。
Gluster関連のパッケージをインストール。


````
# yum update -y
# yum install -y wget
# wget -P /etc/yum.repos.d http://download.gluster.org/pub/gluster/glusterfs/LATEST/EPEL.repo/glusterfsepel.repo
# yum install -y glusterfs glusterfs-server
# exit
````

インストールが完了したので、イメージを作成します。


````
$ docker ps -a
$ docker commit GlusterMaster myimage/glusterserver
$ docker images
````

これで、myimage/glusterserverというイメージができました。
これを元に、GlusterFSコンテナを起動していきます。

### イメージからコンテナをそれぞれ起動する

まずは、データボリューム用のコンテナを起動します。


````
$ docker run -v /data --name gluster1-storage centos:centos6 /bin/bash
$ docker run -v /data --name gluster2-storage centos:centos6 /bin/bash
````

ボリューム用コンテナをマウントして、それぞれ起動します。
※3つのターミナルで、それぞれ実行してください。

````
$ docker run -idt --name client myimage/glusterserver /bin/bash
$ docker run -idt --volumes-from gluster1-storage --name gluster1 myimage/glusterserver /bin/bash
$ docker run -idt --volumes-from gluster2-storage --name gluster2 myimage/glusterserver /bin/bash
$ docker ps
````

### コンテナへの接続
コンテナが接続できたので、それぞれ接続します。

````
$ docker attach gluster1
$ docker attach gluster2
$ docker attach client
````
※docker run時にiオプションつけると、起動時にattacheできますが、あえてやってません
※起動時に指定した、ボリュームコンテナの領域/dataが利用可能になってます

### TIPS:コンテナから一旦抜けたくなったら（一旦抜ける場合）

````
control + p　→ control + q
````
※再接続する場合は、↑のコンテナへの接続を実施

### TIPS:ホスト名を変更してみる
3台あって紛らわしいので変更します
と、思って

````
# vi /etc/sysconfig/network
# vi /etc/hostname
# docker restart client
````
とかやってみましたが無理でした。
これは私の考え方が古くて、dockerではホスト名を使う意味があんまりないんだと思います。
ばんばんコンテナの起動・停止が繰り返される世界でだれもホスト名は気にしないんだと思います。
ということで、変更やめました。

### GlusterFSのボリューム作成

まずは、glusterdを起動します。
※gluster1、gluster2で実行

````
service glusterd start
````

### gluster1、gluster2のIPアドレスを確認し、peerとして登録
※1台で実施。GlusterFSではプライマリサーバ、セカンダリサーバとかの概念がないので、どちらで実施しても問題ないです。今回は、gluster1で実施してます。

````
# gluster peer probe [ipアドレス]
# gluster peer status
````
Connectedになってるはずです。

### ボリュームの作成
/dataをGlusterFS上のミラーボリュームとして作成します。
その他のタイプは[こちら](http://dev.classmethod.jp/cloud/aws/glusterfs-on-ec2/)を参考に。

ますは、brick用のディレクトリを作成します。
gluster1、gluster2でそれぞれ実施。

```
# mkdir /data/vol1
```

GlusterFSのボリューム作成
gluster1で実施

```
# gluster volume create test-vol replica 2 172.17.0.33:/data/vol1 172.17.0.34:/data/vol1
volume create: test-vol: failed: Glusterfs is not supported on brick: 172.17.0.33:/data/vol1.
Setting extended attributes failed, reason: Operation not permitted.
```

あら、エラーで作成できません。
調べたところ

どうやら、GlusterFSでは拡張ファイル属性を利用しているのですが、
dockerでは特権モードの制限をいくつかしているようです。

参考：
	* [Running GlusterFS inside docker container](http://blog.gluster.org/category/redhat/)
	* [Linuxの拡張ファイル属性(extended attributes)についてメモ](http://siguniang.wordpress.com/2013/11/19/notes-on-linux-extended-attributes/)
	* [(ヽ´ω`) < *****](http://www.tsugihagi.net/entry/2014/10/05/083120)

起動時のオプションで変更できるようです。
--cap-add、--cap-dropで細かく設定できるみたいですが、今回は大盤振る舞いで--privilegedを指定して起動します。

と、いうことで先ほどのコンテナを削除して起動しなおします。
glusterfsのボリュームも再作成します。

※gluster1のターミナルで実行

```
# exit
$ docker rm gluster1
$ docker run --privileged=true -idt --volumes-from gluster1-storage --name gluster1 myimage/$ glusterserver /bin/bash
```

※gluster2のターミナルで実行

```
# exit
$ docker rm gluster2
$ docker run --privileged=true -idt --volumes-from gluster2-storage --name gluster2 myimage/glusterserver /bin/bash
```
それでは、気をとりなおしてボリュームの作成

gluster1、gluster2でそれぞれ実施。

```
# service glusterd start
```

gluster1で実施

````
# gluster peer probe [ipアドレス]
# gluster peer status
# gluster volume create test-vol replica 2 172.17.0.36:/data/vol1 172.17.0.37:/data/vol1
# gluster volume start test-vol
# gluster volume info
```

これで、glusterfsでのボリュームが出来ました。

## clientからマウントして使ってみる
※clientも、--privileged=trueで起動し直さないとマウントできませんでしたのでオプション付で起動してください

clientのターミナルより実行

```
# mkdir /data
# mount -t glusterfs [gluster1のIP]:/test-vol /data
```

※gluster1、gluster2で/data/vol1を見ると同じファイルが作成されています。


## まとめ
* Dockerを利用した分散ファイルシステムの構築が可能
* Dockerのポータビリティ性を考慮する場合は、永続データをどうするか考慮が必要
* セキュリティを向上するにはprivilegedにて、細かなセキュリティ設定を行う必要がある
* 調査していたら、dockerはホストのボリューム領域をマウントしてrootとして利用できるためセキュリティ的な考慮が必要
* オーケストレーションでの実装ができればよいと思った。（容量足りなくなったら、コンテナを起動により自動的にボリューム追加が出来る構成）