AWSでAZ障害が起きたのでなるべく影響を受けない構成の考えを書いておく
AZ障害は受け入れるしかないクラウド時代のインフラ
ただの日記。 今日の昼、AWSを利用している人たちは大変だったところもあると思う。 AZの一つが丸々機能しなくなる大きなAWSの障害があり、AWSを利用して運用されていたサービスは多かれ少なかれ影響を受けることになった。
完全に雰囲気で書いてしまうが、今回のAZ障害で影響を受けたサービスは思ったより多かったように感じる。 というのもAWSではアベイラビリティーゾーンの障害は発生するものと考え、本番運用するのであれば、マルチAZ構成を取るのがベストプラクティスとされているので、 マルチAZ構成を取っていれば影響なんてないんじゃないの普通、と思ってしまうと思う。 インフラ屋さんでもそう思ってしまうし、インフラ屋さん以外ならなおさらなんで重くなるのかわからないと思う。
幸い自分の運用しているサービスでは影響が軽微だったので、完全に想像にはなってしまうけど、起こりがちなケースを考えてみる。
障害が長く続いてしまう理由はなんだろう
マルチAZ構成を取らずに全落ちしてしまったケースは残念として、マルチAZな構成を取っていても長く影響が出てしまったサービスもあると思う。 自分でもうっかりやってしまいそうな、マルチAZにしていても障害につながってしまうケースを考えてみる。
2つのAZに配置していて全体の負荷が50%を超えていたケース
これが一番ありがちかなと思う。 2つのAZの構成になっているので、片方のゾーンが落ちても1つのゾーンでは動作するし問題ないだろう、という話なのだが待ってほしい。 2のAZしか使っていないなら、片方のゾーンが落ちた場合に使えるマシンリソースは一気に半分になってしまう。 ということは当然全体の負荷が50%近いか超えていれば当然リソース不足になってしまう。
これはお財布と相談になるがよく使われているサービスほどキャパシティには余裕を持っておかないといけない。 特に低コスト化のために2AZで運用していると50%失われることを覚えておかないといざゾーン落ちした場合に、一気に高負荷になってしまう。
例えば3AZを使うのも良い方法で、33%のリソースが失われるだけで済むので、2AZと比べればリソースの不足には陥りにくい、かもしれない。 この場合でも全体で66%くらいの負荷がかかっているとダメになるだろうから、余裕を持ったキャパシティにしておくというのは変わらない。
2AZで動かしているケースで別のゾーンで簡単に起動し直せる仕組みづくりができていない
サボってるわけではないけど、うっかりやりがちかもと思う。 AZのa/c/dのうちaとcを使うことを前提にしてオーケストレーションツールの設定を書いてしまっていて、簡単に別のゾーンを使い始められないとか。 仮に切り替えられるように書かれていたとしても、ゾーンを切り替えるテストまではやっていなくて、問題がおきた場合に準備なく切り替えが必要になってしまうと、 本当にこれは動くのかと不安になってしまうこともある。流石にゾーン切り替えとか普段からやるものでもないし、検証もしなさそうな気はする。 普段から起きるようなトラブルでないと練習の機会もなく、習熟度も低くなってしまう。これは仕方がない面もある。
結局のところ、2AZでの運用はよくないということになる。お財布と相談とは書いたけど、例えばどうしても2台構成にしたい場合でも、 ゾーンの配置は面倒でも3つのゾーンを意識してサービスごとにばらけさせて2個選択するようにするとか、別のAZに自然に切り替えられるように書いておくとか 構成を書く時点で細かなことだけど準備しておかないとダメなんだろうなとは思う。
オートスケールがうまく動かない
オートスケールはうまく組めていれば、よしなにサーバが起動してゾーン落ちして縮退したサーバの代わりを用意してくれる。 そうとはいえ、負荷が増えた場合に次々にサーバを起動されてしまうとお財布には厳しいので、上限を決めてしまって必要な台数を確保できないとか。
今回厄介だなと思った点はヘルスチェックに失敗して退役させるべきサーバが通常の停止で終了できず強制終了の指示を出してもなかなか終了しなかった点で、 もしかするとこの影響で思ったように切り替えが行かなかったケースがあるのかなとは思う。 関連でAWSのAPIも応答が悪く、強制終了もなかなか受け入れてもらえなかったり、コンソールですらも表示がされなかったり、エラーになったりすることがままあったので、 自動化していたとしても、思ったようにスケールアウトできなかったり、自動化プログラム自体がうまく動作しなかったのかも。
スケールアウトに関連してもう一点あって、AZダウンの影響で多くのインスタンスが使えなくなり、代わりに別のゾーンで多くの起動要求があったため、 起動リクエストのキャパシティに影響があったケースも少しあるんじゃないかな。 この場合でも自動起動を考えていたインスタンスが不足して起動できず回復に時間がかかるというのはありそう。
問題がおきたマシンの切り離しの仕組みがうまく動かない
自然に組んでも切り離しのことは考えているだろうし、例えばALBやRoute53のヘルスチェック機能などで自動化もするだろうけど設定忘れというのはあるかもしれない。 ALBやNLBを通さずにEC2をそのままインターネット側に公開する構成を取るケースだと、DNSラウンドロビンなどを設定するケースもありそうで、 その場合にはTTLの設定を長くしすぎてしまうと、DNSベースの切り替えには時間がかかってしまう。 EIPをつけておき新しく同等のEC2を起動してEIPの付け替えをするのが簡単そうではあるが普段から考えていないとハマりそうな気はする。 普通なWebなら普通にALBを通して死活監視しておくのが簡単で問題にもならなさそうとは思うけど、色々な事情で通せない理由があるのかもしれない。
データベースについて
RDSやAuroraをマルチAZにするのは当然なので、DBへの影響は今回の障害では少なかったのかなと勝手に思っている。 フェイルオーバーは数分程度で切り替わるため、マルチAZ構成を取っていれば数分の書き込みエラーを許容できるなら大きな障害にしては傷は浅く済んだとみることできる。
死活監視について
そういえばと思い出したのが今回の障害でCloudWatchの動作にも影響が出ていたかもという点。 死活監視にCloudWatchを使うケースはままあるとは思っていて、今回のように影響範囲が広いものだとAPIの動作も不安定になり、 CloudwatchのようにAWSの仕組みに乗って動く監視だと、そもそもうまく動作しているか取れなくなるのは不安というのがあった。 監視については同じインフラ内での監視だけでなく、別のインフラから監視する仕組みもあるのがよいかなとは思った。
終わりに
色々書いたけど、オンプレ環境でもラック落ちやスイッチ落ちなどで同じようなことは考えていたし、結局のところ基礎になる考え方は昔からあんまり変わっていない印象で、 クラウド環境の方が道具は自前で用意しなくても用意されていて便利、くらいの印象しかないので、基本に立ち返って安定して動くインフラを用意しておきたいですねという感じです。
ぶっちゃけた話でいうと今回困った理由で他にあったら聞いてみたいので紹介していただけると嬉しいというのはあります。
現場からは以上です。