Serf

障害の検知と、イベントハンドラーを行えるhashicorpのツール。
概要はこちらがわかりやすいです。
http://gihyo.jp/admin/feature/01/serf-consul

NAT冗長化

最近はAutoScalingによる冗長化もあるが、
切り替わり時間を短くしたいためActive/Standbyによる冗長化を実装。

Serfにより障害を検知し、APIを使用しRouteTableを切り替える。

Serf実装

Active側が正常であれば、常に経路を寄せるようにする。
Standby側はActive側の障害を検知した際にRouteTableを書き換える。
また、疎通間隔を4秒とし、タイムアウト12秒設定することで最長の障害時間を12秒にする。

オプション等は以下が参考になります。
https://www.serfdom.io/docs/agent/options.html
http://qiita.com/zembutsu/items/1e2cddd0a424ef7a4895

Serf Active
{
  "node_name": "nat1",
  "enable_syslog": true,
  "tags": {
    "role": "nat"
  },
  "reconnect_interval": "4s",←疎通間隔は4秒
  "reconnect_timeout": "12s",←タイムアウト検知12秒
  "tombstone_timeout": "12s",←タイムアウト検知12秒
  "event_handlers": [
    "member-join=ha-nat -R [変更するRouteTableのTagName] -N 0.0.0.0/0 -r ap-northeast-1 >> /var/log/ha-nat.log 2>&1"
  ]
}
Serf Standby
{
  "node_name": "nat2",
  "enable_syslog": true,
  "tags": {
    "role": "nat"
  },
  "reconnect_interval": "4s",
  "reconnect_timeout": "12s",
  "tombstone_timeout": "12s",
  "start_join": [
    "Active側のPrivateIP"
  ],
  "event_handlers": [
    "member-failed,member-leave=ha-nat -R [変更するRouteTableのTagName] -N 0.0.0.0/0 -r ap-northeast-1 >> /var/log/ha-nat.log 2>&1"
  ]
}
initスクリプト

zembutsuさんのスクリプトを使わせて頂きました。
lockfile等をちょこっと直して使ってます。
https://gist.github.com/zembutsu/7640108

RouteTable書き換えスクリプト

BotoによるRouteTable操作を実装しました。
理由としては、AWSで提供するNATインスタンスはAmazonLinuxのため、
botoであればすでに環境は整っているので追加のインストールは必要なくなります。

https://github.com/SatoHiroyuki/ha-nat-script/blob/master/ha-nat

ha-nat -R [変更するRouteTableのTagName] -N [書き換える経路(Cidr込み)] -r [リージョン]

起動

Active側のサービスを先に上げる。
その後、Standby側のサービスも上げる。

$ sudo /etc/init.d/ha-serf start

障害試験

数回試験しましたが最長で、
Ping1秒間隔の障害試験で切り替わり時に8パケットロスとなり8秒ダウン。

--- 8.8.8.8 ping statistics ---
42 packets transmitted, 34 received, 19% packet loss, time 42087ms
rtt min/avg/max/mdev = 2.181/2.454/2.867/0.176 ms

その他、タイミングによりますがこれよい短い場合もあります。
尚、両方が正常である場合のStandbyからActiveへ戻す際のパケロスはなし。

元記事はこちら

Serfで実装するHigh Availability NAT