EC2-VPCでVRRPを動かしてみた

これまで何度かフレームコピーと送信先MACアドレスの付け替えで擬似的にVPCサブネット内でブロードキャストを実現する話を書いてきました。

今日はそれの応用編ということで、いつもマルチキャストが使えないからと素通りされがちだったけど、本当はみんな大好きなVRRPを動かしてみたという話を書きたいと思います。

VRRPとは?

VRRP (Virtual Router Redundancy Protocol)とは、仮想IPアドレスを使ったL3ノードの冗長化のためのプロトコルです。ゲートウェイルータやロードバランサなど、複数ノードのトラヒック(すいません、IEICEとかに論文を書いていたときのくせで)が通過するIPノードを冗長化するために利用されたりします。

ある仮想IPアドレス(Virtual IP、略してVIP)でサービスを行うノード同士でVRRPグループを構成し、グループ内のノードはMasterとBackupの関係を構築します。 MasterとなったノードはVIP宛のパケットを受信したり転送したりするとともに、VRRPグループ内のノードにIPマルチキャストでハートビートを送ります。何らかの障害でMasterからのハートビートが途絶えた場合はBackupノードがVIPを引き継いで何事もなかったかのようにシステムを継続動作させるというわけです。

そんなわけでマルチキャストが前提なプロトコルなものですから、IPマルチキャスト/ブロードキャストが使えないことで知られるEC2環境では使えないものとされることが多かったかと思います。 冗長化が当然な可用性要件が厳しいシステムであっても、です。

そこに多少のオーバーヘッドはあるとはいえ、Ethernetブロードキャストが通るようにしてVRRPを動かすことが出来れば システム設計の際の選択肢を増やすことが出来ます。 なので早速やってみましょう。

検証システムの構成とVRRPの動作確認

検証用のシステム構成としては下図のようにしました。 単一のVPCサブネットの中にLVS + Keepalivedを動かしたインスタンスを2台、その背後に静的なファイルを返すWebサーバ(nginx)を並べています。 前段のLVSサーバ達には擬似ブロードキャストの設定をしておいて、IPマルチキャストでお互いコミュニケーション可能にした上で、KeepalivedでVRRPグループを組みます。

MasterインスタンスにはSecondary IPアドレスとしてVIPを割り当て、そのVIPに対してElastic IP(EC2で利用できる固定グローバル化IPアドレス)を割り当てました。 これにより、平常時は割り当てたElastic IPに対してパケットを送ると、図の通りにリクエストが流れて行きます。

VRRP-normal

ここでMasterとなっているLVSインスタンスが停止すると、フェイルオーバが起きて、Backupが新たにMasterとなります。 実際にMasterのインスタンスを停止させると、期待通りBackupがMasterに昇格することがログなどで確認できました。

EC2-VPC特有の設定

一般的なEthernetの場合は、VRRPでMasterに昇格した時点でVIPとMACアドレスの対応の更新がGratuitous ARPリクエストによってサブネット内に周知されるので、特に何もせずともVIP宛のパケットが新マスターに送られるようになります。(それ以降に参加したノードは通常通りARPリクエストを送って、新マスターがそれに応答することで更新後のVIP-MACアドレスの対応関係を知ることになります)

しかし、EC2-VPCではARPを元にIPアドレスとMACアドレスを対応付けているわけではないので、単にLVS + Keepalivedの設定をいつも通りしただけでは、VIPの付け替えが起こらず、フェイルオーバした時点でシステムとしては応答しなくなります。 VIPを新マスターのネットワークインターフェースとの紐付けを明示的にVPCに対して設定する必要があります。

フェイルオーバ時の目指すべき状態を図示すると次の図のようになります。

VRRP-failover

上記のようにVIPとネットワークインターフェースのマッピングを変えるのはAWSのAPIをたたくことで可能です。 例えば下記のようなスクリプトを新マスターで実行することで、VIPとネットワークインターフェースのマッピングを更新して、VIP宛のパケットを新マスターに向けることができます。

上記のような内容のスクリプトをVRRPでマスターに昇格した時点で実行するように設定しておけば、期待通りフェイルオーバしてVIP宛のパケットを新マスターが受け取るようになります。 Keepalivedの場合の設定例がこちら(末尾のnotify_masterでMaster昇格時の実行スクリプトを指定している)。

vrrp_instance VI_1 {
  state BACKUP
  interface eth1
  virtual_router_id 51
  priority 100
  advert_int 1

  authentication {
    auth_type PASS
    auth_pass 1111
  }

  virtual_ipaddress {
    172.31.24.1 dev eth0
  }

  notify_master /etc/keepalived/assign_vip.sh
}

実際にこれでフェイルオーバを試してみました。 実行すると、APIでVPCの設定を書き換えるリクエストを投げて、それが反映されるまでというタイムラグがあるので、ARPを使った実ネットワークでのフェイルオーバに比べればダウンタイムが長くなってしまいますが、数秒といった程度で障害検知からフェイルオーバまで出来るのは魅力的かと思います。

まとめ

というわけで、無事EC2-VPCでVRRPが動いて、フェイルオーバが出来ることまで確認できました。

ロードバランサやファイアウォールなど、VRRPでの冗長化が前提となっているソフトウェアをAWSで使う際にはこんな方法も検討してみてはいかがでしょうか?

ほんとはこの構成のCloudFormationテンプレートを作ろうかと思っていたのですが、時間の都合でそこまでたどり着いてません。ご要望あれば作りますのでお寄せください(笑)

コメントを残す

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

WordPress.com ロゴ

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

Twitter 画像

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

Facebook の写真

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

Google+ フォト

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

%s と連携中