GMOアプリクラウドでCentOS6.5+S3QLでSwift Object Storageをマウントする

この記事は [Gohko Naoto](http://qiita.com/naoto_gohko) さんの以下の記事を参考にしています。
> ConoHaのVMでUbuntu 14.04を使ってs3qlでSwift Object Storageをマウントする
> http://qiita.com/naoto_gohko/items/e8b662ae9e19fc1c859a

オブジェクトストレージはファイルサーバーとして便利ですが、そのままではサーバーからファイルシステムとして直接マウントできません。そこで、それを可能にするObjectStorageGatewayを利用して容量無制限のストレージを使おうという内容です。

ObjectStorageGatewayとしてはs3fsなどが有名ですが、S3QLの特徴として、

- Large file（1ファイル2TBまで）をサポート
- GZIPをベースにしたディスク圧縮機能
- データ重複削除機能
- 書き込み／読み取りのロック機能
- 書き込み／読み込みキャッシュ

等があります。
特に読み書きキャッシュは、オブジェクトストレージの速度面の弱点を解決できる実装で、かなり実用的だと思います。
さらにGMOアプリクラウドのVMのroot領域はSSDなので、擬似的に高速なストレージとして使えます。

利用者が多いと思われるCentOSとOpenStack Swiftでの例があまり見つからなかったので書きました。

手順の流れとしては以下のとおりです。既にPython3.3・SQLite3.7以上がインストールされている方は飛ばして読んでください。

- ビルド・マウントに必要なパッケージをインストール
- Python3.3をインストール
- SQLite3.9をインストール
- コンテナ作成
- S3QLインストール

#ビルド・マウントに必要なパッケージをインストール#
CentOSのリポジトリからインストールします。

```lang:shell
# yum install fuse fuse-libs fuse-devel libattr-devel gcc gcc-c++ kernel-devel libxslt-devel
```
##fuseモジュールを読み込み##
```lang:shell
# modprobe fuse
```

#python3.3インストール#
標準リポジトリには存在しないため、PUIASからインストールします。

```lang:shell
# cd /etc/pki/rpm-gpg/
# wget -q http://springdale.math.ias.edu/data/puias/6/x86_64/os/RPM-GPG-KEY-puias
# rpm --import RPM-GPG-KEY-puias
# cat <<EOF >> /etc/yum.repos.d/puias-computational.repo
> [PUIAS_6_computational]
> name=PUIAS Computational Base
> mirrorlist=http://puias.math.ias.edu/data/puias/computational/\$releasever/\$basearch/mirrorlist
> gpgcheck=1
> gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puias
> EOF
# yum install python3 python3-devel python3-libs python3-setuptools
```

##Pythonのパッケージ管理ツールpipのインストール##
setuptoolsも一緒にインストールされます。

```lang:shell
# wget -O - https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python3

# pip -V
pip 7.1.2 from /usr/lib/python3.3/site-packages (python 3.3)

# pip list
pip (7.1.2)
setuptools (18.8.1)
wheel (0.26.0)
```

##Pythonモジュールをインストール##
Pythonのeasy_install機能を使ってインストールします。

```lang:shell
# easy_install-3.3 -U pycrypto
# easy_install-3.3 -U defusedxml
# easy_install-3.3 -U requests
# easy_install-3.3 -U llfuse
# easy_install-3.3 -U dugong
```

pipを使っても良いです。

```lang:shell
# pip install pycrypto
# pip install defusedxml
# pip install requests
# pip install llfuse
# pip install dugong
```

#SQLite3.9インストール#
こちらも標準リポジトリにはないため、SQLite本家から取得してコンパイルします。
CentOS標準のSQLiteとバッティングしないよう、インストール場所を「/usr/local/sqlite-3.9」に指定します。

```lang:shell
# cd /usr/local/src/
# wget -q https://www.sqlite.org/2015/sqlite-autoconf-3090200.tar.gz
# tar zxf sqlite-autoconf-3090200.tar.gz
# cd sqlite-autoconf-3090200
# ./configure --prefix=/usr/local/sqlite-3.9
# make
# make install
# echo "/usr/local/sqlite-3.9/lib" > /etc/ld.so.conf.d/sqlite.conf
# ldconfig
```

##APSWをインストール##
インストールしたSQLiteに対応するバージョンをインストールします。

```lang:shell
# cd /usr/local/src/
# wget -q https://github.com/rogerbinns/apsw/releases/download/3.9.2-r1/apsw-3.9.2-r1.zip
# unzip apsw-3.9.2-r1.zip
# cd apsw-3.9.2-r1
```

セットアップファイルを編集します。include_dirs と library_dirs の値を変更します。

```lang:shell
# cp -p setup.py setup.py.org
# vi setup.py
```

（一部抜粋）

```bash
from distutils.core import setup, Extension, Command
from distutils.command import build_ext, build, sdist

##
## Do your customizations here or by creating a setup.cfg as documented at
## http://www.python.org/doc/2.5.2/dist/setup-config.html
##

include_dirs=['src','/usr/local/sqlite-3.9/include']
library_dirs=['/usr/local/sqlite-3.9/lib']
define_macros=[]
libraries=[]

# This includes the functionality marked as experimental in SQLite 3.
# Comment out the line to exclude them
define_macros.append( ('EXPERIMENTAL', '1') )

##
## End of customizations
##
```

編集後、インストールを実行

```lang:shell
# python3 setup.py install
```

##S3QL 導入前の確認##
今までの作業の結果、インストールしたモジュール等を確認すると以下のようになります。

```lang:shell
# pip list
apsw (3.9.2.post1)
defusedxml (0.4.1)
dugong (3.5)
llfuse (0.41.1)
pip (7.1.2)
pycrypto (2.6.1)
requests (2.8.1)
setuptools (18.8.1)
wheel (0.26.0)
```

#コンテナ作成#
事前にクライアントソフトでオブジェクトストレージに接続し、コンテナを作成してください。今回は「obj」という名前で作成しました。
また、リージョン名もクライアントソフトで確認します。今回は「tokyo-2」でした。
クライアントソフトについては以下を参照してください。ここでは割愛します。
[オブジェクトストレージリファレンス](http://cloud.gmo.jp/docs/objectstorage/)

#S3QLインストール#
S3QLのサイトから最新版を取得してインストールします。

```lang:shell
# cd /usr/local/src/
# wget -q https://bitbucket.org/nikratio/s3ql/downloads/s3ql-2.15.tar.bz2
# tar jxf s3ql-2.15.tar.bz2
# cd s3ql-2.15
# python3 setup.py build_ext --include-dirs='/usr/local/sqlite-3.9/include' --library-dirs='/usr/local/sqlite-3.9/lib' --inplace
# python3 setup.py install
```
##S3QL設定ファイル作成##
コントロールパネル内のAPI情報等を参照の上、作成してください。

```lang:shell
# mkdir /root/.s3ql/
# vi /root/.s3ql/authinfo2
```

```bush
[swift]
backend-login: (テナント名):(コントロールパネルログインID)
backend-password: (コントロールパネルログインパスワード)
storage-url: swiftks://(identify Endpoint URL)/(Region):(コンテナ名)
```

今回は以下のようになります。

```bush
[swift]
backend-login: app****************:app*****
backend-password: hogehoge
storage-url: swiftks://ident-r2nd1001.app-sys.jp/tokyo-2:obj
```

セキュリティ上、パーミッションを変えておきます。

```lang:shell
# chmod 600 /root/.s3ql/authinfo2
```

##マウントポイント作成##
任意の名称のディレクトリを作成します。今回は「obj」とします。

```lang:shell
# mkdir /obj
```

#ファイルシステムとして初期化#
S3QLのコマンドを使って初期化します。
ちなみに --plain オプションを付けると暗号化なしになります。

```lang:shell
# mkfs.s3ql --plain --authfile /root/.s3ql/authinfo2 swiftks://ident-r2nd1001.app-sys.jp/tokyo-2:obj

Before using S3QL, make sure to read the user's guide, especially
the 'Important Rules to Avoid Loosing Data' section.
Creating metadata tables...
Dumping metadata...
Dumping metadata...
..objects..
..blocks..
..inodes..
..inode_blocks..
..symlink_targets..
..names..
..contents..
..ext_attributes..
Compressing and uploading metadata...
Wrote 115 bytes of compressed metadata.
Cycling metadata backups...
Backing up old metadata...
```

マウント

```lang:shell
# mount.s3ql --allow-other swiftks://ident-r2nd1001.app-sys.jp/tokyo-2:obj /obj/
```

正常にマウントされているか確認します。

```lang:shell
# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       26G  1.7G   23G   7% /
tmpfs                 939M     0  939M   0% /dev/shm
/dev/vda1             477M   81M  371M  18% /boot
/dev/vdb1              50G   52M   47G   1% /mnt
swiftks://ident-r2nd1001.app-sys.jp/tokyo-2:obj/
                      1.0T     0  1.0T   0% /obj
```

##自動起動##
再起動後も自動でマウントされるよう設定します。

```lang:shell
# chkconfig --add s3ql
```

以下のようなスクリプトを作成します。内容は任意で変更してください。

```lang:shell
# vi /etc/init.d/s3ql
```

```bash
#!/bin/bash
#
# description: S3QL Auto Mount
#
# Source function library.
. /etc/init.d/functions
#
AUTHFILE="/root/.s3ql/authinfo2"
BUCKET="swiftks://ident-r2nd1001.app-sys.jp/tokyo-2:obj"
MOUNTPOINT="/obj"
OPTIONS="--allow-other"
start() {
        echo -n $"Mounting S3QL: "
        mount | grep $MOUNTPOINT > /dev/null
        if [ $? -eq 0 ];then
                echo $"Cannot mount $MOUNTPOINT. Already mounted !!"
                echo
                exit 1
        fi
        echo
        fsck.s3ql --batch $BUCKET
        mount.s3ql $OPTIONS $BUCKET $MOUNTPOINT
        RETVAL=$?
        [ $RETVAL -eq 0 ] && success || failure
        echo
}
stop() {
        echo -n $"Unmounting S3QL: "
        mount | grep $MOUNTPOINT > /dev/null
        if [ $? -ne 0 ];then
                echo $"Already unmounted !!"
                echo
                exit 1
        fi
        umount.s3ql $MOUNTPOINT && success || failure
        echo
}
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    *)
        echo "Usage: `basename $0` {start|stop}"
        exit 1
        ;;
esac
```

作成したスクリプトに実行権限を付与して完了です。

```lang:shell
# chmod 755 /etc/init.d/s3ql
```

#その他#
アンマウントする場合

```lang:shell
# umount.s3ql /obj/
```

#備考#
- マウントした後、dfコマンドで1TBと表示されるのはLinuxの仕様のようです。実際は無制限です。
- ~/.s3ql/ ディレクトリにキャッシュされるので、ローカルディスクの速度が書き込み速度となります。
- S3QLはオブジェクトストレージ内に独自形式でファイルシステムを作る構造になっているため、S3QLを経由しないと保存されたファイル名や中身を参照することはできません。
- S3QLは複数サーバーからの同時アクセスをサポートしていませんが、S3QLのドキュメントでは1台でマウントした後、NFSやCIFSなどで共有してからアクセスする例が紹介されています。
- S3QLの詳細については以下ドキュメントをご参照ください。
- [http://www.rath.org/s3ql-docs/](http://www.rath.org/s3ql-docs/)
- [https://bitbucket.org/nikratio/s3ql/wiki/FAQ](https://bitbucket.org/nikratio/s3ql/wiki/FAQ)


#終わりに#
どちらかというとインストールとか事前準備が面倒です。公式レポジトリから入れられるようになればもう少し楽になると思います。
言わずもがな容量無制限ですが使った分はもちろん請求されます。ご利用は計画的に。