本記事はOpenStackをInfiniband(eipoib)にて導入しようとして蹴躓いた(現在進行形で蹴躓いてる)話です

OpenStackについて

OpenStackは(パブリック|プライベート)クラウドを構築するソフトウェアプラットフォームで、2010年にRackspaceとNASAが開発を開始しました。(意外と若いような、若くないような・・・。)
OpenStackを用いることで、あらゆるベンダー/あらゆるタイプのハードウェア資源を協調動作させ、ユーザーにダッシュボード、もしくはCLI、RESTful APIで提供することができるようになります。

ようは複数台の物理マシン上のKVMとかVMWareの利用状況をAMQPとかのメッセージプロトコルを使ってDBに貯めて
一元管理し、APIで注文受け付けたらリソースが余っているところから切りだせるようにしたのがOpenStack。

何がつらいか

  • つらみポイント①コンポーネント多すぎ問題

現在の最新バージョンMitakaにおけるコンポーネントは
Nova,Swift,Glance,Horizon,Keystone,Neutron,Cinder,Heat,Ceilometer,Trove,Sahara,Ironic,Zaqar,Manila,Designate,Barbican

・・・・・・・・多いわ!
んでもって名前が直感的じゃないのでパッとみよくわからない。
この中で一番重要かつOpenStackを運用する上で最低限必要なのはたった4つ
・Nova
・Glance
・Keystone
・Neutron
あとはWeb画面としてHorizonがあるといいかな、というぐらい。もちろん他のコンポーネントも使いこなせると便利なのだけど、
ひとまずはこの4つ+1つを扱えるようになれば構築はできると思います。
基本的な流れは以下の通り

  1. まずKeystoneというユーザ認証をつかさどるコンポーネントにユーザを登録します

  2. Glanceという仮想マシンのOSイメージを貯めておくところにKVMで作ったイメージ(にvirt-sysprepしたもの)とかOS配布サイトで拾えるクラウド用のイメージを登録

  3. Neutronという仮想ネットワークを作成するコンポーネントでvlanを定義(flatという物理マシンと同じネットワークを使うこともできるし、スイッチを跨ぐvxlanとかもある)

  4. NovaというKVMなどの仮想基盤上に展開されている仮想マシンを管理するコンポーネントを使い、1.で作ったユーザでログイン(CUIなら環境変数にユーザ・パスワード記載)して、2.で作ったイメージを指定し、3.で作ったネットワークを指定して仮想マシンをブートします。

運用する上ではその他にCeilometer(リソース監視のコンポーネント)もあるといいかな、と思いますが、これが結構曲者でVM立ち上げてるだけでガンガンDBに書き込みやがりますのでディスク容量の見積もりなどを行った上、定期的にDBから削除したりログを削除したりといった工夫が必要になります。
CinderやSwiftのような外部ストレージもあると便利ではありますが、プライベートクラウドのようなある程度自由にできる環境であれば(社員だけが使うことが分かっている状況)NFSとかの方が使い勝手よろしいんじゃないかという気がします。共有できないので。(Manilaという新たに追加されたコンポーネントで共有できるようになるみたいですが・・・)
ということで色々コンポーネント増えまくってはいますが結局やってることはリソースを一元化・抽象化してRestful API生やしてるだけじゃーんということがわかると理解が楽でよろしいかと思います。なんか怒られそうな気がしますが。

  • つらみポイント②ネットワーク複雑すぎる問題

こっちが本題。
さて基本的には上記の通りなのですが、ここにOpenvswitchが絡むと話がややこしくなります。
(ていうかNeutronってだけでややこしい?)
Openvswitchは仮想ネットワークソフトウェア(仮想スイッチ)で、OpenFlowというSDNを実現するための標準に対応しており、このOpenvswitchによって仮想マシンのネットワークの管理を行うことが可能になります。
OpenvswitchはLinux bridgeと互換性があり、NeutronにおいてはLinux bridgeとの選択となりますが機能の豊富さからOpenvswitchが選択されることが多いようです。

そしてそれが全ての苦難の始まりだった・・・

というのもこのOpenvswitch、仮想マシンの管理において仮想ブリッジを複数作成して管理するので身に覚えのないブリッジデバイスがなんかたくさんできてるという状況になります。(例:br-int,qvo何某,tap何某,etc,etc,)
ついでに、作成したネットワークがflatかvlanかでブリッジデバイスの付け方が違う上、Infiniband上で利用しようとするとipoib(IP over Infiniband)ではダメで、eipoib(Ethernet IP over Infiniband)でなければいけないという困った仕様があります。(というか開発できていないだけ?)
eipoibはせっかくInfinibandで流れてるフレームにわざわざEthernetのヘッダを付け加え(もちろんパフォーマンスは劣化します)完全にEthernetと同じ状態にするプロトコルで、困ったことにあまりデバッグされていない機能のため、様々な問題が発生することがあります。
たとえばofed(Infinibandのドライバ)のバージョンによってはeipoibのパケットが正しく流れないというバグがあるせいかflatを指定しているのにvlanのような状態になったり、ofedのバージョン上げたらflatに戻ったり、ハードによってはflatに戻らなかったりというような地獄が現出します。
その他、SR-IOVというInfinibandのハードウェア仮想化機能においても、Firmwareのバージョンやofedのバージョン、Openvswitchのバージョン、OpenStackのバージョン次第でできたりできなかったりします。

とてもつらい

ということで結論として、OpenStack+Infinibandの組み合わせは結構Buggyであんまり知見がないのでよほどInfinibandに強いとか、どんな状況でもInfinibandのFirmwareやドライバを好きに上げられる、
Linuxのカーネルを好きに上げられる、OpenStackのバージョンを最新に上げられる状況の上、多少バグっててもすぐさま自作パッチ当てて二度とバグが表面化しないというような能力を持っていない人はたぶん普通にEthernetで組んだ方がいいんじゃないかなって思いました。はい。
もちろんInfiniband+SR-IOVが正しく構築できればそのコストパフォーマンスは多大なものがあるので挑戦できる環境であればぜひチャレンジしていただきたいです。そして知見を共有してください。なんでもしますから!

以上、2016年を締めくくるバッドエンド的なアドカレをお送りいたしました。ではまた来年。