分散ファイルシステム GlusterFS による Web サーバー間の同期

&gt; to English Pages
https://kyowg.blogspot.com/2017/12/distributed-parallel-fault-tolerant.html

## 1. 要約
この記事では、クラスタリング環境における各 Web サーバーへのソースコードデプロイ処理の時間差による差分発生を抑止する方法の一つとして、各 Web サーバーのファイルシステム間を GlusterFS のようなフォールトトレラントな分散ファイルシステムで同期させるアプローチを投稿します。

## 2. はじめに
複数の Web サーバーで構成されているようなクラスタリング環境において、そのノード間のソースコードに差分が発生している時間が長い程、予期しない不具合を引き起こす可能性を高めてしまうかもしれません。
分かりやすい例でいえば、ソースコードが古い Web サーバーと新しい Web サーバーの間を、アクセスが行き来してしまった場合を考えれば、想像に難しくないでしょう。

このような課題に対しては、ロードバランサーのセッション維持機能を活用して解決されている事例も多いかとは思いますが、ということはロードバランサーとの連動性や制約に縛られる割合も高めているという事にもなります。
これがまた、新たな課題（一部後述します）を生むという経験をされた方も、いらっしゃるのではないでしょうか。

また、rsync や lsyncd、CI ツールなど、Web サーバー間のソースコードの同期について、様々な方法が存在しますが、並列処理によるデプロイ方式ではない限り、これらの方法は「ノード数 x デプロイ」処理に対して手動と自動の時間差を埋めているだけに過ぎず、ソースコードの差分発生の根本的な解決にはなっていません。
特に rsync など、同期の性質が片方向性の場合には、強引に相互同期をかけてもデータの整合性には保証がないため、それらの対策を講じるためにツールや制約への依存度を更に高めてしまえば、システムスケーラビリティや弾力性や生産性が更に損なわれる硬直したシステムが生まれてしまうなど、更なる新たな課題が発生するかもしれません。

そこでこの記事では、これらの課題の解決方法の一つとして、Web サーバー間のファイルシステムを GlusterFS のような分散ファイルシステムで同期させるアプローチを投稿します。
（しかし、上記の課題が問題とならない場合には、このポストは役に立たないかもしれません。）

GlusterFS は、分散型並列フォールトトレラントファイルシステムです。
GlusterFS を使用するいくつかのメリットは、ファイルシステムの分散や同期、容量の増減がシステム無停止で実現できるなど、フォールトトレラントな設計が可能なところにもあります。
もちろん、同期も双方向であり、マスターやスレーブという概念もありません。
ただし、ロックされ続けるようなファイル（RDB の PID ファイルなど）を Gluster ボリュームに含める事はオススメできません。

更にこのアプローチには、下記のような副次的なメリットも生まれます。

* 自動・手動を問わず、複数回のデプロイ処理がいらない
* Web アプリケーションのセッション環境に、DB や LB のセッション維持機能との連動に依存しないファイルシステムを利用できる
* ソースコード以外の用途でも Web サーバー間で完全同期できるため、ミドルウェアまわりなどの複数回の設定作業を減らせる

では、以降でその設計例と構築例を投稿してみます。

## 3. GlusterFS 設計
以下の図は、GlusterFS の大まかな概念です。
![GlusterFS.png](https://qiita-image-store.s3.amazonaws.com/0/260161/999fdc15-bbbf-7898-198c-c5bfb0a21c8e.png)

以下の図は、このポストの構成例です。
ボリュームサーバー群は用意せず、シンプルな自己完結型構成となっています。
Web サーバー自身が、ボリュームサーバーとクライアントとなり、自身のボリュームに対してクライアントからマウントして接続している仕組みです。
当然、ブリックを増減することで、システム構成を変更することは可能です。
![GlusterFS_Example.png](https://qiita-image-store.s3.amazonaws.com/0/260161/da9b5fa8-778d-d7fa-107c-9964c4e30b1d.png)

## 4. GlusterFS 環境
* RHEL 7 系
* GlusterFS 4.1.5

## 5. GlusterFS サーバー設定
### 5-1. GlusterFS サーバーインストール
@ Web サーバー 1, 2
`$ sudo yum -y install centos-release-gluster`
`$ sudo yum -y install glusterfs-server`

### 5-2. GlusterFS サーバー起動
@ Web サーバー 1, 2
`$ sudo systemctl start glusterd`
`$ sudo systemctl enable glusterd`
`$ sudo systemctl status glusterd`

### 5-3. GlusterFS hosts ファイル設定
@ Web サーバー 1, 2
`$ sudo vim /etc/hosts`

```text:/etc/hosts
10.0.0.1 web1.example.com
10.0.0.2 web2.example.com
```

### 5-4. GlusterFS ストレージプール設定
@ Web サーバー 1
`$ sudo gluster peer probe web2.example.com`

### 5-5. GlusterFS ストレージプール確認
@ Web サーバー 1, 2
`$ sudo gluster peer status`

## 5-6. GlusterFS ボリューム作成
@ Web サーバー 1 のみ
`$ sudo gluster volume create server replica 2 web1.example.com:/server/ web2.example.com:/server/ force`

### 5-7. GlusterFS ボリューム情報確認
@ Web サーバー 1, 2
`$ sudo gluster volume info`

### 5-8. GlusterFS ボリューム起動
@ Web サーバー 1
`$ sudo gluster volume start server`

### 5-9. GlusterFS ボリューム状態確認
@ Web サーバー 1, 2
`$ sudo gluster volume status`

## 6. GlusterFS クライアント設定
### 6-1. GlusterFS クライアントインストール
@ Web サーバー 1, 2
`$ sudo yum -y install glusterfs glusterfs-fuse glusterfs-rdma`

### 6-2. GlusterFS クライアントにサーバーをマウント
@ Web サーバー 1
`$ sudo mkdir /client`
`$ sudo mount -t glusterfs web1.example.com:/server /client`
`$ sudo df -Th`

@ Web サーバー 2
`$ sudo mkdir /client`
`$ sudo mount -t glusterfs web2.example.com:/server /client`
`$ sudo df -Th`

### 6-3. GlusterFS クライアント：自動マウント
@ Web サーバー 1
`$ sudo vim /etc/fstab`

```text:/etc/fstab
web1.example.com:/server       /client   glusterfs       defaults,_netdev        0 0
```

@ Web サーバー 2
`$ sudo vim /etc/fstab`

```text:/etc/fstab
web2.example.com:/server       /client   glusterfs       defaults,_netdev        0 0
```

### 6-4. GlusterFS 同期テスト
@ Web サーバー 1
`$ sudo cd /client`
`$ sudo touch test.txt`
`$ sudo ls`

@ Web サーバー 2
`$ sudo cd /client`
`$ sudo ls`
`$ sudo rm text.txt`

@ Web サーバー 1
`$ sudo ls`

## 7. まとめ
この記事では、クラスタリング環境における各 Web サーバーのファイルシステム間を GlusterFS のような分散型フォールトトレラントファイルシステムで同期させるアプローチを投稿してみました。
このソリューションを利用する事で、各 Web サーバーへのソースコードデプロイ処理の時間差による差分発生を抑止させ、連携システムとの連鎖的な課題やシステムスケールに関する課題を解決する事が可能となりえます。