はじめに
こんにちは、クラウド事業部の上野です。
今回はAWSのバージニア北部(us-east-1)リージョンにて、10月19日午後11:48分(PDT)〜 10月20日午後2時20分(PDT)に発生した障害について調べてみました。(日本時間: 10月20日 15:48~ 10月21日 06:20)
詳しい障害の内容については以下レポートを参考にします。この時の障害について図解することで、AWSの内部構造(あくまで記事から読み取れる範囲の想像)まで理解しやすい記事になればと思います。
※注意点
以下に様々な図を出していますが上記の障害レポートから読み取って独自に作成したものであるため、実際にその通りであるかは分かりませんし、公開情報として調べても特に出てこないものです。あくまで読み取れる範囲で整理しただけのものである点にご注意ください。
障害の内容
大きく以下の流れで障害は発生したようです。
- 10月19日午後11時48分〜10月20日午前2時40分
- バージニア北部(us-east-1)リージョンにおいてAmazon DynamoDBのAPIエラー率が上昇
- 10月20日午前5時30分〜午後2時9分
- バージニア北部(us-east-1)リージョンの一部ロードバランサーにおいてNetwork Load Balancer(NLB)の接続エラーが増加。
- NLBフリートのヘルスチェック失敗が原因で、一部のNLBで接続エラーが増加したため
- 10月20日午前2時25分〜午前10時36分
- 新規EC2インスタンスの起動失敗が発生。午後1時50分までには解決。
障害発生の理由
1. DynamoDBの障害理由
全体の障害の起因となったのはDynamoDBでした。 DynamoDBの障害理由についてですが、まずDynamoDBのDNS管理アーキテクチャについての説明がされており読み取れる限り以下のような構成となっているようです。
- 大きく2つのコンポーネントがあり、DNSプランナーとDNS Enactorが処理の中心にある。
- DNSプランナーは各サービスエンドポイントとロードバランサーの紐付けを行うDNSレコードを生成する。この紐付けはロードバランサーのcapacityチェックを行い都度適切なロードバランサーに切り替えるためDNSレコードプランは定期的に更新される。
- このDNSレコードプランをポーリングして、DNS EnactorがRoute53サービスにDNS更新リクエストを行っている。この時複数のEnactorが同時に更新処理をして不整合を起こさないようトランザクションを貼って更新するような挙動になっている。

障害発生の流れ
1~2. まず一部DNS Enactorが想定外の遅延を発生させ(以下画像だとAZ3)、他のEnactorのDNSプランが先に適用された。

3.上記画像2.の処理でRoute53 へのプラン適用後、AZ3のEnactorが遅延によって遅れて実行されることで古いDNSで上書きされる。
4.AZ1はDNSプラン適用後、クリーンアッププロセスにより古いDNSを削除する。この時3.で登録されたものが削除される。これによってDNS上のレコードが消えてしまった。
5.DNS Enactorは不整合を起こして更新処理が失敗するようになった。

DynamoDBに接続できなくなったのは上記1~5の理由でDNSレコードが削除されて不整合状態に陥り自動回復できなくなったことが原因だった。
2. Amazon EC2の障害理由
上記DynamoDBの障害はEC2にも伝播して影響を与えていたようです。
ここで最初に理解しておく必要があるのはEC2の物理サーバー基盤とEC2にネットワーク設定を伝搬するコンポーネントの存在です。
- Network Manager
- Internet通信, 同一VPC内のEC2との通信, VPC内のネットワーク機器などとの通信設定をEC2に伝搬させるためのもの。
- DropletWorkflowManager
- EC2の物理サーバー群であるdropletsをリースと言うプロセスか何かに紐付けてそれごとにdropletsを管理するもの。

障害発生(1)
今回はこのdropletsのリース確立プロセスにDynamoDBが使用されているせいで、リースチェック失敗->リース切れ扱い → 新規インスタンスの候補から除外という流れで新規EC2が立ち上がらなくなっていた。

その後、DynamoDBが正常に動き始めたことでこちらのプロセスも正常に動き始めるかというとそうはならなかった。
- まず処理しないといけないdropletsが多すぎた結果全て処理しきれずtimeoutが大量に発生。
2~3. timeoutしたタスクはキューに積まれるがキューが増える一方で輻輳崩壊状態に陥って処理ができない状態になったとのこと。(すでに処理の必要がないタスクなども溜まりっぱなしになっていたなどが想像される)
4.最終的にはキューをクリアするためにDWFMを一部再起動することで処理を再開できたとのこと。

障害発生(2)
DropletWorkflowManager(DWFM)に関する問題はこれで完了したが、この後Network Manager側で問題が発生した。
起動し始めたEC2へネットワーク伝搬が大量に発生し遅延が発生してしまったとのこと。
これについてはエンジニアが手動で負荷軽減措置を実施して解決。

3. Network Load Balancer (NLB)の接続エラー増加の原因
上記で紹介したEC2のNetwork Managerからのネットワーク伝搬遅延により、NLBのHealth checkに影響が発生していた。
まずNLBのアーキテクチャについてだが、NLBは複数のAZにまたがるNode上に構築されておりそのNodeはHealth checkサブシステムによって監視されている。もしHealth checkに失敗するとDNSから削除されて通信対象から排除される。

障害発生
今回、EC2のネットワーク伝搬遅延によってNodeとEC2の経路構築前にHealth checkが実行されて失敗することで大量にDNSからNodeが削除される結果となった。

- このHealth checkの失敗増加は、その失敗が増加しているNodeのあるAZへの転送をDNSレベルで流れないようにDNSフェイルオーバーをトリガーした。
2~3. 1.のせいで他AZのNLB Nodeへトラフィックが増加したことで負荷が増えてEC2への接続エラーを引き起こすなどした。
4.ネットワーク伝搬が完了してHealth checkが成功したEC2も、Nodeの置き換えなどが発生するとネットワーク伝搬が再度必要になり、これによって再度遅延によるHealth check失敗が起きるため成功と失敗を繰り返す状態となっていた。

5.NLBの問題についてはHealth checkサブシステムの負荷増加によるフェイルオーバー発生が問題だったので、エンジニアが自動フェイルオーバーを無効化することで対応したとのこと。
まとめ
全ての原因はDynamoDBでありAWS内部でもDynamoDBは様々な用途で使用されていることがわかって面白かったです。
また、この機会にAWSの内部構造について障害レポートを通じて理解を深めることができ学びになりました。
多少図では説明しきれてない部分もあると思うので、気になる方はレポート本体を読んでみることをお勧めいたします。