GlusterFS
2016/1/1更新
対応バージョン: 3.7.6
CentOS 7にGlusterFSを導入する手順を示す。
GlusterFSのボリュームの構成方式には以下の3種類があるが、導入手順は同じなのでDistributeを基本に他の2方式についても必要に応じて説明する。
Distribute(分散配置)
デフォルトの構成方式。
ボリュームを構成するBrickのどれかにファイルを配置する。
あるBrickが故障するとそのBrickに格納されていたファイルが失われる。
Stripe(ストライピング)
ファイルをストライプサイズに分割してBrickに均等配置する。いわゆる「RAID 0」。
あるBrickが故障するとボリューム全体が使用不能になる。
Replica(ミラーリング)
ファイルを全てのBrickに複製配置する。いわゆる「RAID 1」。
あるBrickが故障してもファイルは失われない。
この中でDistributeとStripeは拡張性が高い反面、耐障害性が低いので実際にはReplicaと組み合わせて使うことで可用性を高めることができる。複数の構成の組み合わせについてはここでは扱わない。
導入環境作成
導入環境としてVagrantを使用してホストOS上にCentOS 7の仮想サーバを3つ作り、それぞれに10GBのストレージを接続してGlusterFSのBrickとして使用する。
CentOS 7のBoxイメージは以下の記事にてVagrant Cloudに公開したものを使用する。
関連資料・記事
手順としてはまず1台の仮想サーバにGlusterFSをインストールしてBrick用ストレージを追加したものをBox化し、3サーバのベースとする。
Vagrantfile
スクリプトを2つ用意してGlusterFSのインストールとBrick用ストレージの設定を行う(スクリプトの内容は後述)。
10GBのストレージを追加する。
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure(2) do |config| config.vm.box = "kogurek1/centos72_64_min" config.vm.provision :shell, :path => "01_install_glusterfs.sh" config.vm.provision :shell, :path => "02_setup_ext_hdd.sh" config.vm.provider :virtualbox do |vb| file_to_disk = "ext1.vdi" if not File.exist?(file_to_disk) then vb.customize ["createhd", "--filename", file_to_disk, "--size", 10 * 1024] end vb.customize ['storageattach', :id, '--storagectl', 'SATA', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', file_to_disk] end end
01_install_glusterfs.sh
GlusterFSをインストールする。
#!/bin/bash cd /etc/yum.repos.d wget http://download.gluster.org/pub/gluster/glusterfs/LATEST/EPEL.repo/glusterfs-epel.repo yum -y install ftp://ftp.muug.mb.ca/mirror/fedora/epel/7/x86_64/u/userspace-rcu-0.7.16-1.el7.x86_64.rpm yum -y install glusterfs-server glusterfs-fuse yum clean all systemctl start glusterd systemctl enable glusterd
02_setup_ext_hdd.sh
Brick用ストレージをパーティショニングしてXFSとし、/shareにマウントする。Brick管理ディレクトリは/share/gfsとする。
#!/bin/bash # partitioning parted -s /dev/sdb 'mklabel msdos' parted -s /dev/sdb 'mkpart primary 2048s -0' # make filesystem mkfs.xfs -f /dev/sdb1 # mount filesystem echo "/dev/sdb1 /share xfs defaults 0 0" >> /etc/fstab mkdir /share mount /share mkdir /share/gfs
上記の3ファイルを作ってvagrant upで仮想サーバを作り、Box化する。
% vagrant up % vagrant package % vagrant box add centos72_64_min_gfs package.box
このBoxはVagrant Cloudに公開したので必要に応じて利用してほしい。
https://atlas.hashicorp.com/kogurek1/
次にこのBoxを使って3つの仮想サーバを作成する。
192.168.33.11
192.168.33.12
192.168.33.13
仮想サーバ同士が通信できるようにアダプタ2をホストオンリーアダプタとし、それぞれにIPアドレスを付与する。
Vagrantfile
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure(2) do |config| # common config.vm.box = "centos72_64_min_gfs" # guest #1 config.vm.define :gfs1 do |v| v.vm.hostname = "gfs1" v.vm.network "private_network", ip: "192.168.33.11" end # guest #2 config.vm.define :gfs2 do |v| v.vm.hostname = "gfs2" v.vm.network "private_network", ip: "192.168.33.12" end # guest #3 config.vm.define :gfs3 do |v| v.vm.hostname = "gfs3" v.vm.network "private_network", ip: "192.168.33.13" end end
vagrant upにて3つの仮想サーバを作成する。以降このサーバにログインして各種作業を行っていく。
% vagrant up % vagrant status Current machine states: gfs1 running (virtualbox) gfs2 running (virtualbox) gfs3 running (virtualbox) :
GlusterFS設定
ボリューム全体に関わる作業はどこか1台のサーバで実施すればよいのでサーバ#1(gfs1)にて行う。一部、マウントポイント作成などの作業は各サーバで実施する。
trusted storage pool作成
まずボリュームを構成するサーバを信頼関係で結び、trusted storage poolを作成する。
[gfs1]# gluster peer probe 192.168.33.12 [gfs1]# gluster peer probe 192.168.33.13 [gfs1]# gluster peer status Number of Peers: 2 Hostname: 192.168.33.12 Uuid: 7118ac16-764e-4de8-931a-5b90269b7348 State: Peer in Cluster (Connected) Hostname: 192.168.33.13 Uuid: f04e85c4-443e-4d78-9065-c15e357ccb2a State: Peer in Cluster (Connected)
ボリューム作成
各サーバ上に用意した/share/gfsを結びつけてボリュームを作成する。ボリュームの構成方式はデフォルトのDistributeとする。残りの2方式については後述する。
[gfs1]# gluster volume create gfs \ 192.168.33.11:/share/gfs \ 192.168.33.12:/share/gfs \ 192.168.33.13:/share/gfs volume create: gfs: success: please start the volume to access data
ボリュームが作成されたら使用開始し、NFSをいったん使用不可とする。
[gfs1]# gluster volume start gfs [gfs1]# gluster volume set gfs nfs.disable true [gfs1]# gluster volume get gfs nfs.disable Option Value ------ ----- nfs.disable true [gfs1]# gluster volume info gfs Volume Name: gfs Type: Distribute Volume ID: 1454ca36-6c3b-4906-8619-af74d5af3673 Status: Started Number of Bricks: 3 Transport-type: tcp Bricks: Brick1: 192.168.33.11:/share/gfs Brick2: 192.168.33.12:/share/gfs Brick3: 192.168.33.13:/share/gfs Options Reconfigured: nfs.disable: true performance.readdir-ahead: on [gfs1]# gluster volume status Status of volume: gfs Gluster process TCP Port RDMA Port Online Pid -------------------------------------------------------------------- Brick 192.168.33.11:/share/gfs 49152 0 Y 11214 Brick 192.168.33.12:/share/gfs 49152 0 Y 11287 Brick 192.168.33.13:/share/gfs 49152 0 Y 11267 Task Status of Volume gfs -------------------------------------------------------------------- There are no active volume tasks
(*) NFSを使用可能なままにしておくとログファイル(/var/log/glusterfs/etc-glusterfs-glusterd.vol.log)にエラーを出力し続ける。
[2015-12-31 19:43:09.627638] W [socket.c:588:__socket_rwv] 0-nfs: readv on /var/run/gluster/968e6f601f8686fb47b8decacbf2af9d.socket failed (無効な引数です) [2015-12-31 19:43:12.628080] W [socket.c:588:__socket_rwv] 0-nfs: readv on /var/run/gluster/968e6f601f8686fb47b8decacbf2af9d.socket failed (無効な引数です) [2015-12-31 19:43:15.628514] W [socket.c:588:__socket_rwv] 0-nfs: readv on /var/run/gluster/968e6f601f8686fb47b8decacbf2af9d.socket failed (無効な引数です) :
ボリュームが使用可能になったらFUSEでマウントする。これは各サーバで行う。構成方式がDistributeなのでサイズが10G x 3 = 30Gになっているのが確認できる。Stripeも同様に6G、Replicaはミラーリングなので10Gとなる。
# mkdir /mnt/gfs # mount -t glusterfs localhost:gfs /mnt/gfs # df -h /mnt/gfs ファイルシス サイズ 使用 残り 使用% マウント位置 localhost:gfs 30G 97M 30G 1% /mnt/gfs
これでどのサーバからでも同じボリュームが利用できる。10個のファイルを書き込んでみてどのBrickに格納されるかを確認してみる。
# cd /mnt/gfs # for i in `seq -w 1 10`; do touch file$i; done
FUSEでマウントしたディレクトリには10個が存在しているように見えるが、実際には各サーバ上に分散されて格納されていることがわかる。
# ls -l /mnt/gfs 合計 0 -rw-r--r-- 1 root root 0 12月 31 21:36 file01 -rw-r--r-- 1 root root 0 12月 31 21:36 file02 -rw-r--r-- 1 root root 0 12月 31 21:36 file03 -rw-r--r-- 1 root root 0 12月 31 21:36 file04 -rw-r--r-- 1 root root 0 12月 31 21:36 file05 -rw-r--r-- 1 root root 0 12月 31 21:36 file06 -rw-r--r-- 1 root root 0 12月 31 21:36 file07 -rw-r--r-- 1 root root 0 12月 31 21:36 file08 -rw-r--r-- 1 root root 0 12月 31 21:36 file09 -rw-r--r-- 1 root root 0 12月 31 21:36 file10
#1
[gfs1]# ls -l /share/gfs 合計 0 -rw-r--r-- 2 root root 0 12月 31 21:36 file01
#2
[gfs2]# ls -l /share/gfs 合計 0 -rw-r--r-- 2 root root 0 12月 31 21:36 file02 -rw-r--r-- 2 root root 0 12月 31 21:36 file04 -rw-r--r-- 2 root root 0 12月 31 21:36 file05 -rw-r--r-- 2 root root 0 12月 31 21:36 file07 -rw-r--r-- 2 root root 0 12月 31 21:36 file08 -rw-r--r-- 2 root root 0 12月 31 21:36 file10
#3
[gfs3]# ls -l /share/gfs 合計 0 -rw-r--r-- 2 root root 0 12月 31 21:36 file03 -rw-r--r-- 2 root root 0 12月 31 21:36 file06 -rw-r--r-- 2 root root 0 12月 31 21:36 file09
Stripeボリューム、Replicaボリューム作成
先のDistributeボリューム同様、この2つのボリュームもgluster volume createコマンド実行時のオプションが変わるだけなのでその部分を説明する。
Stripeボリューム
stripeオプションに続いてストライプを構成するBrickの個数を指定する。
[gfs1]# gluster volume create gfs stripe 3 \ 192.168.33.11:/share/gfs \ 192.168.33.12:/share/gfs \ 192.168.33.13:/share/gfs
Stripeボリュームの場合、以下のようにファイルが分割されて各Brickに均等配置される。
[gfs1]# cd /mnt/gfs [gfs1]# dd if=/dev/zero of=file bs=1M count=100 [gfs1]# ls -l /mnt/gfs 合計 102400 -rw-r--r-- 1 root root 104857600 12月 31 22:02 file
#1
[gfs1]# ls -l /share/gfs 合計 34180 -rw-r--r-- 2 root root 34996224 12月 31 22:02 file
#2
[gfs2]# ls -l /share/gfs 合計 34180 -rw-r--r-- 2 root root 34996224 12月 31 22:02 file
#3
[gfs3]# ls -l /share/gfs 合計 34052 -rw-r--r-- 2 root root 34865152 12月 31 22:02 file
3つの分割されたファイルのサイズを合計すると作成したファイルのサイズとなる。
34996224 + 34996224 + 34865152 = 104857600
Replicaボリューム
replicaオプションに続いてレプリカを構成するBrickの個数を指定する。
[gfs1]# gluster volume create gfs replica 3 \ 192.168.33.11:/share/gfs \ 192.168.33.12:/share/gfs \ 192.168.33.13:/share/gfs
Replicaボリュームの場合は単純に全てのBrickに同じファイルが配置される。
[gfs1]# cd /mnt/gfs [gfs1]# dd if=/dev/zero of=file bs=1M count=100 [gfs1]# ls -l /mnt/gfs 合計 102400 -rw-r--r-- 1 root root 104857600 12月 31 22:14 file
#1
[gfs1]# ls -l /share/gfs 合計 102400 -rw-r--r-- 1 root root 104857600 12月 31 22:14 file
#2
[gfs2]# ls -l /share/gfs 合計 102400 -rw-r--r-- 1 root root 104857600 12月 31 22:14 file
#3
[gfs3]# ls -l /share/gfs 合計 102400 -rw-r--r-- 1 root root 104857600 12月 31 22:14 file
ボリューム再利用設定
一度作成したボリュームを再度別の目的に使用する場合、ボリュームを停止するだけでなく管理情報も削除する必要があるので説明する。
FUSE umount
まず各サーバでボリュームをumountする。
# umount /mnt/gfs
ボリューム停止 & 削除
次にそのボリュームを停止し、削除する。
[gfs1]# gluster volume stop gfs Stopping volume will make its data inaccessible. Do you want to continue? (y/n) <--- y [gfs1]# gluster volume delete gfs Deleting volume will erase all information about the volume. Do you want to continue? (y/n) <--- y
拡張属性削除
Brick管理対象ディレクトリに設定された拡張属性を削除する。これは各サーバで実行する。
# attr -l /share/gfs Attribute "glusterfs.volume-id" has a 16 byte value for /share/gfs Attribute "gfid" has a 16 byte value for /share/gfs Attribute "glusterfs.dht" has a 16 byte value for /share/gfs # setfattr -x trusted.glusterfs.dht /share/gfs # setfattr -x trusted.glusterfs.volume-id /share/gfs # setfattr -x trusted.gfid /share/gfs
これで基本的にボリュームが再利用可能になるが、まだ以下のようなエラーになる場合がある。
[gfs1]# gluster volume create gfs \ 192.168.33.11:/share/gfs \ 192.168.33.12:/share/gfs \ 192.168.33.13:/share/gfs volume create: gfs: failed: /share/gfs is already part of a volume
この場合は各サーバの/share/gfs配下の管理領域も削除する。
# rm -rf /share/gfs/.glusterfs
関連資料・記事
参考サイト
分散ファイルシステムのGlusterFS:こんなとき、どうなる (日経ITpro)
GlusterFS Community ではじめる分散ファイルシステム (インフラ本舗)
GlusterFS技術情報 (Googleサイト)
GlusterFS技術情報 (Qiita)
Vagrant技術情報 (Qiita)
VirtualBox技術情報 (Qiita)