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に公開したので必要に応じて利用してほしい。

次にこの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

関連資料・記事

参考サイト