re:Inventの展示ブースだったのですが、その後日本国内で開かれたCouchconfに参加して同社のエンジニアと話したりする中でどんどん親しみが湧いてきて、早速試してみたくなりました。日本での知名度はまだまだあまり高くなさそうだし、日本語の情報もまだまだ少なそうなので、知名度向上の一助になればという思いも含め、書いています。インストールについてCouchbaseのインストールですが、特に難しいことは無いと思います。OS向けのダウンロードリンクが表示されたりするので楽々感たっぷり。クラスタリング等試したいですし、それを考えるとパッケージ入れたノードをいくつも作るのはめんどくさいですし、どのポートを開けないと動かないとかとりあえず試すだけなのに考えるのはいやです。Marketplaceでおもむろにcouchbaseとたたいてみました。無料でインストール済みのEC2インスタンスが1-clickで立ち上げられるというわけです。これで立ち上げましょう。Editionならライセンス費はかからない模様。それを選んで進みます。Continueをクリックして次の画面へ。(できればt1.microで行きたかったのですが、どうもt1.microだとサーバは立ち上がるものの、セットアップ途中からスペック不足らしく、まともに動作しません。m1.smallが選べればちょうどいいのですが。try...)これだけでセットアップ済みのCouchbaseノードが立ち上がります。嬉しいのはセキュリティグループ(EC2インスタンスに設定するファイアウォールのテンプレートのようなもの)もCouchbaseにあわせて最初から設定されているので、必要なポート番号について悩む必要もなく、ポート全通しのような暴挙に出る必要もなく、サーバが立ち上げられます。(昔は1つソフトウェアを試すだけで大変でしたが、いい時代になったものですね。)下記のような画面が出れば完了です。上記画面にはこの後のインストラクションなどが書いてあってとっても親切。Software”と書いたリンクをクリックしましょう。Software”を選びます。すると何と言うことでしょう!既にCouchbaseのWebコンソールの中です!繰り返しになりますが、いい時代になったものですねぇ。ログインしてみましょう。<起動したEC2インスタンスのID>パスワードはわかりにくいので要注意です。起動したEC2インスタンスのIDを調べて入力して下さい。1つ手前のページに出ているi-XXXXXXXというやつがそれです。わからなければAWSのマネージメントコンソールで確認しましょう。ログインすればもうそこはCouchbasenの管理用GUI。このコンソールを使えばデータ用のバケットを作成したり、クラスタ内の各ノードのステータスを管理したり、Viewを管理したり、クラスタにノードを追加したり、何でも出来ます。クエリを試す為のサンプルバケットを追加することもコンソールから簡単に出来ます。選び、beer-sampleやgamesim-sampleにチェックを入れて、Createを押せばサンプルデータが読み込まれたバケットが出来上がります。試しにもう1つ同じようにインスタンスを追加して、そのインスタンスと2ノードでクラスタを組んでみましょう。同じ手順でもう1つインスタンスを起動。Servers”のボタンを押します。Passwordを聞かれるので入力します。21100番ポートと通信出来る必要があるので、セキュリティグループを調整しておきましょう)これだけで何と2台のノードを含むクラスタの設定が完了です。後はRebalanceが行われれば2台で負荷を分散し合う形になります。下記の図はRebalancingを手動でキックした際の様子。Couchbaseのクラスタのノード間にはマスタ/スレーブの関係はなく、すべてのノードが同等のピアになっています。そのため、どのノードにログインしてもクラスタのマネージメントが出来ます。クライアントからはライブラリにクラスタのノードを渡しておけば、後はうまくやってくれるというわけです。kentiestEC2は非常に自由度が高いので、好みのOSを使って自由にアプリケーションやミドルウェアを利用可能ですが、レイヤが下がれば下がるほど、物理サーバとは環境が違うことを実感する場面が出てきます。その1つがIPブロードキャスト、IPマルチキャストが使えないことかと思います。ユニキャストのみなんです。VPCでサブネットを区切ったとしても、その中でブロードキャストやマルチキャストが出来るわけではないんです。驚かれる方も多いところです)クラウド環境という物理的なリソースを共有する環境でブロードキャストが出来てしまうと、他のユーザに影響を与える可能性が出てくるのである意味出来ないのは納得です。そのため、ブロードキャストやマルチキャストを使ったDiscoveryプロトコルや、Keepaliveプロトコル等々はそのままでは使えません。多くの方はそれを考慮して使うソリューションを選んでいるかと思いますが、ちょっと工夫すればメッセージング程度の利用には耐えるようなブロードキャストをEC2でも用いることが出来ます。それが本日のお題です。そもそもIPブロードキャストとIPマルチキャストってIPのブロードキャストやマルチキャストは特別なIPアドレス宛に送られたパケットをサブネット全体あるいは指定されたマルチキャストグループ宛に送られますが、L2がEthernetの場合は、IPブロードキャスト・IPマルチキャスト共に、Ethernetのブロードキャストフレームに包まれて送信されます。IPブロードキャストもIPマルチキャストも、Ethernetの上では同じ扱いです。このEthernetのブロードキャストのフレームはEC2では送信されないというのがどちらも使えない理由です。「でもユニキャストは送れるんだから、送りたい相手に全部順番に送りつければいいんじゃない?」まさにその通り。それをやってしまって、IPブロードキャスト・IPマルチキャストをEC2上で出来るようにしてしまおうというわけです。(VPCの外でEC2を使うことをこう呼ぶようになりました)だと、L2はブラックボックスになっていて、L2のアドレスを使って宛先制御という概念がありません。-aとかたたいてみると、見慣れない出力が返ってくることに気づくと思います。fe:ff:ff:ff:ff:ffという普通じゃないMACアドレス宛にすべてのフレームが送られる形となり、下でハイパーバイザーによってL3のヘッダを見ながらルーティングがされていくものと思われます。Interface)があることからも推測される通り、この辺りの仕様が違っていて、ENIにつくMACアドレスを使ってパケットのスイッチングが仮想的になされるようになっています。-aの出力を見てみると、そこには見慣れた光景が広がっています。いうことは、L2のアドレスを使ってごにょごにょすることで、パケットの宛先をコントロール出来るわけです。Return)なロードバランサを作ったり、うまくやればVRRPみたいなのも動くかも、という感じです。本題のブロードキャストについても、パケットを複製して、同一サブネット上のアドレスに対してそれぞれ送りつけるようなコードを書けば出来る、という話になります。いうわけでやってみたこんな感じのコードを書いてみました。上記のコードは、標準入力からMACアドレスのリストを受け取り、Ethernetのブロードキャストフレーム(最初のバイトの1ビット目が1)をキャプチャしたら、それを受け取ったMACアドレスのリスト分複製して、宛先をリスト中のそれぞれのMACアドレスに書き換えながら送信するというものです。これだけのコードでEthernetのブロードキャストを動作させられます。実際にこのコードを動作させながら、ブロードキャストpingを送ってみた結果がこちら。SDKを使いながら、同一サブネット上のENIのリストを取得して、そのMACアドレスのリストに対して、上記のようなコードを実行すれば特に手で設定することなく利用可能です。そんなコードをsupervisordで管理しながら実行すれば結構実用的になるんじゃないかと思ってます。宛先分パケットを送り直すので、大量のブロードキャストメッセージが発生するユースケースでは無理が出てくるでしょうが、メッセージングに用いるだけならいいんじゃないかと。そのうちこれを使いながら何か動かしたよ〜という記事を書こうと思います。kentiest先日「EC2でパケットをミラーリングしたい時ー」に書いたEC2インスタンスでパケットをキャプチャして別のコレクションポイントに送る構成を実装する方法について書いてみたいと思います。インバウンドのパケットだけコピー&リダイレクト出来ればいい場合まず、EC2インスタンスに入ってくるインバウンドのパケットだけをミラー&リダイレクトするのでしたら話は簡単ですので、この場合について書いておきます。この場合であれば、iptablesのteeというターゲットを使えば簡単に実行出来ます。下記のようにすればTCPの80番ポートで受信されるパケットのコピーを作って指定したIPアドレスに宛先を付け替えて送り出すことが出来ます。B&gt;ちなみに、インバウンドのパケットだけで良ければと註釈したのにはわけがあります。次の図を見ればわかるかと思いますが、teeを使った場合、宛先IPアドレスを書き換えてしまうので、アウトバウンドのパケットにこれを適用すると、リクエスト元のIPアドレスがパケットから失われてしまい、アクセス解析等を行いたい場合には使えない内容になってしまうのです。(黄色がクライアントのアドレスだとすると、それがコレクタには届かない)両方向のパケットを宛先と送信元含めてキャプチャしたい場合はteeでは役不足となります。別の方法としては、パケットのコピーを作った後、L2で宛先を書き換えてコレクタに送るという手があるかと思います。この場合、上記の問題は起きませんが、コレクタとキャプチャポイントが同一サブネットにいる必要があること、という条件が付きます。サブネットが異なれば当然L2フレームを届けることは出来ませんので。EC2-Classicではそもそも出来ません。L2はインスタンスからは見えないブラックボックスとなっている為です。arpコマンドの出力例。fe:ff:ff:ff:ff:ffというアドレスがプロキシーARPのようになっていて、そこにすべてのパケットが送られるようになっているのですね。L3でトンネルしてコレクションポイントに集めるサブネット越えもしつつ、送信先・送信元アドレスを残したままパケットを別の宛先に送りたいとすると、やはりトンネルしかなくなってきます。いえ、オーバーヘッドは最小限にしたいですし、出来れば特別なソフトウェアを使うのも避けたい、カーネルに処理をさせたい、等々考えると自ずと選択肢は狭まってきます。ここで取り上げるIP-in-IPは上記のようなポイントを考慮すると1つよい選択肢だろうと思います。その名の通り、IPパケットを別のIPパケットのペイロードとして送る仕組みです(RFC1853)。これを使えば、次の図のようにうまいことコレクションポイントにパケットを集めることが出来ますし、キャプチャポイントにもコレクションポイントにも特別なソフトウェアは必要ありません。一方向の転送しかしないことを活かして、複数あるキャプチャポイント側のトンネルエンドポイントにすべて同じIPアドレスを指定すれば、コレクションポイント側では単一のトンネルインターフェースで全パケットを受け付けることが出来ます。redirect)アクションを使えば特定のパケットを指定したインターフェースに再送出来るので、トンネルインターフェースを作った後はその設定を追加すればいけるはず。設定例は次のような感じ。orz...どうも送信するパケットをトンネルインターフェースに流そうとすると逝ってしまわれるようで、受信したパケットのみを流す(上記設定の前半)分に関しては特に問題なし。トンネルインターフェースでないネットワークインターフェース(eth1やlo)に流すと、受信・送信パケットともに問題なく流れます。EC2インスタンスでも物理PCでも試したところ同じ現象が起きるので、どうやらLinuxカーネルが原因っぽい。パケットがループしているということも考えたけど、それにしては受信側に1つもパケットが流れてこない不思議。トンネルインターフェースから出るパケットが再びeth0を通らないような設定にするとOSがハングアップしないことを確認。これでパケットをキャプチャ出来るのでしてみることに。3.こちら、IP-in-IPのトンネルインターフェースにtcpdumpを走らせたところなんですが、本来パケット先頭にあるはずのIPヘッダが、赤い四角のところから始まっているのです。octetsの不可思議なゴミが。おー、なんと!Ethernetのヘッダじゃないですか!よく見ればご丁寧にMACアドレスらしきバイト列の後にEthernet的に次に続くのはIPヘッダと書いてくれてます。|という状態になっているということ。わかったはいいけど、なぜ付いているのかは謎のまま。tcを使ってingress以外のルールでトンネルインターフェースに出したときにのみ生じる現象のようで。カーネルのバグですかね。OSがハングアップしたのも、このなぜかIPヘッダの後ろにEthernetヘッダが続くパケットを処理出来ずにカーネルが刺さったのが原因かと。カーネルのデバッグまで出来たら時間を見つけてやりたいところですが、一旦コンセプトを確認する為に、簡単なコードを書いて確認することにしました。これで無事にコレクションポイントでIP-in-IPのインターフェースでキャプチャを行うことで、期待通り複数のキャプチャポイントでキャプチャしたパケットを集めることが出来ることを確認出来ました。出来ればtc周りのカーネルのコードを見て問題を直してやりたいと思います。Sundance.投稿先:キャンセル。