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 ってのを使っていて、そのバックエンドに以下のどれかが必要らしい。
- Jerasure and GFComplete at http://jerasure.org
- Intel(R) ISA-L at http://01.org/intel%C2%AE-storage-acceleration-library-open-source-version
- 自分で実装する
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 上で構築出来るってのはとにかくすごい。