EC2でブロードキャスト/マルチキャスト

EC2は非常に自由度が高いので、好みの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上で出来るようにしてしまおうというわけです。

L2でごにょごにょする

前のエントリ「コピー&リダイレクトパターン(仮)実装編」でちょっと触れましたが、EC2-Classic (VPCの外でEC2を使うことをこう呼ぶようになりました)だと、L2はブラックボックスになっていて、L2のアドレスを使って宛先制御という概念がありません。

arp -aとかたたいてみると、見慣れない出力が返ってくることに気づくと思います。

ec2classic-arp

fe:ff:ff:ff:ff:ffという普通じゃないMACアドレス宛にすべてのフレームが送られる形となり、下でハイパーバイザーによってL3のヘッダを見ながらルーティングがされていくものと思われます。

ところが、EC2-VPC(VPC内でEC2を使うことをこう呼ぶようになりました)の場合、ENI (Elastic Network Interface)があることからも推測される通り、この辺りの仕様が違っていて、ENIにつくMACアドレスを使ってパケットのスイッチングが仮想的になされるようになっています。

arp -aの出力を見てみると、そこには見慣れた光景が広がっています。

ec2-vpc

と、いうことは、L2のアドレスを使ってごにょごにょすることで、パケットの宛先をコントロール出来るわけです。

すなわち、ebtablesでEthernetレベルのNATをしたり、DSR (Direct Server Return)なロードバランサを作ったり、うまくやればVRRPみたいなのも動くかも、という感じです。

本題のブロードキャストについても、パケットを複製して、同一サブネット上のアドレスに対してそれぞれ送りつけるようなコードを書けば出来る、という話になります。

というわけでやってみた

こんな感じのコードを書いてみました。

上記のコードは、標準入力からMACアドレスのリストを受け取り、Ethernetのブロードキャストフレーム(最初のバイトの1ビット目が1)をキャプチャしたら、それを受け取ったMACアドレスのリスト分複製して、宛先をリスト中のそれぞれのMACアドレスに書き換えながら送信するというものです。

たったこれだけのコードでEthernetのブロードキャストを動作させられます。

実際にこのコードを動作させながら、ブロードキャストpingを送ってみた結果がこちら。
Screen Shot 2013-03-24 at 6.29.34 PM

実際にはAWS SDKを使いながら、同一サブネット上のENIのリストを取得して、そのMACアドレスのリストに対して、上記のようなコードを実行すれば特に手で設定することなく利用可能です。さらに、そんなコードをsupervisordで管理しながら実行すれば結構実用的になるんじゃないかと思ってます。もちろん、宛先分パケットを送り直すので、大量のブロードキャストメッセージが発生するユースケースでは無理が出てくるでしょうが、メッセージングに用いるだけならいいんじゃないかと。

そのうちこれを使いながら何か動かしたよ〜という記事を書こうと思います。

EC2でブロードキャスト/マルチキャスト」への1件のフィードバック

  1. ピンバック: VPCサブネットでNeighbour Discovery | Techy? Geeky? Whatever!

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中