SerfでCDP実装 ~ HA-NAT編|アドカレ2013 : CFn #11
こんにちは。望月です。
このエントリは、CDP Advent Calendar 11日目 および Classmethod CloudFormation Advent Calendar #11 となっております。
CDP Advent Calendarの前日は、@oko_changさんのCustomize Scaling Metrics Pattern、
CloudFomration Advent Calendarの前日は、あけりさんの
えっ? ElasticSearchってAWSのサービスじゃなかったんですか!?|アドカレ2013 : CFn #10でした。
CDPアドベントカレンダーに参加することになった
昨日、SAP Japan株式会社様の会場にて、弊社AWSチーム主催の勉強会が開催されました。そちらの詳しい様子は【AWS勉強会】CM re:Growth Developers.IO Meetup 01 を開催してきた #cmdevioを御覧ください。
その中で、CloudFormationとSerfで作る全自動インフラというタイトルで発表させて頂きました。
上記の発表をしたところ、勉強会に参加して頂いていた@maroon1stさんに声をかけていただき、CDP Advent Calendarにも参加させていただくこととなりました。
High Availability NATパターン
High Availability NAT(以下HA-NAT)は、CDP(Cloud Design Pattern)の一つです。
この実装には様々な方法があります。corosync + pacemakerやkeepalivedなどで死活監視を行い、どちらかに異常が発生した際にProtected SubnetのRoute Tableを書き換えます。
今回はSerfを使ってHA-NATを実装してみました。Serfについての簡単な説明は以前私が書いたブログを御覧ください。
さっそくデモ版を起動してみましょう!
HA-NATでは、NATインスタンスからRouteTableを書き換えるため、その権限を持ったIAM Roleを割り当てる必要があります。
このテンプレートではPowerUserRoleを作成しています。
パラメータ名 | 入力 | デフォルト |
AccessFromCIDR | SSH接続の接続元CIDR | 0.0.0.0/0 |
AZ1 | 利用するAZ | ap-northeast-1a |
AZ2 | 利用するAZ | ap-northeast-1c |
KeyName | SSH KeyPairの名前 | - |
実装
Serfの設定ファイルは/etc/serf.confとしました。わずか5行です!(jsonなので1行でもかけますw)
{ "role" : "nat-i-6de81d6a", "event_handlers" : [ "member-failed,member-leave=/opt/serf/ha-nat.sh >> /var/log/serf-event.log 2>&1" ] }
member-failed, member-leaveが発生した際に、Route Tableを書き換えるシェルスクリプト/opt/serf/ha-nat.shが実行されるという仕組みです。member-failedが発生した時には、そのインスタンスのロールが標準入力から渡ってくるので、それを利用してスクリプトを実行します。
シェルスクリプトの内容は以下の通りです。冒頭のインスタンスID取得の部分はSerfに特化したものですが、それ以外の部分はSerf以外でHA−NATを実装する際にも使えると思います。
#!/bin/bash export AWS_DEFAULT_REGION=ap-northeast-1 # role format : nat-{instanceid} while read hostname ip role do peerinstanceid=$(echo ${role} | sed -e 's/nat-//') done myinstanceid=$(curl http://169.254.169.254/latest/meta-data/instance-id) routetableid=$(aws ec2 describe-route-tables | jq -r '.RouteTables[] | select(.Routes[].InstanceId == "'${peerinstanceid}'") | .RouteTableId') if [ -z "${routetableid}" ]; then echo 'no failover executed' exit 0 fi aws ec2 delete-route --route-table-id ${routetableid} --destination-cidr-block 0.0.0.0/0 aws ec2 create-route --route-table-id ${routetableid} --destination-cidr-block 0.0.0.0/0 --instance-id ${myinstanceid}
実践編
さて、実践編では既存のVPCにHA-NATを組み込みます。
このテンプレートは、既存のVPCのルーティングを書き換えます。取り扱いには十分注意してください。
パラメータ名 | 入力 | デフォルト |
AccessFromCIDR | SSH接続の接続元CIDR | 0.0.0.0/0 |
VpcId | VPCのID | - |
VPCCidr | VPCのCIDRアドレス | - |
KeyName | SSH KeyPairの名前 | - |
PublicSubnet1 | 1つ目のNATインスタンスのサブネットID | - |
PublicSubnet2 | 2つ目のNATインスタンスのサブネットID | - |
ProtectedRouteTable | ProtectedRouteTableのID | - |
まとめ
前回の記事ではSerfの紹介だけでしたが、少し実践的な使い方ができたかと思います。この他にも色々なCDPに応用できると思いますので、是非皆さんで使っていきましょう!
明日の記事にもご期待ください!最後に一つ。
CDP Advent Calendarは明日(以降)書いてくれる方を絶賛募集中です!