GlusterFSとNFS-Ganeshaを連携する

# はじめに

GlusterFSのボリュームは、FUSEを使ってマウントする以外にNFSクライアントを使ってマウントすることもできる。
GlusterFS内蔵のNFSサーバはNFSv3プロトコルにのみ対応している。しかしNFS-Ganeshaと連携することによりNFSv4プロトコルにも対応することができる。

元情報は http://blog.gluster.org/2014/09/glusterfs-and-nfs-ganesha-integration/ だが、やってみると結構違った。

# セットアップ

## GlusterFS

本題ではないので特に解説はしないが、私がCentOS 7でいつも使っている標準的な方法を載せておく。CentOS 6でもsystemctlがserviceかchkconfigに変わるのと、xfsprogsがインストールされてなければインストールするくらいの違いだろう。
なお面倒なのでfirewalldは停止させてもらった。

2台をreplicaで構成することとする。
以下のコマンドは2台で実施する。
ストレージを初期化するコマンドを含んでいるので、丸々コピペで実行せず自分の環境に合わせること。

```
# wget http://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-epel.repo -P /etc/yum.repos.d
# yum install glusterfs-server
# systemctl start glusterd
# systemctl stop firewalld
# systemctl disable firewalld
# mkdir /data
# parted -m -s /dev/sdb mklabel gpt
# parted -m -s -a min /dev/sdb mkpart 1 0 -- -1
# mkfs.xfs -i size=512 -n size=8192 /dev/sdb1
# echo $(blkid /dev/sdb1 | awk '{ print $2 }') '/data xfs defaults 1 2' >> /etc/fstab
# mount -a
```

以下はどちらか片方だけで実行する。

```
# gluster peer probe <もう一台のホスト名かIPアドレス>
# gluster pool list # 確認用
# gluster vol create vol1 replica 2 <自分のホスト名かIPアドレス>:/data/brick1 <もう一台のホスト名かIPアドレス>:/data/brick1
# gluster vol set vol1 nfs.disable on
# gluster vol start vol1
# gluster vol status # 確認用
```

なおここで、`gluster vol set vol1 nfs.disable on`はGlusterFS内蔵のNFSサーバ機能を停止するためのコマンドである。
NFSサーバ機能はNFS-Ganeshaから提供するのでGlusterFS内蔵のものは不要である。

## NFS-Ganesha

NFS-GaneshaはGlusterFSと同じコンピュータにインストールしても良いし、別のコンピュータでも良い。

CentOS 6とCentOS 7では手順が結構異なるので、その都度説明する。

NFS-GaneshaがGlusterFSと会話するためのFSAL(File System Abstraction Layer)のインストールが必要なので、/etc/yum.repos.d/glusterfs-nfs-ganesha.repoを以下の内容で作成する。

```text:/etc/yum.repos.d/glusterfs-nfs-ganesha.repo
[glusterfs-nfs-ganesha]
name=glusterfs-nfs-ganesha
baseurl=http://download.gluster.org/pub/gluster/glusterfs/nfs-ganesha/EPEL.repo/epel-$releasever/$basearch/
enabled=1
skip_if_unavailable=1
gpgcheck=0
```

GlusterFS FSALはglusterfs-apiパッケージなどを使用するが、CentOS 7だと標準からインストールできるglusterfs-apiのバージョンが古くて依存性チェックに引っかかるのでGlusterFSのリポジトリも追加してやる。CentOS 6では必要ない。

```
# wget http://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-epel.repo -P /etc/yum.repos.d
```

NFS-Ganeshaはglusterfs-nfs-ganesha.repoにあるものだと依存性チェックに引っ掛かってインストールできなかったりしたのでEPELからインストールすることにする。

```
# yum install epel-release
# yum install nfs-ganesha nfs-ganesha-fsal-gluster nfs-utils
```

NFS-Ganeshaの設定ファイルを作ってやる。これはOS標準のNFSサーバにおける /etc/exports に当たるファイルである。
パスはCentOS 6では /etc/ganesha/ganesha.conf （ディレクトリもないので作る）、CentOS 7では /etc/ganesha.nfsd.conf である。

```
EXPORT {
  FSAL { 
    name = GLUSTER;
    hostname = "<GlusterFSどちらかのホスト名かIPアドレス>";
    volume = "vol1";
  }

  Export_Id = 1;
  Path = "/nfs1_v3";
  Pseudo = "/nfs1_v4";
  Access_type = RW;
  Squash = No_root_squash;
  Disable_ACL = TRUE;
  Protocols = "3,4";
  Transports = "UDP,TCP";
  SecType = "sys";
}
```

ここでPathがNFSv3用のリモートマウントポイント、PseudoがNFSv4用のリモートマウントポイントとなる。
同じにしておくとCentOS 6や7のNFSクライアントはNFSv4で接続するようだ。

またvolumeの名前はGlusterFSに作ったものに合わせる。

この設定ファイルの各項目を説明するドキュメントは詳しいものは特にないので調べる際は検索エンジンに聞くなりソースを読むなり実際に設定して動作を調べるなりすること。私も良く知らない。

**2014-12-25追記**: 後で気付いたがEPELにnfs-ganesha-docsというパッケージがあってインストールするとPDFファイルがいくつか入っている。これを読めば多少設定項目についてわかるようだ。ただし書かれたのは2008年。

NFS-Ganeshaが起動する前にrpcbindが起動している必要があるが、CentOS 7はnfs-utilsインストール直後から起動しているの対して、CentOS 6では起動していない（有効化はされている）ので起動してやる。

```
# service rpcbind start
```

NFS-Ganeshaを起動する。
CentOS 6ではインストールされた時点で有効化されているがCentOS 7ではされていないので有効化も行う。

```text:CentOS6の場合
# service nfs-ganesha start
```

```text:CentOS7の場合
# systemctl start nfs-ganesha
# systemctl enable nfs-ganesha
```

ログは /var/log/ganesha.log にあるので、おかしかったら確認する。

（私はまだどのポートが必要か調べていないので）ファイアウォールを停止する。
調べたら追記する。

```text:CentOS6の場合
# service iptables stop
# chkconfig iptables off
```

```text:CentOS7の場合
# systemctl stop firewalld
# systemctl disable firewalld
```

## NFSクライアント

NFS-Ganeshaに対するNFSクライアントをセットアップする。
といってもOS標準のNFSサーバに接続するのと特に変わりはない。

NFSクライアントをインストール。

```
# yum install nfs-utils
```

mount時に-o nolockが不要になる程度の意味だがrpcbindを起動しておくと良い。
前記の通りCentOS 7はnfs-utilsをインストールした時点ですでに起動しているので、CentOS 6のみで行う手順である。

```
# service rpcbind start
```

ローカルマウントポイントとなるディレクトリを作っておく。

```
# mkdir /data
```

NFSv3を使用する場合はPathに指定したリモートマウントポイント、NFSv4を使用する場合はPseudoに指定したリモートマウントポイントを指定してマウントする。
最近は-t nfsとか指定しなくてもマウントできる。

```
# mount <NFS-Ganashaのホスト名かIPアドレス>:/nfs1_v4 /data
```

上記ではNFSv4でマウントしているので、マウントした後にmountコマンドを引数なしで実行すると最後の1行は以下のような出力となる。

```
x.x.x.x:/nfs1_v4 on /data type nfs (rw,vers=4,addr=x.x.x.x,clientaddr=y.y.y.y)
```

これで完了である。
ちなみにGlusterFSの1台を`systemctl stop glusterfsd glusterd`などで落としても、切り替わりにほんの少しの時間（1秒程度？）が掛かることがあるが引き続き使用できる。これはNFS-Ganeshaに指定した方のGlusterFSサービスであっても、そうない方であっても同じである。
ただしNFS-Ganeshaに指定した方のGlusterFSサービスが落ちている場合はnfs-ganeshaサービスの起動は失敗する。

mountコマンドではなく/etc/fstabに書くなら以下の通り。
_netdevはネットワークが接続されるまで待つオプションである。

```
# echo '<NFS-Ganashaのホスト名かIPアドレス>:/nfs1_v4 /data nfs defaults,_netdev 0 0' >> /etc/fstab
```

# おわりに

今のところGlusterFSの前にNFS-Ganeshaを噛ました場合の利点はNFSv4が使えることしかないように見える。
しかしGlusterFSとNFS-Ganeshaは開発が割と密に連携しているようで、将来はもっと違った利点も出てくることを期待している。

一例として、現在のところNFS-GaneshaはHA機構を持っていないため、せっかくのGlusterFSのHAを生かせずSPOFになってしまう（もっともそれはGlusterFSにFUSEでなくNFSクライアントでマウントした場合も同じだ）。それでNFS-GaneshaにHA機構を持たせるという件が何故かGlusterFSのFeature Requestに挙がっている。
http://www.gluster.org/community/documentation/index.php/Features/HA_for_ganesha

なお、NFS-GaneshaにHA機構がないことに対するワークアラウンドとしては、すべてのNFSクライアント機にNFS-Ganeshaを同居させるという手が考えられる。NFSクライアント機がWindowsだったりするとダメだが。
またこの手を使えば、NFS-Ganeshaはlibgfapi経由でGlusterFSにアクセスしているようなので、FUSEを使ってマウントしてアクセスするより高いパフォーマンスが出るかもしれない。
今現在、私はベンチマークを実施する環境を持ち合わせていないため確かめることができない。もし将来機材が余って測定できるようなら確かめてみたい。