去年くらいから@jxta先生や@mnagakuさんとEucalyptusのお世話をさせていただいているなんでも屋です。
Eucalyptus Advent Calendar 2012 JPに参戦させていただきます。
俗にいうプライベートクラウドという奴なのですが、やってみると意外とお世話が大変。ということでその中で試行錯誤してみていることをネタに書いてみます。
何やってるの?
色々なところで論文とか出しているから名前出してしまってもいいかなー、くらいに思ったわけですが、一応固有名詞は伏せつつ。
- Eucalyptusのバージョンは1.6.2で、これが17セットある。内訳は約100コア×10, 約50コア×5, 約160コア×1, 約240コア×1。
- 用途はWindows仮想マシンでリモートデスクトップを使ったり、Linuxで研究目的の計算クラスタを構築したりとかさまざま。
- 性能測定などを行うことがあるため、オーバーコミットはしない。
みたいな感じになっています。少なくともお世話している人間の数に比べると多い気がします。わけがわからないよ。
で、さらに、
- 仮想マシンではなく物理マシン貸しタイプのクラウドもあり、上のEucalyptusの一部はこの上に載っている
- この物理マシン貸しクラウドはネットワークをOpenFlowで制御している
みたいな仮想化基盤のミルフィーユのような状態なわけです。とてもイヌカレー空間な感じがしますね。
何が大変なの?
まあそんな感じの仮想化基盤を組織内の方々にお貸しするわけですが、色々と大変です。
- トラブルの原因特定が大変
- トラブルが起きた時にミルフィーユ状態のどの層の何が悪さしてるのかなかなかわかりません。それぞれが相互に影響しあっているのでなんだかよくわからない。 情報が足りないとたいてい各担当者はお互いに「お前が何か悪いことしてんじゃないの?」的なことしか言えなくなるので非常にソウルジェムが濁ります。
- リソースの分配が大変
- Amazon みたいな超覇王な感じのパブリッククラウドはちゃんとリソース単位で金も取ってるし相応にスケールしていくのでリソース使いたい放題のわがままな利用者に対しても対応できますが、プライベートクラウドは予算の割り当て方式などの制約上あらかじめ計画した量の計算リソースしか提供できません。一方、もともと EucalyptusはAmazonのAPIをなぞっているので基本的に中身は見えない。隠蔽は仮想化の重要なポイントではあるのですが、クラウド全体が どんなにカッツカツな状態で動いているかも隠蔽してしまうので、「ようわからんがリソースが確保できなくて動かないぞゴルァ」みたいなことを利用者の方から言われてまた俺のソウルジェムが濁ります。
- 新参者の扱いが大変
- みなさんご存知のとおりEucalyptusのようなクラウド基盤はいくつか現れてきていて、「Eucalyptusの1.6.2なんて古いのでなくOpenStack使おうぜ」みたいな展開になったりします。(dodai-deployとかやってる組織だし。) そうなると 「どうやって今あるEucalyptusと整合性をとりつつ管理するんですかそれ」みたいな感じになって、もはやアルティメットまどか神に俺の存在を生まれる前に消し去ってもらう展開しか見えません。
と、 結構な大変な任務になってくるわけですが、一方で俺にはTwitter上で #precure やら #garupan やらハッシュタグをつけつつ草を生やすという重大な業務があるわけで、いかに人間の手間を減らしつつ状況を把握してうまいこと立ちまわるかみたいなことを日々考えることになるわけです。
で、可視化という方向に走っているわけですが(研究会発表くらいはさせていただいていて、slideshareにアップしてあります)、今回はEucalyptus Advent Calendarっぽい感じのネタということで思いついた、MuninのプラグインをJavaでDasein Cloud APIなるものを使って書いてみたぜ!的なことを書きます。
Munin はサードパーティのプラグインが充実しているので、できあいのプラグインを持ってくることもできるわけですが、少なくとも自分が置かれている状況は時に よって見たいパラメータの組み合わせがあれやこれや変わってしまうので、(できるだけ少ないコード量に抑えつつ)コードを書く、ということをやったほうが 全体的にはスムーズに対応できるんじゃないか?みたいな感じもありこんなことをやってみています。
材料
- Munin http://munin-monitoring.org/
- サーバの監視ソフトウェア。Munin masterがとりまとめ役になって複数のMunin nodeからやってくる情報をグラフにしてくれたり一定値を越えたりすると教えてくれたりする。
- プラグインを作るのが簡単。Munin nodeに一定のルールを満たしたテキストを標準出力に吐くような実行可能ファイルを置いてあげると、Munin masterの設定など変えることなく監視内容を増やすことができる。
- ここではMuninはインストール・設定されているという前提で考えることにする。
- Dasein Cloud API http://dasein-cloud.sourceforge.net/
- Amazon EC2やEucalyptusやOpenStackといったクラウド基盤に対するアクセス用のAPIの差異を吸収する抽象APIとその実装。昨日「なんか書かなきゃ」と思ってググって見つけたレベル。
- Javaでわりと簡単にかける。
こいつらを組み合わせて、とりあえず今回はネタとして、
- ユーザごとのインスタンス数
- ユーザごとのイメージ数
- イメージごとのインスタンス数
をグラフ化するようなプラグインを作ってみることにします。
構成
こんな感じです。こうしておけばOpenStackにしようぜって言われてもコード使いまわせるよね。よね。という話です。バイナリのダウンロード
SourceForgeからdasein-cloud-2012.04.zipをダウンロードします。最新版はgithubに移ったようですが、どうもeuca版の実装がなく(aws版を使えという話っぽい)、ウチのEucalyptusは1.6.2と古いので地雷の香りがしたので華麗にスルー。
とりあえずクラウドの情報にアクセスしてみる
パッケージを展開すると、コンパイル済みのjar一式が取り出せます。主に利用するのは以下のディレクトリに格納されているjar。- lib/shared
- lib/providers/eucalyptus
で、これらをclasspathに追加してあげると、以下のような流れでDasein Cloud APIを使っての情報取得ができるようになります。
- org.dasein.cloud.ProviderContextインスタンスにクラウドへのアクセスに必要な設定情報を詰める。
- アクセス対象に応じたorg.dasein.cloud.CloudProviderの実装クラスを生成する。
- CloudProvider.connect(ProviderContext)する。
- CloudProviderから各種情報アクセス用のサービスインスタンスを取得していじくり回す。
実際のコードとしてはだいたいこんな感じ。
import org.dasein.cloud.CloudProvider; import org.dasein.cloud.compute.ComputeServices; import org.dasein.cloud.compute.MachineImage; import org.dasein.cloud.compute.MachineImageSupport; import org.dasein.cloud.euca.Eucalyptus; ... ProviderContext ctx = new ProviderContext(); ctx.setAccountNumber(getProperty("EC2_USER_ID")); ctx.setAccessPublic(getPropertyBytes("EC2_ACCESS_KEY")); ctx.setAccessPrivate(getPropertyBytes("EC2_SECRET_KEY")); String url = getProperty("EC2_URL"); if (url != null) { final String SERVICE_NAME = "/Eucalyptus"; if (url.endsWith(SERVICE_NAME)) { url = url.substring(0, url.length() - SERVICE_NAME.length()); } } ctx.setEndpoint(url); ctx.setRegionId("Eucalyptus"); ctx.setX509Cert(getPropertyBytesFromFile("EC2_CERT")); ctx.setX509Key(getPropertyBytesFromFile("EC2_PRIVATE_KEY")); CloudProvider provider = new Eucalyptus(); provider.connect(ctx); ComputeServices services = provider.getComputeServices(); MachineImageSupport imageService = services.getImageSupport(); Iterable<MachineImage> images = imageService.listMachineImages(); for (MachineImage image : images) { // イメージごとの処理 }
見ての通り、Eucalyptusに対応するにはnew Eucalyptus()のところを別のクラウド向けの実装クラスに差し替えてあげればよいという寸法(ProviderContext設定の手順は調整しなければならないけど)。やったね。
地雷
と思ったものの、動作確認すると何かがおかしい。
ど うやらdasein-cloud-eucaのVirtualMachine.getProviderOwnerId()の実装が、describe instancesの結果からではなく、アクセスしている本人(ProviderContext.setAccountNumber された値) を返すようになっていた模様。Amazonではそれでいいと思うわけですが、EucalyptusってマルチユーザだからReservationから ownerIdとらないとダメだよね?多分。
ということでdasein-cloud-eucaだけsourceforgeからsvn checkoutしてアレコレします。Mavenベースのプロジェクトだから比較的楽。
org.dasein.cloud.euca.compute.Instance.toVirtualMachine(org.w3c.dom.Node instance)の server.setProviderOwnerId(provider.getContext().getAccountNumber()); なる行の下に以下のコードを書き足してあげる。(適当)
NodeList siblings = instance.getParentNode().getParentNode().getChildNodes();
for(int i = 0; i < siblings.getLength(); i ++) {
Node sibling = siblings.item(i);
if(sibling.getNodeName().equals("ownerId")) {
String value = sibling.getFirstChild().getNodeValue().trim();
server.setProviderOwnerId(value);
}
}
で、あとはmvn compile jar:jar みたいにしてあげると所望の情報が得られるようなjarファイルを得ることができます。これを先のlib/providers/eucalyptusのものと置き換えてあげればひと安心。
Muninの流儀にしたがってみる
Muninは /etc/munin/plugins
ディレクトリに実行ファイルを置いてあげると勝手にそれをプラグインとして認識してくれます。この実行ファイルが最低限以下のように振る舞うようにしておくとあとはMunin masterさんとMunin nodeさんが協力してデータ収集、グラフ描画などしてくれます。
引数にconfigが指定された場合、グラフの描き方を標準出力に吐き出してあげるようにします。詳しくは protocol-config 参照。
graph_title Images on Eucalyptus graph_category eucalyptus graph_args --lower-limit 0 admin.label admin admin.draw AREASTACK TESTUSER1.label test1 TESTUSER1.draw AREASTACK TESTUSER2.label test2 TESTUSER2.draw AREASTACK
引数に何も指定されなかった場合、グラフの値を標準出力に吐き出してあげるようにします。
admin.value 9 TESTUSER1.value 3 TESTUSER2.value 8
こんな振る舞いをするJavaプログラムを作成し、/etc/munin/plugins/以下にこのJavaプログラムを キックするようなスクリプトを書いてあげます。で、/etc/init.d/munin-node restartして少し待つとこんな感じのグラフが作成されはじめます。
テスト環境とは言え少しキーワードが入っていたのでマスクしてありますが、上のTESTUSER1だとかTESTUSER2だとかがグラフ中に項目として現れるようになります。
上は「誰が何個イメージを持っているの?」のグラフで、こんな感じで「今誰がインスタンスを使っているの?」とか「今どんなイメージがインスタンスに使われているの?」みたいなことがわかるグラフも作ってみました。画像はちょっとした負荷テストの最中の様子。
とまあこんな感じで、調査~実装だいたい正味4~5時間くらいでまあなんかそれっぽいものができるわけです。
つ くづく感じるのは、Eucalyptusみたいな複数の要素の合わせ技みたいなものを健康的に動かし続けるためには結構いろいろと目を配ってあげないといけないですねえ、というところです。面白いからこそ、気をつけてあげないと希望から絶望への相転移でうんたらかんたらしてしまうわけです。