VPSでOpenStack Swiftを試してみる

OpenStack は VPS でも動かせる

ちょっとした理由で、 OpenStack を試してみようと思った。でも、物理サーバーとか用意したりするのだりーとか思ってたら、VPSでも動かせるということを知って、俄然やる気になった。

(ちなみに、自分の OpenStack の前提知識はゼロスタートなので、本文中におかしな部分とかがあれば、是非つっこみを)

調べたところ、とりあえず選択肢としてはこの辺らしい。

  • DevStack
  • PackStack

実は、最初に DevStack を試してみたけど、全然簡単じゃなかったので、とりあえずもう一つの PackStack を試してみた。

やりたいこと

あまり使っていないVPSが何台かあるので、それらをファイル置き場にしたい。

scp とかでも良かったんだけど、何か新しいことをしたいと思って、OpenStack Swift を使うことにした。

環境

  • CentOS 7.0
  • お名前.com の VPS、メモリ2G (!!)

そもそも、最初は CentOS 6.6 だったので、CentOS 7へのアップグレードを試みたけどうまくいかなかったので、CentOS 7.0 をクリーンインストールした。

事前準備

スワップ

OpenStack はメモリ4GB以上を推奨してたが、VPS なのでメモリのアップグレードとかは出来ない。仕方ないので、スワップを多目に持たせておく。CentOS 7 をデフォルトの設定でインストールすると、スワップが 2GB だったので、スワップファイルを作成してスワップに追加した。

SELinux

見出しを見ただけで想像つくと思うけど、SELinux はオフにしておく。

ファイアウォール

沢山のプロセスが沢山のポートを使うので、最初はとりあえずファイアウォールを無効にしておくことをおすすめする。

CentOS 7 から、firewalld というのを使うようになっているので要注意。

RDOのインストール

CentOS の場合、RDO (※)というのを使って簡単に出来るらしいので、それをインストールする。

※ RDO というのは、コミュニティの名前でもあり、そのコミュニティが作っているOpenStack のデプロイ&管理ツールの名前でもあるらしい。分かりにくい。

まぁこのへんのドキュメントのとおりにやれば問題ないはず。いくつか気づいた点を書いておく。

  • CentOS 6 系だとStep 2で失敗する
  • Step 0 の ifdown を実行する意味がよく分からなかったので、実行しなかったが、とりあえず大丈夫そうだった。OpenStack 上で VM を立ち上げる場合に必要になってくるのかもしれないが。

ちなみに、最後のステップの以下のコマンドは、めっちゃ時間がかかった。

packstack --allinone

不要なものもインストールされる

この allinone では、使われないものも結構インストールされるので注意。今回の内容に関係しそうなところは個別に説明していく。

 Swiftの設定

こっからが試行錯誤しながらだったので結構時間がかかった。SAIO – Swift All In One というドキュメントを参考にしながら進めた。

いきなりだけど、”Installing dependencies” の部分は不要っぽいのでスキップ。

ストレージ用の領域の確保

次に、Swift が使うストレージ領域を確保する。それには2通りの方法がある。

  • パーティション(/dev/sdb1等)をそのまま使う
  • ループバックデバイスを使う

今回は前者でいくことにした。なお、packstack –allinone でループバックデバイスも作成されているみたいだが、ここでは使わない。

領域の確保の手順としては以下のとおり。

  • フォーマット (xfs が推奨?っぽい)
  • マウントポイントを fstab に追加
  • ディレクトリを色々作成

自分の場合は以下のようなコマンドを実行した。

$ sudo fdisk /dev/vdb
$ sudo mkfs.xfs /dev/vdb2
$ sudo mkdir /mnt/vdb2

fstabに以下を追加

/dev/vdb2 /mnt/vdb2 xfs noatime,nodiratime,nobarrier,logbufs=8 0 0

続いて以下のコマンドを実行。

for x in {1..4}; do sudo mkdir /mnt/vdb2/$x; done
sudo chown swift:swift /mnt/vdb2/*
for x in {1..4}; do sudo ln -s /mnt/vdb2/$x /srv/$x; done
sudo mkdir -p /srv/1/node/sdb1 /srv/1/node/sdb5 \
 /srv/2/node/sdb2 /srv/2/node/sdb6 \
 /srv/3/node/sdb3 /srv/3/node/sdb7 \
 /srv/4/node/sdb4 /srv/4/node/sdb8
# **Make sure to include the trailing slash after /srv/$x/**
for x in {1..4}; do sudo chown -R swift:swift /srv/$x/; done

 Common Post-Device Setup の項目

さっきの SAIO ドキュメントの Common Post-Device Setup の項は、packstack –allinone で既に実行されているものも多いので、適宜飛ばす。

  • Getting the code → 不要
  • Setting up rsync → とりあえずやっておいた
  • Starting memcached → 不要
  • Optional: Setting up rsyslog for individual logging → Optional なのでやらなかった
  • Configuring each node → 後述
  • Setting up scripts for running Swift → 後述

Configuring each node: 各ノードの設定

$HOME/swift/doc から設定ファイルのテンプレートを持ってくる、という部分はやらなかった。というか、そんなテンプレートはなかった。

次に、各設定ファイルの編集だが、以下の通り行った。

  • /etc/swift/swift.conf → 既存ファイルの末尾にコピペ。ただし、[storage-policy:2] の項目は飛ばした。理由は後述。
  • /etc/swift/proxy-server.conf → 既に存在していたので、触らず。
  • /etc/swift/object-expirer.conf 及び /etc/swift/container-reconciler.conf は飛ばした。飛ばした理由をあまり覚えていない・・・
  • /etc/swift/*/n.conf → IPアドレスとパーティションのパスを除いてそのまま使用。

<your user name> の部分は swift に置換する必要があるので、以下を実行。

find /etc/swift/ -name \*.conf | xargs sudo sed -i "s/<your-user-name>/swift/"

Setting up scripts for running Swift

さっきのページの 1〜6 は飛ばす。

7 の remakerings スクリプトの中身を手動で実行して、rings を作成した。コマンドの実行は、/etc/swift ディレクトリ内で行うこと(重要)。

なお、パラメーターを間違えて作ってしまった場合は、swift-ring-builder XXX create コマンドを正しいパラメーターで再実行すれば、再作成してくれるらしい。XXXの名前の部分を間違えてしまった場合、swift-ring-builder remove で削除出来るっぽい。

8〜15 もとばす。

設定完了!いざ起動へ

ここまででとりあえず設定は完了した。で、起動なんだけど、packstack –allinon コマンドで、既に自動起動設定がされているものも結構ある。OpenStack には色んなコンポーネントがあって、大量のプロセスが立ち上がっているのが分かるかと思う。

ここは色々試行錯誤したところでもあるんだけど、結局以下のようにしたらうまくいった。

  • systemd で起動しているものは止める (systemctl stop xxx, systemctl disable xxx)
  • swift-init コマンドで起動するようにした。

swift-init コマンドでの起動方法はこんな感じ。

[root@host ~]# swift-init main start
Starting proxy-server...(/etc/swift/proxy-server.conf)
Starting container-server...(/etc/swift/container-server.conf)
Starting container-server...(/etc/swift/container-server/1.conf)
Starting container-server...(/etc/swift/container-server/2.conf)
Starting container-server...(/etc/swift/container-server/3.conf)
Starting container-server...(/etc/swift/container-server/4.conf)
Starting account-server...(/etc/swift/account-server.conf)
Starting account-server...(/etc/swift/account-server/1.conf)
Starting account-server...(/etc/swift/account-server/2.conf)
Starting account-server...(/etc/swift/account-server/3.conf)
Starting account-server...(/etc/swift/account-server/4.conf)
Starting object-server...(/etc/swift/object-server.conf)
Starting object-server...(/etc/swift/object-server/1.conf)
Starting object-server...(/etc/swift/object-server/2.conf)
Starting object-server...(/etc/swift/object-server/3.conf)
Starting object-server...(/etc/swift/object-server/4.conf)

動作確認

コマンドラインで

root ユーザーのホームディレクトリに keystonerc_admin と keystonerc_demo というファイルが出来ているはず。それの中をみると、接続情報が書かれている。使い方としては以下のとおり。

$ . /path/to/keystonerc_admin # 接続情報を環境変数にセット
$ swift stat                  # コマンドの引数にパスワードとかは必要ない

コンテナ(S3 のバケットみたいなもの?)の作成やファイルのアップロードコマンドが出来るようになっているはず。詳しくはリファレンスを参照のこと。

ブラウザで

http://example.com/dashboard というURLにアクセスすると OpenStack の dashboard が表示されるはず。

トラブルシューティング

とりあえず自分が遭遇したエラーとかを。

libJerasure.so が読み込めない

ログに以下のようなエラーが出て、proxy server が起動しなかった。

 6月 26 18:55:09 swift.example.com systemd[1]: Starting OpenStack Object Storage (swift) - Proxy Server...
 6月 26 18:55:09 swift.example.com systemd[1]: Started OpenStack Object Storage (swift) - Proxy Server.
 6月 26 18:55:14 swift.example.com liberasurecode[1109]: liberasurecode_backend_open: dynamic linking error libJerasure.so: cannot open shared object file: No such file or directory
 6月 26 18:55:14 swift.example.com swift-proxy-server[1109]: liberasurecode[1109]: liberasurecode_backend_open: dynamic linking error libJerasure.so: cannot open shared object file: No such file or directory
 6月 26 18:55:14 swift.example.com swift-proxy-server[1109]: Error trying to load config from /etc/swift/proxy-server.conf: Invalid arguments passed to liberasurecode_instance_create
 6月 26 18:55:14 swift.example.com systemd[1]: openstack-swift-proxy.service: main process exited, code=exited, status=1/FAILURE
 6月 26 18:55:14 swift.example.com systemd[1]: Unit openstack-swift-proxy.service entered failed state.

調べてみると、Swift は Erasure Code なるものをサポートしているらしいんだけど、内部ではPyECLib ってのを使っていて、そのバックエンドに以下のどれかが必要らしい。

  1. Jerasure and GFComplete at http://jerasure.org
  2. Intel(R) ISA-L at http://01.org/intel%C2%AE-storage-acceleration-library-open-source-version
  3. 自分で実装する

1番なんだけど、CentOS で簡単にインストールする方法が見つからなかった。2番に関しては、自分でコンパイルする必要があったのでとりあえず除外。3番は論外。

とりあえずは、この Erasure Code を使わなければ良い。

/etc/swift/swift.conf → 既存ファイルの末尾にコピペ。ただし、[storage-policy:2] の項目は飛ばした。理由は後述。

と書いたのはこれが理由。

/etc/swift/object-1.ring.gz が見つからない

同じく proxy server 起動時に以下のようなエラーが出た。

 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: self.object_ring = Ring(swift_dir, ring_name=self.ring_name)
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: File "/usr/lib/python2.7/site-packages/swift/common/ring/ring.py", line 152, in __init__
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: self._reload(force=True)
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: File "/usr/lib/python2.7/site-packages/swift/common/ring/ring.py", line 157, in _reload
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: ring_data = RingData.load(self.serialized_path)
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: File "/usr/lib/python2.7/site-packages/swift/common/ring/ring.py", line 65, in load
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: gz_file = GzipFile(filename, 'rb')
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: File "/usr/lib64/python2.7/gzip.py", line 94, in __init__
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: fileobj = self.myfileobj = __builtin__.open(filename, mode or 'rb')
 6月 26 20:49:06 swift.example.com swift-proxy-server[2839]: IOError: [Errno 2] No such file or directory: '/etc/swift/object-1.ring.gz'
 6月 26 20:49:06 swift.example.com systemd[1]: openstack-swift-proxy.service: main process exited, code=exited, status=1/FAILURE
 6月 26 20:49:06 swift.example.com systemd[1]: Unit openstack-swift-proxy.service entered failed state.

理由は、rings の作成のコマンドを、/etc/swift ディレクトリではなく、/root ディレクトリで行っていたため。ring ファイルも /root にできていた。

permission denied だと?

ファイルのパーミッションは問題無さそうなのに permission denied が出る場合は、SELinux が原因の可能性が高い。

Jun 26 21:19:01 swift systemd: Starting Session 148 of user keystone.
Jun 26 21:19:01 swift systemd: Started Session 148 of user keystone.
Jun 26 21:19:05 swift swift-proxy-server: Traceback (most recent call last):
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/bin/swift-proxy-server", line 23, in <module>
Jun 26 21:19:05 swift swift-proxy-server: sys.exit(run_wsgi(conf_file, 'proxy-server', **options))
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/swift/common/wsgi.py", line 473, in run_wsgi
Jun 26 21:19:05 swift swift-proxy-server: loadapp(conf_path, global_conf=global_conf)
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/swift/common/wsgi.py", line 385, in loadapp
Jun 26 21:19:05 swift swift-proxy-server: app = ctx.app_context.create()
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/paste/deploy/loadwsgi.py", line 710, in create
Jun 26 21:19:05 swift swift-proxy-server: return self.object_type.invoke(self)
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/paste/deploy/loadwsgi.py", line 146, in invoke
Jun 26 21:19:05 swift swift-proxy-server: return fix_call(context.object, context.global_conf, **context.local_conf)
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/paste/deploy/util.py", line 56, in fix_call
Jun 26 21:19:05 swift swift-proxy-server: val = callable(*args, **kw)
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/swift/proxy/server.py", line 614, in app_factory
Jun 26 21:19:05 swift swift-proxy-server: app = Application(conf)
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/swift/proxy/server.py", line 110, in __init__
Jun 26 21:19:05 swift swift-proxy-server: ring_name='container')
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/swift/common/ring/ring.py", line 152, in __init__
Jun 26 21:19:05 swift swift-proxy-server: self._reload(force=True)
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/swift/common/ring/ring.py", line 157, in _reload
Jun 26 21:19:05 swift swift-proxy-server: ring_data = RingData.load(self.serialized_path)
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib/python2.7/site-packages/swift/common/ring/ring.py", line 65, in load
Jun 26 21:19:05 swift swift-proxy-server: gz_file = GzipFile(filename, 'rb')
Jun 26 21:19:05 swift swift-proxy-server: File "/usr/lib64/python2.7/gzip.py", line 94, in __init__
Jun 26 21:19:05 swift swift-proxy-server: fileobj = self.myfileobj = __builtin__.open(filename, mode or 'rb')
Jun 26 21:19:05 swift swift-proxy-server: IOError: [Errno 13] Permission denied: '/etc/swift/container.ring.gz'
Jun 26 21:19:05 swift systemd: openstack-swift-proxy.service: main process exited, code=exited, status=1/FAILURE
Jun 26 21:19:05 swift systemd: Unit openstack-swift-proxy.service entered failed state.

以下のとおりオフに出来る。

setenforce Permissive

Account HEAD failed

swift コマンドに失敗する。

[root@swift ~]# . keystonerc_demo
[root@swift ~(keystone_demo)]#
[root@swift ~(keystone_demo)]# swift stat
Account HEAD failed: http://example.com:8080/v1/AUTH_sometoken 503 Internal Server Error

理由はサービスが正常に立ち上がっていないか、ファイアウォールで通信がブロックされていること。

まとめ

結構大変。でも、こんなに高機能なインフラが、比較的簡単に、安価なサーバーや VPS 上で構築出来るってのはとにかくすごい。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です