EC2でGlusterFSを使ってみた
GlusterFSとは
GlusterFSとはオープンソースの分散ファイルシステムです。
複数のサーバ上の記憶領域を集約して、1つのファイルシステムとして扱うことができます。
例えば、10台のLinuxサーバから、それぞれ100GBのディスク領域をGlusterFS用に提供し、1つの1TBのストレージとして使用することができます。
今回は、GlusterFSクラスタ(GlusterFS3.3.2)をEC2上に構築し、簡単な動作確認をしてみました。
用語説明
実際の構築に入る前に、GlusterFSで使われる用語について簡単に説明しておきます。
Storage Pool
ストレージクラスタに参加するサーバ(ノード)の集まりです。GlusterFSにストレージを提供するサーバは、あらかじめStorage Poolに参加させておく必要があります。
Brick
個々のサーバ上のディレクトリで、GlusterFSにストレージとして提供されるものです。
GlusterFSの分散ファイルシステム(Volume)に保存されたファイルは、物理的にはBrick上に保存されます。
Volume
Brickを論理的に集約したもので、1つのストレージとして扱うことができます。ストレージを使う側は、このVolumeをマウントして利用することになります。GlusterFSの運用はVolumeの操作に関するものがほとんどです。
Volumeタイプ
Volumeには3つのタイプ(Distributed Volume、Replicated Volume、Striped Volume)があり、Volumeを作成するとき選択できます。タイプごとにファイルの保存のされ方が異なります。
Distributed Volume(分散ボリューム)
Distributed Volumeの場合、ファイルはVolumeを構成するBrickのいずれか一つに保存されます。Volumeの容量はBrickの容量の合計になるため、大容量のストレージを利用したい場合に向いています。ただし、Brickに障害が発生した場合、そのBrickに保存されていたファイルにはアクセスできなくなります。下の図の場合、ノード3が障害で停止した場合、ファイル3の情報は失われてしまいます。
Replicated Volume(複製ボリューム)
Replicated Volumeの場合、ファイルは指定したレプリカ数分のBrickに重複して保存されます。Volumeの容量はBrick容量の合計をレプリカ数で割ったものになります。Brickに障害が発生しても他のBrickにある複製されたファイルを利用できるため、可用性や耐久性が重要な場合に適しています。
下図はレプリカ数3のReplicated Volumeです。2つのBrickに障害が発生してもファイルは失われません。
Striped Volume
Striped Volumeの場合、ファイルは分割され(デフォルトだと128KB)、指定したストライプ数分のBrickに分散して保存されます。Volumeの容量はBrickの容量の合計になります。複数のBrickを並行して利用できるため、巨大なファイルに頻繁にアクセスする場合に向いていますが、一つでもBrickに障害が発生すると、ファイルにアクセスできなくなります。
下図はストライプ数3のStriped Volumeです。一つでもノードが失われるとファイル1、ファイル2いずれもアクセスできなくなります。
今回の検証内容
2台のEC2インスタンスからなるGlusterFSクラスタ上にDistributed Volumeを一つ作成し、別のEC2インスタンスからマウントします。
マウント後、ファイルがどのように保存されるか確認し、最後にノードに障害が発生した場合の挙動について見ていきます。
構築手順
構成
まず、GlusterFS用のEC2インスタンス2台とクライアント用EC2インスタンス1台を用意しましょう。
- クライアント用インスタンス(1台)
- AMI: Amazon Linux AMI 2013.09
- セキュリティグループ
- base(0.0.0.0/0からの22/TCPを許可)
- glusterfs-clients(空)
- GlusterFS用インスタンス(2台)
- AMI: Amazon Linux AMI 2013.09
- セキュリティグループ
- base(22/TCPを許可)
- glusterfs-nodes(glusterfs-clientsからの111/TCP, 24007-24010/TCP, 38465-38468/TCPを許可。glusterfs-nodesからの24007-24010/TCPを許可※)
- 追加EBS: 5GB(Brick用)
※24007以降のポートはGlusterFSのVolume管理とクライアント-Brick間の通信に利用します。Brick1つにつき1つのポートを利用するので、24007〜(24008 + 使用する最大ブリック数)のポートが必要です。今回は2Brick使うので24010までオープンしています。実際に利用するときには多め(100ポートとか)にオープンしておくことをお勧めします。111/TCPと38465〜38468/TCPはGlusterFSのVolumeにNFS接続するときに利用します。今回はNFSでは接続しないので必要ないのですが、一応オープンしています。
パッケージのインストール
EC2インスタンスが立ち上がったら、SSHでログインし、クラスタを作っていきます。
以下の作業はGlusterFS用インスタンス全て(今回は2台)で行ってください。
rootユーザで作業します。
[ec2-user@node01 ~]$ sudo su - [root@node01 ~]#
GlusterFS用yumレポジトリを登録し、レポジトリ情報を一部修正します。
Amazon Linuxでは$releaseverの値が「latest」なのですが、
[ec2-user@node01 ~]$ grep releasever /etc/yum.conf cachedir=/var/cache/yum/$basearch/$releasever releasever=latest
GlusterFSのサイトには該当するレポジトリがないため、$releaseverの部分を「6」に変更します。(最初から設置してある/etc/yum.repos.d/epel.repoで「6」を指定しているのでそれに合わせています。)
[root@node01 ~]# curl -o /etc/yum.repos.d/glusterfs-epel.repo http://download.gluster.org/pub/gluster/glusterfs/3.3/LATEST/EPEL.repo/glusterfs-epel.repo [root@node01 ~]# vim /etc/yum.repos.d/glusterfs-epel.repo # Place this file in your /etc/yum.repos.d/ directory [glusterfs-epel] name=GlusterFS is a clustered file-system capable of scaling to several petabytes. #baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.3/3.3.2/EPEL.repo/epel-$releasever/$basearch/ baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.3/3.3.2/EPEL.repo/epel-6/$basearch/ enabled=1 skip_if_unavailable=1 gpgcheck=0 [glusterfs-swift-epel] name=GlusterFS is a clustered file-system capable of scaling to several petabytes. #baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.3/3.3.2/EPEL.repo/epel-$releasever/noarch baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.3/3.3.2/EPEL.repo/epel-6/noarch enabled=1 skip_if_unavailable=1 gpgcheck=0 [glusterfs-source-epel] name=GlusterFS is a clustered file-system capable of scaling to several petabytes. - Source #baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.3/3.3.2/EPEL.repo/epel-$releasever/SRPMS baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.3/3.3.2/EPEL.repo/epel-6/SRPMS enabled=0 skip_if_unavailable=1 gpgcheck=0
変更したらglusterfs-serverパッケージをインストールしてください。
[root@node01 ~]# yum install -y glusterfs-server (出力略)
ちょっと脇道にそれますが、/var/lib/glusterd/glusterd.infoというファイルの中身を見てみてください。
[root@node01 ~]# cat /var/lib/glusterd/glusterd.info UUID=161832ab-17e3-4f60-8594-209c561cbab2
これはノードのユニークなIDを表しており、パッケージインストール時に付与されます。ですので、パッケージインストール後にAMIを作成し、それをもとにノード群(Storage Pool)を作ろうとすると、IDが重複してしまい、正常に動作しないので、注意してください。
クラスタを管理するglusterdプロセスを立ち上げましょう。
[root@node01 ~]# chkconfig glusterd on [root@node01 ~]# service glusterd start Starting glusterd: [ OK ]
Brickの作成
次に、Brick用のディレクトリを作成します。
今回、追加のEBSは/dev/xvdbにアタッチされているので、ext4でフォーマットします。inodeサイズは512バイトにする必要があります。
[root@node01 ~]# mkfs.ext4 -I 512 /dev/xvdb (出力略)
フォーマットが終わったら、適当なディレクトリを作成し、マウントしましょう。インスタンス起動時に自動でマウントされるようにfstabにも追記しておきます。
[root@node01 ~]# mkdir -p /bricks/vol01/ [root@node01 ~]# mount /dev/xvdb /bricks/vol01/ [root@node01 ~]# echo '/dev/xvdb /bricks/vol01 ext4 defaults,noatime 1 1' >> /etc/fstab [root@node01 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 7.9G 977M 6.9G 13% / tmpfs 298M 0 298M 0% /dev/shm /dev/xvdb 4.9G 138M 4.5G 3% /bricks/vol01
これで、Brickの準備まで終わりました。
クラスタを作るため、もう一台のインスタンスnode02も同じ状態にします。
[root@node02 ~]# service glusterd status glusterd (pid 1440) is running... [root@node02 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 7.9G 977M 6.9G 13% / tmpfs 298M 0 298M 0% /dev/shm /dev/xvdb 4.9G 138M 4.5G 3% /bricks/vol01
GlusterFSクラスタの構築
もう一台の準備が終わったら、クラスタを構成していきましょう。
今回のGlusterFS用インスタンスのホスト名のプライベートIPアドレスは以下の通りです。
node01: 172.16.101.11
node02: 172.16.102.11
GlusterFSのノードにはマスタやスレイブといった役割の違いはないので、以下の作業はいずれか1つのインスタンスで行えばOKです。今回はnode01で行います。
まず、glusterコマンドで対話モードに入ります。
[root@node01 ~]# gluster gluster>
最初に、Storage Poolにノードを登録します。自分自身(node01)は最初から登録されているので、自分以外のノード、node02登録します。
peer probe <<追加したいノードのホスト名またはIPアドレス>>
で登録できます。
gluster> peer status No peers present gluster> peer probe 172.16.102.11 Probe successful gluster> peer status Number of Peers: 1 Hostname: 172.16.102.11 Uuid: d11e714d-f8bd-43f9-89d0-3f42df82cd9d State: Peer in Cluster (Connected)
ノード数2のStorage Poolができていることが確認できました。
次に、Volumeを作成します。
Distributed Volumeの場合
volume create <<Volume名>> <<ノードのホスト名またはIPアドレス>>:<<Brickのパス>> <<ノードのホスト名またはIPアドレス>>:<<Brickのパス>> ....
で作成できます。Brickは必要な数だけ指定してください。今回は2つです。Volume名はvol01にします。
gluster> volume info No volumes present gluster> volume create vol01 172.16.101.11:/bricks/vol01 172.16.102.11:/bricks/vol01 Creation of volume vol01 has been successful. Please start the volume to access data. gluster> volume info Volume Name: vol01 Type: Distribute Volume ID: 58378596-bbfa-475f-b37d-dda4c63edc3c Status: Created Number of Bricks: 2 Transport-type: tcp Bricks: Brick1: 172.16.101.11:/bricks/vol01 Brick2: 172.16.102.11:/bricks/vol01
node01とnode02の/bricks/vol01でVolumeが作られているのが確認できました。
Volumeを利用するには起動させる必要があります。
起動方法は
volume start <<Volume名>>
です。
gluster> volume status vol01 Volume vol01 is not started gluster> volume start vol01 Starting volume vol01 has been successful gluster> volume status Status of volume: vol01 Gluster process Port Online Pid ------------------------------------------------------------------------------ Brick 172.16.101.11:/bricks/vol01 24009 Y 17716 Brick 172.16.102.11:/bricks/vol01 24009 Y 1500 NFS Server on localhost 38467 Y 17722 NFS Server on 172.16.102.11 38467 Y 1506
これで、Volumeが利用できるようになったので、クライアントインスタンスから接続してみましょう。
Volumeへの接続
接続方法はNFS、CIFS、GlusterFSのNativeクライアントから選べます。今回はNativeクライアントで接続してみましょう。
クライアントパッケージglusterfs, glusterfs-fuseを導入してください。
[ec2-user@client01 ~]$ sudo su - [root@node01 ~]# [root@client01 ~]# curl -o /etc/yum.repos.d/glusterfs-epel.repo http://download.gluster.org/pub/gluster/glusterfs/3.3/LATEST/EPEL.repo/glusterfs-epel.repo [root@client01 ~]# vim /etc/yum.repos.d/glusterfs-epel.repo (略) [root@client01 ~]# yum install -y glusterfs glusterfs-fuse (出力略)
適当なディレクトリを作成し、マウントしてみましょう。
マウントタイプはglusterfs、マウント先は「ホスト名(またはIPアドレス):/(Volume名)」です。BrickのパスではなくVolume名を指定する点に注意してください。
[root@client01 ~]# mkdir -p /glusterfs/vol01 [root@client01 ~]# mount -t glusterfs 172.16.101.11:/vol01 /glusterfs/vol01/ [root@client01 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 7.9G 975M 6.9G 13% / tmpfs 298M 0 298M 0% /dev/shm 172.16.101.11:/vol01 9.7G 277M 9.0G 3% /glusterfs/vol01
Volumeサイズは5GB + 5GBで約10GBになっています。
動作確認
実際にファイルをいくつか作成してみましょう。
[root@client01 ~]# touch /glusterfs/vol01/{01..10} [root@client01 ~]# ls /glusterfs/vol01/ 01 02 03 04 05 06 07 08 09 10 lost+found
無事作成できました。
各Brickの中身を見てみると、ファイル03, 04, 05がnode01に、それ以外がnode02分散して保存されていることがわかります。
node01
[root@node01 ~]# ls /bricks/vol01/ 03 04 05 lost+found
node02
[root@node02 ~]# ls /bricks/vol01/ 01 02 06 07 08 09 10 lost+found
node01に障害が起きたと仮定して、停止させてみましょう。
[root@node01 ~]# shutdown -h now
node02からクラスタ情報をみると、
[root@node02 ~]# gluster gluster> peer status Number of Peers: 1 Hostname: 172.16.101.11 Uuid: 161832ab-17e3-4f60-8594-209c561cbab2 State: Peer in Cluster (Disconnected) gluster> volume info vol01 Volume Name: vol01 Type: Distribute Volume ID: 58378596-bbfa-475f-b37d-dda4c63edc3c Status: Started Number of Bricks: 2 Transport-type: tcp Bricks: Brick1: 172.16.101.11:/bricks/vol01 Brick2: 172.16.102.11:/bricks/vol01 gluster> volume status vol01 Status of volume: vol01 Gluster process Port Online Pid ------------------------------------------------------------------------------ Brick 172.16.102.11:/bricks/vol01 24009 Y 1500 NFS Server on localhost 38467 Y 1506
node01(172.16.101.11)はStorage Poolに所属しているがDisconnectedであること、VolumeにBrickを提供しているが、Onlineでないことが確認できます。
クライアント側からみると
[root@client01 ~]# ls /glusterfs/vol01/ 01 02 06 07 08 09 10 lost+found
node01側に保存されていたファイルだけ消えました。 ここで注意していただきたいのは、先ほどVolumeをマウントするとき、node01を指定してマウントしたにもかかわらず、node01停止後もVolumeが利用できる点です。node02に保存されているファイルには正常にアクセスできます。Nativeクライアントは各ノード上のBrickと直接通信しているので、マウント先が停止しても正常にVolumeへのアクセスを続けることができます。
試しに、クライアントで接続情報をみてみると
[root@client01 ~]# netstat -anp|grep gluster tcp 0 1 172.16.1.11:1022 172.16.101.11:24009 SYN_SENT 1442/glusterfs tcp 0 1 172.16.1.11:1023 172.16.101.11:24007 SYN_SENT 1442/glusterfs tcp 0 0 172.16.1.11:1019 172.16.102.11:24009 ESTABLISHED 1442/glusterfs unix 2 [ ] DGRAM 8045 1442/glusterfs
Nativeクライアントと各Brickが直接通信していることがわかります。
ただし、これはNativeクライアントで接続した場合のみであり、NFSやCIFSで接続した場合はマウント先のノードが停止するとVolumeにアクセスできなくなります。
では、node01を再び起動し、glusterdプロセスを起動させましょう。
[root@client01 ~]# ls /glusterfs/vol01/ 01 02 03 04 05 06 07 08 09 10 lost+found
元に戻りました。
以上、GlusterFSクラスタを構築し、簡単な動作確認をして見ましたが、分散システムにしてはかなり取っ付きやすかったです。また、メタ情報を管理するサーバが必要ないため、運用もしやすいと思います。
今回はVolumeの作成まででしたが、次回以降、Volumeの構成変更や他のタイプのVolumeについて書いてみたいと思います。