natインスタンスの冗長化

こんにちは。プラットフォームの小宮です。

他を冗長化してもnatインスタンスを冗長化してないと、
プライベートセグメントでHAしてるサーバ達がAWSのAPIサーバと通信できなくなって詰むなあと思いまして、
先人の皆さまの記事を参考にして以下のとおりにしました。

・なんとなくどうするか検討

AmazonLinuxで作っちゃったので、たぶんHeartbeatとか入れづらいし、そもそもheartbaet使う必要ない気がする。
待機系から監視してaws的にルーティングテーブル挿げ替えるだけでよさそう。

待機系natインスタンスについて、
 作成しておかないと作成と起動とルーティングテーブル作るところもやらないといけないので切替時間が長くなる。
 インスタンス代がかかるけど起動もしたままがいいと思われ。

・とりあえず既存のAmazonLinuxのNATインスタンスの設定をいじるところから


sudoできるようにしてみる

コメントはずす。
他のインスタンスから渡ってsudoできるか確認する

あとnatインスタンスにpythonのツール入れておく

メール送信も設定
AmazonLinuxではsendmailが動いてる模様だった。

ロケールを合わせる

カーネルチューニングを入れる

・natインスタンスとそれをデフォルトゲートウェイにしたルーティングテーブルを別途作っておく

NATインスタンスはAMIをコピーして同じセグメントに作る

作った
i-005a5e02
Source/DestCheckをDisableにしないとRouterTableにルート設定する時の出口にできるインスタンスとして出てこない。

rtb-yyyyyyyy
というルーティングテーブルのDestination0.0.0.0/0(つまりデフォゲ)のターゲットを、
先ほどのインスタンスに指定してAddしておく
この時点でこのテーブルにAssosiationしてるサブネットは存在しない状態。

・とりあえずプライベート側のホストでyahooにpingしながらルーティングテーブルをawsのコマンドで挿げ替えてみる

マニュアルを見てみる

コマンドでのフェイルオーバーを確認する

参考:http://d.hatena.ne.jp/j3tm0t0/20120814/1344971491

確かにスタンバイルートに切り替わったことをマネジメントコンソールからも確認できた。
コマンド単体での切替試験は成功。yahooへのpingが途切れることはなかった。

・フェイルオーバーの条件を検討する

以下を参考に考えると裏側にいるホストが3台くらいyahooとかと疎通が通らなくなったらフェイルオーバとかでいいのではないか。
http://d.hatena.ne.jp/hirose31/20131105/1383623672

serf使うと楽なんじゃないのかな。調べてみる。
メッセージングツールSerfをEC2で使ってみる | Developers.IO
Serf を使ってみた – jedipunkz’ blog
https://dl.bintray.com/mitchellh/serf/
【Serf】v0.2.0 へのバージョンアップと、変わった所を確認してみた | Pocketstudio.jp log3
serf-muninでmunin-nodeの監視自動追加/削除 | Pocketstudio.jp log3
Serf+HAProxyで作るAutomatic Load Balancer – Glide Note – グライドノート

natの冗長化の参考:
NATインスタンス冗長化の深淵な話 – (ひ)メモ
suz-lab – blog: “High Availability NAT”の作成(CentOS6)
cloudpackブログ: (ELBとからめて)Hostヘッダでの振り分けをHAProxyでやってみる
NATインスタンスを冗長構成にしてみた – log4moto

serf入れてみたり調べてみたけど
結果的に新しすぎて情報が極端に少ないようなのでシェルスクリプトで頑張ることに。
(カスタムユーザイベントの例がいまいち少なくて今回の需要に合わない感じがした)

pacemakerでiptablesが落ちた時にF/Oというおなじみのパターンでもいいんだけど、
待機系からssh越しにpingして3つくらいのノードがダメならF/Oというほうが実情に即している模様。

cronで定期実行するかmonとかにするか。
⇒時間もないし簡単だからcronでいいや。

とりあえずpingだからrootで無くても大丈夫なような

natの公開鍵を裏にいるホスト全部の/home/user-op/.ssh/authorized_keysに登録する

こんな感じで確認は可能なのであとはどういうスクリプトを何でどう実行するのかを考えます

・フェイルオーバさせるスクリプトの実行をどうするか考える

完成したスクリプト↓

見ればわかるかもしれませんが敢えて解説すると
hostsからバックセグのチェックするホストを全部取得し、
pingの結果が3台以上のホストでNGな場合にnat02側のルートに再アソシエイトします。
一応sshの接続性チェックをしています。
pingのtargetも3つの中からランダム指定にしたので全滅でない限りは、
 targetに不通でGlobalに出れる状態でf/oはしないでしょう。たぶん。

NAT自体がAPIサーバに到達できなかった場合にはF/Oに失敗しますが、
 完了ロックファイルは作成されて異常終了ステータスが入るので再実行はされません。

定期的にstop/startとかする環境の場合はnatを最後に起動するなど起動順に気をつけないとだめそうで、
natが起動してないとHA組んでる裏側のサーバがAPI通信できなくなってしまうので、
uptimeが数分たたないとcheckが始まらないようにする等の分岐を入れたほうがいいかということで一応いれました。

・テスト結果

pingの疎通が問題なかったためフェイルオーバーしなかった模様。
次はnat01のiptablesでもstopしてglobalにpingが通らない状態にしてf/oするか確かめてみる。

適当なバックセグメントのサーバからpingうちながら実施。

フェイルオーバするときの実行時間は35秒なので毎分実行しても大丈夫ではある。(ホストが増えすぎなければ
バックグラウンドで動かすと並列実行できるとか見かけたけどよくわからなかったので気にしないことにします。
(並列実行とかするとたぶんDoS攻撃ちっくになるので良ろしくないんじゃないのかとも思いました。)
負荷とか実行時間が気になる場合は、全部じゃなくてランダムに選んだ複数のホストでチェックするとかでもいい気がします。
変えるならこんな感じでしょうか。

何も考えずにcron登録すると複数回実行されることを防ぐためにロックファイルを作るようにしたので、
復旧するときにそれを手動で管理する必要があります。

ロックファイルがある状態でテストしてみると変数定義直後に終了します。

参考にしたスクリプトは以下URLに載ってるのです。
NATインスタンスを冗長構成にしてみた – log4moto

個人的に少し気にしているのはyahoo.co.jpにそんなにpingしていいのかどうか。
8.~もgoogleらしいので、まあいいことにします。
こんなの↓もあるようです。あとはjpじゃないyahooにpingしてみるという意見も。
pingチェックサイト(試験運用) – 学術情報ネットワーク(SINET4、サイネット・フォー)

・とりあえず2分おきにcron登録(スタンバイ機にて)

後日修正した↓ので追記します。

以上、見ていただいてありがとうございました。

おすすめ記事