kentiestなんかこの話題が続き過ぎな気もしていますが、EC2でマルチキャストの続きです。いうのも、MTUを超えるサイズのパケットを↑の方法で擬似マルチキャストすると、1台のインスタンスにしか届かないよー、というフィードバックを頂いたのでした。IPフラグメント周りで何か起きている擬似マルチキャストでは同じIPパケットを何度も投げているということから当たりをつけるとするとやはりIPパケットのID周りかなと思って、パケットIDを変えながら送り出すというようなことをやってみました。(IPパケットにはそれぞれIDがついていて、分割されたときには各フラグメントのIDを見ながら再結合するようになっています。)このコードで試すと、MTU越えなパケットで、フラグメントされたとしても期待通り複数ホストで受信できる事が分かりました。変更分は単純で、パケットIDを複製する度に1つずつずらしているのと、それに伴ってチェックサムを再計算しているくらいです。ずらし方は一定なので、パケットが分割されてもフラグメント同士は同一のIDを持ち続けるので関係性は保たれつつ、複製ごとに異なるIDを持つというわけです。(こんなずらし方で直近のパケットとあたる可能性が十分低いのかは要チェック)IPレイヤではパケットのIDを見比べてフラグメントされたパケットを再結合するので、複数同じIDのフラグメントが通過すると、どうやら下のネットワークレイヤでこの再結合がうまくいかなくなるようです。これがフラグメントなしだと通るけど、フラグメントされると通らない原因と言えそうです。試しながら気づいたこととしては、送信側と受信側でフラグメントの切れ目が違うので、恐らく下のネットワークで再結合と再分割を行なっているようです。IPヘッダをいじるとチェックサムを再計算しないといけないのがいやですね。出来ればL2だけで済ませたかった。実はユーザランドのプログラムに頼らずにカーネルだけで処理を完結する方法を編み出していたのですが、この問題に対応する為にもうちょっといくつか試さないといけなそうです。その方法についてはまた近いうちに。kentiestこれまで何度かフレームコピーと送信先MACアドレスの付け替えで擬似的にVPCサブネット内でブロードキャストを実現する話を書いてきました。今日はそれの応用編ということで、いつもマルチキャストが使えないからと素通りされがちだったけど、本当はみんな大好きなVRRPを動かしてみたという話を書きたいと思います。Protocol)とは、仮想IPアドレスを使ったL3ノードの冗長化のためのプロトコルです。ゲートウェイルータやロードバランサなど、複数ノードのトラヒック(すいません、IEICEとかに論文を書いていたときのくせで)が通過するIPノードを冗長化するために利用されたりします。IP、略してVIP)でサービスを行うノード同士でVRRPグループを構成し、グループ内のノードはMasterとBackupの関係を構築します。MasterとなったノードはVIP宛のパケットを受信したり転送したりするとともに、VRRPグループ内のノードにIPマルチキャストでハートビートを送ります。何らかの障害でMasterからのハートビートが途絶えた場合はBackupノードがVIPを引き継いで何事もなかったかのようにシステムを継続動作させるというわけです。そんなわけでマルチキャストが前提なプロトコルなものですから、IPマルチキャスト/ブロードキャストが使えないことで知られるEC2環境では使えないものとされることが多かったかと思います。冗長化が当然な可用性要件が厳しいシステムであっても、です。システム設計の際の選択肢を増やすことが出来ます。検証用のシステム構成としては下図のようにしました。Keepalivedを動かしたインスタンスを2台、その背後に静的なファイルを返すWebサーバ(nginx)を並べています。前段のLVSサーバ達には擬似ブロードキャストの設定をしておいて、IPマルチキャストでお互いコミュニケーション可能にした上で、KeepalivedでVRRPグループを組みます。IP(EC2で利用できる固定グローバル化IPアドレス)を割り当てました。IPに対してパケットを送ると、図の通りにリクエストが流れて行きます。ここでMasterとなっているLVSインスタンスが停止すると、フェイルオーバが起きて、Backupが新たにMasterとなります。実際にMasterのインスタンスを停止させると、期待通りBackupがMasterに昇格することがログなどで確認できました。ARPリクエストによってサブネット内に周知されるので、特に何もせずともVIP宛のパケットが新マスターに送られるようになります。Keepalivedの設定をいつも通りしただけでは、VIPの付け替えが起こらず、フェイルオーバした時点でシステムとしては応答しなくなります。VIPを新マスターのネットワークインターフェースとの紐付けを明示的にVPCに対して設定する必要があります。フェイルオーバ時の目指すべき状態を図示すると次の図のようになります。上記のようにVIPとネットワークインターフェースのマッピングを変えるのはAWSのAPIをたたくことで可能です。下記のようなスクリプトを新マスターで実行することで、VIPとネットワークインターフェースのマッピングを更新して、VIP宛のパケットを新マスターに向けることができます。上記のような内容のスクリプトをVRRPでマスターに昇格した時点で実行するように設定しておけば、期待通りフェイルオーバしてVIP宛のパケットを新マスターが受け取るようになります。Keepalivedの場合の設定例がこちら(末尾のnotify_masterでMaster昇格時の実行スクリプトを指定している)。/etc/keepalived/assign_vip.sh}実際にこれでフェイルオーバを試してみました。実行すると、APIでVPCの設定を書き換えるリクエストを投げて、それが反映されるまでというタイムラグがあるので、ARPを使った実ネットワークでのフェイルオーバに比べればダウンタイムが長くなってしまいますが、数秒といった程度で障害検知からフェイルオーバまで出来るのは魅力的かと思います。まとめというわけで、無事EC2-VPCでVRRPが動いて、フェイルオーバが出来ることまで確認できました。ロードバランサやファイアウォールなど、VRRPでの冗長化が前提となっているソフトウェアをAWSで使う際にはこんな方法も検討してみてはいかがでしょうか?ほんとはこの構成のCloudFormationテンプレートを作ろうかと思っていたのですが、時間の都合でそこまでたどり着いてません。kentiest以前、EC2でブロードキャストができるようにするという記事を書きました。EC2-VPCならL2のアドレスを書き換えてL3以上にタッチせずにフレームの宛先を変えられるので、それを利用して受信ノード数分フレームをコピーしてユニキャストで送るというトリックでEthernetブロードキャストを動かし、結果としてサブネット内のIPマルチキャスト・ブロードキャストを実現するという話です。図に起こしたので貼っておきます。なると、Ethernetブロードキャストをするには、まず同一サブネット内の他インスタンス(厳密に言うとそれにアタッチされたENI)のMACアドレスのリストが必要です。IPホストグループ(224.0.0.1やff02::1など)にpingでも打てば良さそうなものですが、そもそもそのマルチキャストができないのだから本末転倒です。ここはEC2に特化したネットワーク情報の取得方法を取ることにしましょう。AWS上の操作や必要な情報の取得はAPIを通じて可能です。サブネットに関する情報ももちろん取得可能。下記のようなスクリプトを動かせば、同一サブネットに接続されて、インスタンスにアタッチされているネットワークインターフェース(ENI)のリストを取得することができます。(Linux前提ですが)これの出力を先日の擬似ブロードキャストを実現するスクリプトの引数として与えるようなスクリプトを用意すればMACアドレスを調べてわざわざ渡す必要なくブロードキャストが実現できます。自分(インスタンス)が属するリージョンを取得describe-network-interfacesを実行して、VPCサブネットのID、インスタンスにアタッチされているかどうかでフィルタという感じのことをしています。実際に使うときにはこれをたくさんのホストが実行するのは非効率なので、API取得結果をキャッシュするような仕組みを別途用意しておくのが吉かと思います。describe-network-interfacesの結果をDynamoDBに入れておいて、各インスタンスはそこに対して自分のサブネットの情報をQueryするとか。X220に見当たらない事に気づきました。Mixをインプットに指定して録音ソフトを動かせばいいじゃないと思ってました。いえ、なきゃないで巷にはいくらでもソリューションがあるだろうと思って探してみたものの、Google様に導かれて見つかるのは同じように驚き困り果てる人々の姿のみ。Mixのサポートをやめたサウンドカードが多いんだとか。(すべてのサウンドカードでダメというわけではないようです。Mixを有効化出来る場合もあるんだとか。いうソフトウェアを試すことにしました。Mixがない問題を解決してくれるソフトウェアで、インストールすると仮想のオーディオ再生デバイスと、オーディオ録音デバイスが作られます。この仮想デバイスを通すことで、PCから出る任意のサウンドをキャプチャ出来るという仕組みです。Unixのパイプで入出力つないでいく感じをイメージすると近いですかね。Streamingの仮想録音デバイスを設定という感じです。Streamingのデバイスを設定するのが簡単かと思います。下記はそのような設定の例。録音側も設定できなければデフォルトに設定してしまうことも可能です。これでひとまず任意の音声出力の録音が出来るようになりました。なんかWindowsって出来る事がバージョンが上がるにつれて減っていくような。