DevCloud2による最新CloudStack環境の構築

CloudStackにはDevCloudというお試し開発環境がある。その実体は仮想アプライアンスになっていて、VirtualBoxKVM上で最低限のCloudStack環境を動かせるようになっている。OS XでもVirtualBoxが動くのだけど、新たにVirtualBoxをインストールするのはいやなので、既存のVMWare Fusion + Ubuntu環境でDevCloudを動かしてみた。VMWare Fusion 5はNested Virtualizationに対応しているので*1、ゲストOS内でKVMなどのハイパーバイザを動かすことができる。う〜ん、すばらしい!

DevCloudの動かし方は、CloudStackのWikiに詳しいので、それに従えばOK。ただし、4.2-SNAPSHOTというgitのmasterブランチを使っていたので、ソースコードを一部直す必要があったけど、これは後述する。

VMWare FusionVMにはCPU 2個とメモリ4GBを割り当てた。ゲストOSはUbuntu 12.04である。ちゃんと/proc/cpuinfoでvmxとeptフラグが立っていることを確認すること。

まず、KVM用のDevCloudパッケージをダウンロードして、virshを使ってゲストOSを起動する。事前に最低限libvirt-binやqemu-kvmは必要。VNCクライアントが欲しければ、xtightvncviewerあたりも入れておく。

ubuntu# virsh net-define devcloud-nat-0.xml
ubuntu# virsh net-define devcloud-nat-1.xml
ubuntu# virsh net-start devcloud-nat-0
ubuntu# virsh net-start devcloud-nat-1
ubuntu# virsh net-autostart devcloud-nat-0
ubuntu# virsh net-autostart devcloud-nat-1

ubuntu# vi devcloud.xml # xxx.qcow2のパスを変更

ubuntu# virsh define devcloud.xml
ubuntu# virsh start devcloud

ゲストOSのIPアドレスは192.168.56.10になるので、rootでsshログインできることを確認する。

続いて、ゲストOS内で最新のソースコードをgitで取得して、管理サーバを起動する。

devcloud# git clone https://git-wip-us.apache.org/repos/asf/cloudstack.git

まず、管理サーバをビルドして、

devcloud# mvn -P developer,systemvm clean install

データベースをデプロイして、

devcloud# mvn -P developer -pl developer,tools/devcloud -Ddeploydb

管理サーバを起動する。

devcloud# mvn -pl :cloud-client-ui jetty:run

なお、古いドキュメントにはTomcatが必要みたいな記述があるが、最新版ではJettyを使っているので、おそらくTomcatは不要だと思う。また、antじゃなくてmavenを使う点が4.0.xとの違い。

この時点でhttp://192.168.56.10:8080/clientにアクセスすればポータルのログイン画面が表示される。

このまま環境を作っていてもいいのだけど、基本ゾーンをデプロイする手段が用意されているので、これを使う。ただ、そのままではすんなり動かなかった。まず足りないパッケージを入れる(この辺の実装にはPythonが使われているようだ)。

devcloud# apt-get install python-mysql.connector

devcloud# mvn -P developer -pl tools/devcloud -Ddeploysvr

しかし、tools/marvin/marvin/cloudstackConnection.pyのmarvin_request関数で"TypeError: 'dict' object is not callable."が発生して止まってしまう。これは216行目の"response.json()"を"response.json"に変更すればOKで、基本ゾーンのデプロイが完了する。

ポータルにログインすると、一通りちゃんと動いているようだ。

しばらく待つとtiny Linuxのテンプレートが使えるようになるので、インスタンスを起動してみる。

VNCコンソールも使えるが、あまり実用的な速度で動かないので、sshを使うとよい。

KVMのゲストOSの中ではハイパーバイザとしてXenServerが使われていて、xe vm-listするとDom0以外に4つのCloudStack関連のDomUが起動していることがわかる。それにしても、VMWare FusionKVMXenという仮想化が入れ子になって、それなりの性能で動いているのはなかなかすごいなぁ。

ということで、CloudStackに興味あるけど、環境構築が面倒そうと思っている人は試してみればどう?

*1:VMWare Fusion 4でもNested Virtualizationに対応していたけど、5ではGUIで設定可能になった。

VMWare Fusionでawesomeを使うときのTIPS

小ネタをひとつ。VMWare FusionVMUbuntu + awesomeを入れて使っている。awesomeでウィンドウサイズを調整するのに、Mod4 + h/lを使う。Mod4はMacのCommandキーに割り当てられているので、Mod4 + hを実行するとウィンドウが隠れてしまう(フルスクリーンだと画面が切り替わってしまう)。マウスでも操作できるけど、キーボードでやりたい。
VMWareの設定画面でKeyboard & Mouseタブを選択し、Fusion ShortcutsのHide Applicationのチェックを外せばOK。これだけ。

UbuntuでInfinibandクラスタを作る

今までRedHatLinux + OFEDパッケージでInfinibandを使うことが多かったが、Ubuntu 12.04 + 基本パッケージでどこまでできるかやってみた。InfiniBand HCAはMellanoxのConnectX-3。カーネルは3.5.0-23-genericで、ドライバ類はカーネル標準の物を利用する*1

結論から言えば、基本的に基本パッケージだけでInfinibandが動く環境を作ることができる。ただし、Ubuntu 12.04に含まれるlibmlx4パッケージはConnectX-3に対応していないので、ここだけは12.10のパッケージを持ってきてしのいだ*2。したがって、12.04でも新しめのHCAを使わない場合や、12.10では何の問題もなく動くだろう。

まず、/etc/modulesにとりあえず必要そうなモジュールを追加して、それぞれをmodprobeしておく。

# For Infiniband
mlx4_ib
rdma_ucm
ib_umad
ib_uverbs
ib_ipoib

基本的な動作確認とMPI実行環境が必要であれば、ibverbs-utils、infiniband-diags、perftest、openmpi1.5-binあたりをインストールする。コンパイル環境が必要なノードには、これらに加えてopenmpi1.5-dev、gcc、gfortran、g++あたりをインストールする。

冒頭に書いた通り、12.10のlibmlx4をダウンロードして、インストールする。

$ curl -O http://us.archive.ubuntu.com/ubuntu/ubuntu/pool/universe/libm/libmlx4/libmlx4-1_1.0.4-1_amd64.deb
$ sudo dpkg -i libmlx4-1_1.0.4-1_amd64.deb

ibv_devinfoやibstatでHCAが見えているか確認する。

OpenSMをどこか最低1台のノードで起動する。おそらく自動起動になっているので、一度Infinibandの設定が済めば、後はこの作業は不要。

/etc/init.d/opensm start

OpenSMとのネゴシエーションに成功すれば、ibv_devinfoでポートの状態がPORT_ACTIVEになるはず。あとはibpingやib_write_bw、ib_read_bwあたりでノード間の疎通や性能を確認する。

node1 $ sudo ibping -S

node2 $ sudo ibping <node1のLID>

必要ならIPoIBの設定もやっておく。/etc/network/interfacesにib0の設定を加える。デフォルトではdatagramモードで動くが、connectedモードにしてもよいかも。

# IPoIB network interface
auto ib0
iface ib0 inet static
address 192.168.250.1
network 192.168.250.0
netmask 255.255.255.0
broadcast 192.168.250.255

最後にOpen MPIの動作を確認する。まず、FAQだけど、memlockの制限をunlimitedにしないと動かない。安直には/etc/security/limits.confに次の行を追加すればよい。SSHがPAMの設定を参照してくれるので、SSH経由でプロセスを起動してもちゃんとmemlockがunlimitedに設定される。Ubuntu 12.04は大丈夫だったけど、これだけでダメな場合は、/etc/ssh/sshd_configのUsePAMの設定を確認すること。

* soft memlock unlimited
* hard memlock unlimited

あとは、適当なMPIプログラムを動かしてみる。

$ mpirun --mca btl openib,self -np 20 -hostfile hostlist ./a.out

*1:ちなみに、最近のOFED 3.x系ではOFED 1.5.x系とは異なりドライバは含まれない。

*2:詳細はここを参照。ibv_devinfoを実行すると「libibverbs: Warning: no userspace device-specific driver found for /sys/class/infiniband_verbs/uverbs0」というメッセージが出て動かない。

計算「ノード」という呼び方について

計算機のことをノードとかホストと呼ぶことがある。ホストは計算をホスティングするという意味で問題ないけど、今回はノードという呼び方について考えてみる。特に計算機がネットワークに接続されたクラスタやデータセンタではノードと呼ぶことが多い。計算機屋のみと話しているときはこれで支障ないのだけど、ネットワーク屋と話していると話が食い違ってしまうことがある。特にデバイスに近い人だと、スイッチングモジュールなどのチップをスイッチ、システムとなった装置をノードと呼んでいたりする。ネットワークの視点で見ると、スイッチやルータがノード(節点)であるというのは正しい。

計算ノードと呼び始めたのは、HPC分野で単に計算ノードとスイッチノードの区別から始まったのかもしれない。けど、インターコネクト・トポロジがメッシュ・トーラスだった計算機が由来だったりしないかな。メッシュ・トーラスなら計算ノードでルーティングするし、リーフ(葉)ではなくなる。一方、Ethernetに代表されるツリー・トポロジだと計算機もリーフになる。まぁ、リーフもノードの一部だから、計算ノードと呼んでも間違いじゃないけどさ。

OpenFlow実践入門

そろそろ「OpenFlow実践入門」についてステマしないといけないのではと思ったので書いてみる。OpenFlowに関して日本語で書かれた書籍はまだ2冊しか出ていないと思うけど、OpenFlowに興味あるならまずはこれを買っておけと。

OpenFlow本と言いつつ、実質はTrema本である。TremaはRubyで書かれたOpenFlowコントローラフレームワークなので、Rubyに愛のない人は厳しいだけど、Rubyを知らなくてもその都度Rubyの文法に関する補足がなされているので、最後まで読み通すことができる。Trema Dayでも、「Python版Tremaはどうなった?」という話が出てきたが、Pythonで再実装するぐらいなら、Rubyを覚えた方が早い。Python使いならRyuという選択肢もある。

高宮さんの巻頭言に感動しながら読み進めていくと、最初に出てくるhello-trema.rbにtypoが!これではまる人はいないと思うが。。。バカ売れして改訂版で直るといいなぁ。

class HelloTrema  Controller # あれ「<」がない
  def start
    puts "Hello, Trema!"
  end
end

つまらない粗探しはこれぐらいにして、へぇと思った部分をいくつか。

  • Flow ModとPacket Outは一緒にやらない方がよい。
  • 統計情報を取得するには、Flow Removedメッセージを使う。(え、それでいいの?という驚き)
  • OpenFlowに関係ないけど、ルーティングテーブルのロンゲストマッチの実装方法。

また、Trema Dayで鈴木さんが、シンプルルータ(simple-router.rb)について、C言語でパケットを書き換えるのは簡単だけど、Rubyは抽象度が高いので苦労した。パケットの生成や書換えをうまくやる方法は確立できてないと裏話を語っておられた。会場からはRacketというライブラリが使えるのではとの指摘があった。

あとは実際に手を動かしながら、読み深めようと思う。

(追記)高宮さんに正誤表のページを教えてもらった。

クラウド時代のネットワーク技術 OpenFlow実践入門 (Software Design plus)

クラウド時代のネットワーク技術 OpenFlow実践入門 (Software Design plus)

Trema Day #1でOpenFlow 1.3について思ったこと

Trema Day #1に参加した。まったりとした雰囲気の中、Tremaに限らずSDN関連のいろんな発表聴けて休日を潰しても十分元を取れた。その中でOpenFlow 1.3の話がいくつか出てきたので、まとめておきたいと思う。当日の様子はust録画されているとのことなので、まだ視聴できると思う。

1.0から1.3への変更について、機能レベルでIPv6やMPLS、PBBなどに対応したというのはあちこちで耳にするので、ここでは踏み込まない。グループやQoSのあたりも、具体的にどう使うのかいまいち分かっていないし。個人的には予想以上にプロトコルが変わっているという印象を強く受けた。詳しくは後で書くけど、packet inに関わる部分は特に変わりすぎじゃないかな。現実に即すように変更されたのだとは思うけど。Trema開発の中心人物である須堯さんは、1.0と1.3の互換性を取りながらコントローラを作るのは無理じゃないかとおっしゃっていた。このレベルの変更をあの頻度にやられると、確かにベンダは着いて来られないよな。1.3で仕様策定をペースダウンしましょうというONFの判断は納得できる。

packet inはOpenFlowがもたらす柔軟性の肝である。OpenFlowが出てきたとき、フローテーブルはproactiveにもreactiveにも設定できるけど、packet inを使ってreactiveにやるのがOpenFlow流みたいに私は受け取った。その後、本当にそうなのかなと悶々としていたけど、ComSys 2012で藤田@NTTさんが「packet inしたら負け」というのを講演冒頭からおっしゃっていて、スッキリした。OpenFlowだから何でもできるわけじゃなくて、適用できる範囲というものが徐々に明らかになってきたのだろう。OpenFlowの仕様もそれに合わせて変わってきたのだと思う。@tsuboiさんによると、クラウド/通信事業者がOpenFlowを適用するときの動機として、運用の自動化が大きい。reactiveでは、自動化の阻害要因になりかねないので、proactiveを中心にしたアーキテクチャとして検討され直したのだろうとのことである。なるほど。

まず1.3になると、デフォルトではpacket inはコントローラに上がってこない。これは結構衝撃的だった。packet inが必要な場合は、コントローラが明示的にflow modで設定する必要がある。packet inに付属する情報も(後述するように)変わっていて、肥大化の傾向にある。当然コントローラの負荷は増える。そこでセキュアチャネル以外に、Auxiliary Connections(これはUDP?)を使って、packet inをオフロードしようという話もあるようだ。また、1.0のflow modはマッチしたらアクションを実行するという単純なものだったが、インストラクションが入って、アクションをパイプライン化することが可能になった。会場からは本当にハードウェア化できるのか、やるなら何段?という質問も出ていた*1

あとはスイッチのポート情報がfeatures replyで上がってこないので、自力で検索する必要があるとか。たぶん大規模データセンタでの運用を見据えた変更だろうけど、Tremaアプリを書く人は気をつける必要がある。

話は変わるが、OpenFlow対抗?として、JuniperやCiscoらがIETFで標準化を進めているI2RS (Interface to the Routing System)ワーキンググループの動向も気になる。何でもプログラマブルに対する揺り戻しとして、どのあたりに着地点を設定してくるのだろうか。

ちなみに上の写真は懇親会でもらったTrema Tシャツ。packet_in構造体の定義がなぜTrema?と思ったら、Trema独自の抽象化が入っているので、Open vSwitchのものとは違うそうだ。TシャツにもあるTremaの定義(src/lib/openflow_application_interface.h)は次の通り。

typedef struct {
  uint64_t datapath_id;
  uint32_t transaction_id;
  uint32_t buffer_id;
  uint16_t total_len;
  uint16_t in_port;
  uint8_t reason;
  const buffer *data;
  void *user_data;
} packet_in;

これに対して、Open vSwitchの定義(include/openflow/openflow-1.0.h)ではこうなる。

struct ofp10_packet_in {
    ovs_be32 buffer_id;     /* ID assigned by datapath. */
    ovs_be16 total_len;     /* Full length of frame. */
    ovs_be16 in_port;       /* Port on which frame was received. */
    uint8_t reason;         /* Reason packet is being sent (one of OFPR_*) */
    uint8_t pad;
    uint8_t data[0];        /* Ethernet frame, halfway through 32-bit word,
                               so the IP header is 32-bit aligned.  The
                               amount of data is inferred from the length
                               field in the header.  Because of padding,
                               offsetof(struct ofp_packet_in, data) ==
                               sizeof(struct ofp_packet_in) - 2. */
};

なるほど、datapath_id、transaction_id、user_dataあたりがTremaでは追加されている。ちなみにOpenFlow 1.3ではtable_inやcookieが追加され、in_portが削除されている。packet_inでin_portはわからないのでmatchを検索しろと言うことらしい。

Open vSwitchのmasterブランチにはopenflow-1.3.hは含まれているけど、次のlong term supportになる1.9系ではOpenFlow 1.3は対応されないらしい。OpenFlow 1.3対応がそろってくるのはもう少し先になるのかな。Tremaが1.1と1.2を飛ばして1.3対応したことに対して、会場では概ね納得という反応だった。Pica8は最近のUpdate(PicOS 1.6)でOpen vSwitch 1.7.1ベースになり、OpenFlow 1.2対応と刻んできた。AcctonもOpenFlow 1.2対応と言っていたはず(AcctonのスイッチもOpen vSwitchベースなのかな?)。その辺にはいろいろ大人の事情があるんだろう。

Trema edgeが正式リリースされれば、packet_inの定義も1.3対応されるので、新しいTシャツが作られるとのこと。Trema DayでLTしたり、Tremaにパッチを投げたりしたら、Tシャツもらえるかも。ちなみにTrema Dayは、今後も3ヶ月に一度ぐらいの頻度で開催予定ということだ。

個人的にはOpenFlowの仕様書を一度真面目に読んでみようと思った。

(追記)はてブPlan9日記なのにPlan 9について書かれていないじゃないかみたいなことが書かれていたので、ちょっとだけ蛇足。Trema Dayの懇親会でPlan 9acmeの話が出ていたらしい。次回は宴会芸として、acmeへの愛を語りたい!?

*1:ONFの仕様策定方法についても話題に上った。スタンフォード大学が音頭を取っていた1.0までは、実装がないと標準化しないというポリシだった。しかし、ONF設立後、実装がないまま1.1がなし崩し的にリリースされてしまうと、それが慣習となってしまった。ONF内の力関係がどうなっているか知らないけど、ハードウェアベンダよりもNiciraのようなソフトウェアベンダの力の方が強く、ハードウェア化が困難なものも入ってしまうのかなと思ったり。

awesome+urxvtでmozcを使う

Windows 8でHyper-VならぬVirtualBox環境を構築」の続き。Linux (ubuntu 12.04)環境で日本語ファイル名を処理したくなったので、mozcを入れてみた。けど、まだ完全には動いてない。ちなみにmozcを使うのは今回初めて。Linuxのデスクトップ環境から離れて長いし。

tony/awosome-configを参考にawesomeの設定を済ませておくと吉。今回関係するのはautorun.luaだけなので、rc.luaの最後に

require_safe('autorun')

を追加するだけでも事足りる。

まずは、mozc関係のパッケージをインストールする。

$ sudo apt-get install ibus-mozc emacs-mozc

$HOME/.xprofileは次のように。

export XMODIFIERS="@im=ibus"
export GTK_IM_MODULE="ibus"
export QT_IM_MODULE="ibus"

ibus (Intelligent Input Bus for Linux / Unix OS)って仕組みは初耳だ。浦島状態。

$HOME/.config/awesome/autorun.luaは次のように。

run_once("ibus-daemon", "-rdx --panel=disable")

これでXを再起動すれば、Ctrl+spaceでmozcが起動する。ただ、urxvtターミナル上だと変換候補が表示されないので、事実上使い物にならない。。。何が足りないのだろう。情報求む!

Emacsからmozcを使うには、.emacs.d/init.elに次のように書いておけばOK。こちらは問題なく動いた。

;; mozc
(require 'mozc)
(set-language-environment "Japanese")
(setq default-input-method "japanese-mozc")
(global-set-key (kbd "C-o") 'toggle-input-method)