AmazonLinuxでGlusterFSのGeo-Replication

先日Linux女子部で、「AWSではじめるGlusterFS」というお題目で話をする機会を頂きました。
デモンストレーションとして、EC2インスタンス複数使ってGlusterFSのレプリケーション構成を一発で作れるCloudFormationテンプレートを作成しましたが、Geo-Replicationについては試すことが出来なかったので、ひとまずその足がかりとして、EC2上でGer-Replicationを構築してみました。

Geo-Replicationとは?

GlusterFSが持つレプリケーション機能のうち、遠隔地へのレプリケーションを目的とした機能です。
遠隔地へのレプリケーションのため、通常のレプリケーションとは異なり、非同期でのレプリケーションを行ないます(通常のレプリケーションは同期処理)。GlusterFS本体に加え、Geo-Replicationモジュールをインストールすることで、利用可能になります。


Geo-Replicationは、1つのGlusterFSボリューム(マスター)を、複数のGlusterFSボリュームもしくは通常のファイルシステム(スレーブ)に対してレプリケーションする事が出来ます。
仕組みとしては、Pythonで実装された「gsyncd」というプロセスがマスターのサーバで動作し、定期的にファイルの変更を検知して、変更されたものをスレーブへ転送することで、非同期のレプリケーションを実現しています。
なお、通常のレプリケーションは双方向に同期を行なう(マルチマスター)のに対して、Geo-Replicationはマスタースレーブモデルのため、マスターからスレーブへの反映しか行なわれません。例えばスレーブにファイルを足した場合でも、同期処理のタイミングで、スレーブへ足したファイルは削除されます。

EC2での環境構築

今回はAmazonLinuxを使用しました。その都合上、極力rootを使わないような形で設定してみました。
出来上がりは以下のようなイメージです。
https://cacoo.com/diagrams/tIey5eqjlFgTBXaS-2A00B.png
EC2インスタンスを各リージョンで2台ずつ起動して、同一のセキュリティグループに入れます。セキュリティグループは、同一セキュリティグループからの通信を受け入れるように設定をしておきます。また、使用するキーペアはすべて同一のものを使用する前提とします。

Replication設定

まず最初に、マスター側のレプリケーション構成を作ります。AmazonLinuxを意識して、すべてec2-userで作業を行ないます。
まずマスター2から作業を行ないます。

sudo yum localinstall -y http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-server-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-fuse-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-geo-replication-3.3.0-1.el6.x86_64.rpm
sudo chkconfig glusterd on
sudo mkdir /gluster-vol

つぎにマスター1での作業です。

sudo yum localinstall -y http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-server-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-fuse-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-geo-replication-3.3.0-1.el6.x86_64.rpm
sudo chkconfig glusterd on
sudo mkdir /gluster-vol
sudo gluster peer probe マスター2のプライベートIP
sudo gluster vol create vol01-master replica 2 マスター1のプライベートIP:/gluster-vol/brick-vol01-master マスター2のプライベートIP:/gluster-vol/brick-vol01-master 
sudo gluster vol start vol01-master

プライベートIPの部分は、ホスト名でも構いません。
この作業で、マスター2台によるレプリケーション構成が作れます。


同様の作業を、スレーブにも行ないます。
スレーブ2から作業を行ないます。

sudo yum localinstall -y http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-server-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-fuse-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-geo-replication-3.3.0-1.el6.x86_64.rpm
sudo chkconfig glusterd on
sudo mkdir /gluster-vol

次にスレーブ1での作業です。

#10.130.87.159(slave-geo-slave)
sudo yum localinstall -y http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-server-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-fuse-3.3.0-1.el6.x86_64.rpm http://adsj-demo.s3.amazonaws.com/gluster-fs3.3/glusterfs-geo-replication-3.3.0-1.el6.x86_64.rpm
sudo chkconfig glusterd on
sudo mkdir /gluster-vol
sudo gluster peer probe スレーブ2のIP
sudo gluster vol create vol01-slave replica 2 スレーブ1のIP:/gluster-vol/brick-vol01-slave スレーブ2のIP:/gluster-vol/brick-vol01-slave
sudo gluster vol start vol01-slave

ここまでで、スレーブ側にもレプリケーション構成が構築出来ます。

Geo-Replication設定

続いてGeo-Replicationの設定を行ないます。
Geo-Replication使用時はマスターからスレーブへSSHで接続を行ないますが、AmazonLinuxはデフォルトでrootでのSSHログインが不可のため、今回はec2-userユーザーでの接続を行ないます。一般ユーザーでのGeo-Replicationを行なう場合は、「mountbroker」という仕組みを使用する必要があり、こちらの設定を行ないます。
スレーブ1で、以下のように作業を行ないます。

#mountbrokerのルートフォルダ作成
sudo mkdir /var/mountbroker-root
#権限設定
sudo chmod 711 /var/mountbroker-root
#以下のファイルを編集 (下の3つのoptionを追加)
sudo vi /etc/glusterfs/glusterd.vol
volume management
    type mgmt/glusterd
    option working-directory /var/lib/glusterd
    option transport-type socket,rdma
    option transport.socket.keepalive-time 10
    option transport.socket.keepalive-interval 2
    option transport.socket.read-fail-log off

    option mountbroker-root /var/mountbroker-root 
    option mountbroker-geo-replication.ec2-user vol01-slave
    option geo-replication-log-group ec2-user
end-volume
#サービス再起動
sudo service glusterd restart

作成したmountbrokerのルートフォルダと、設定ファイルに記載したoptionのフォルダパスが異なる場合、サービスが正しく再起動できたように見えて実はサービスが上がっていない、という状況になるため、glusterdが上がっているかどうかを確認して下さい。


最後に、マスター1へGeo-Replication設定を行ないますが、その前にマスター1のEC2インスタンスへ、pemファイルをアップロードします。今回はec2-userを使用するため、EC2へログインする時に使用したpemファイルをそのままアップロードします。もしpemを外に出したくない場合は、事前にスレーブ1にユーザーを作成して、マスター1からSSHでログインできるように設定しておきます。(この際、キーペアを使用してかつパスワードなしでログイン出来るようにしておく必要があります)

#スレーブ1で呼び出すgsyncdのパス(デフォルトが/usr/local/libexec/...となっているため、再設定)
sudo gluster volume geo-replication vol01-master ssh://ec2-user@スレーブ1のグローバルIP:gluster://localhost:vol01-slave config remote-gsyncd /usr/libexec/glusterfs/gsyncd
#SSH接続設定
sudo gluster volume geo-replication vol01-master ssh://ec2-user@スレーブ1のグローバルIP:gluster://localhost:vol01-slave config ssh-command ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i pemファイルのパス
#Geo-Replicationの開始
sudo gluster volume geo-replication vol01-master ssh://ec2-user@スレーブ1のグローバルIP:gluster://localhost:vol01-slave start

以上で設定は終了です。接続ステータスは以下のコマンドで確認出来ます。

sudo gluster volume geo-replication vol01-master status

ステータスがOKとなっていれば、正しく設定できています。

動かないときは・・

もしうまく動かない場合は、ログレベルをdebugに変更することで、エラー詳細を確認出来ます。
マスター1で以下の設定を追加します。

sudo gluster volume geo-replication vol01-master ssh://ec2-user@スレーブ1のグローバルIP:gluster://localhost:vol01-slave config log-level debug
sudo gluster volume geo-replication vol01-master ssh://ec2-user@スレーブ1のグローバルIP:gluster://localhost:vol01-slave config gluster-log-level debug

ログは、マスター1は/var/log/glusterfs/geo-replication以下に、スレーブ1は/var/log/glusterfs/geo-replication-slave以下に出力されます。
エラー時にPythonのエラーが出力されることがありますが、その場合大体
パーミッション設定
・フォルダがない
SSH接続でこけている
のうちのどれかのケースに当てはまります(私がはまった経験では)

スレーブを通常のファイルシステムにする場合

スレーブ側はGlusterボリュームでなく、通常のファイルシステムを対象にすることが出来るのですが、その場合はrootでのSSH接続を行なわないと、うまくレプリケーション出来ませんでした。おそらくパーミッションの問題だと思うのですが、もし詳しくご存じの方がいらしたら教えて頂ければと思います。
またもしファイルシステムを対象にしたい場合は、スレーブ1でrootでのSSHログインを許可した後に、以下の設定をおこないます。

gluster volume geo-replication vol01 ssh://root@スレーブ1のグローバルIP:/var/vol01-slave config remote-gsyncd /usr/libexec/glusterfs/gsyncd
gluster volume geo-replication vol01 ssh://root@スレーブ1のグローバルIP:/var/vol01-slave ssh-command ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i pemファイルパス
gluster volume geo-replication vol01 ssh://root@スレーブ1のグローバルIP:/var/vol01-slave start