2019年8月のAWS障害を思いながらAWS Well-Architectedフレームワーク 信頼性の柱 ホワイトペーパーを読んでみた
こんにちは。AWS事業本部のKyoです。
覚えていますか?一年前の今日のこと。
そう、AWSの東京リージョンのEC2,EBSでの障害の日ですね。
当時はAWSの利用歴が浅かったこともあり、AWSで大きめな障害なんて...と幻想を抱いていました。
この障害をきっけにその幻想は打ち砕かれ、Werner Vogelsの言葉やカオスエンジニアリングを知り、信頼性の面白さにズブズブとハマっていったのでした。
AWS re:Invent 2019 - Keynote with Dr. Werner Vogelsより引用
そんなわけで今回は、あの日のことを思いながら、「AWS Well-Architectedフレームワーク 信頼性の柱」のホワイトペーパーを読んでみました。
信頼性の柱には、ワークロードが意図した機能を期待どおりに正しく一貫して実行する能力が含まれます。これには、ライフサイクル全体を通じてワークロードを操作およびテストする機能が含まれます。このペーパーでは、AWSに信頼性の高いワークロードを実装するための詳細なベストプラクティスガイダンスを提供します。
本ブログについて
本ブログは、しっかり読むと大変なWell-Architectedフレームワークのホワイトペーパーについて個人的にポイントだなと思った点を述べていくスタイルです。大枠についてサクッと知りたいという際にご覧いただければ幸いです。本ブログと公式に違いがあった場合は、公式を正としてください。
以下が公式です。個人的にはPDFよりもHTMLページの方が読みやすい印象を受けました(ただしこちらはまだ日本語訳されていないようです)。
なお、ワークロードのレビューを行いたい場合にはAWS Well-Architected Toolを利用可能です。
また、Well-Architected フレームワークは2020年7月に大幅アップデートされています。
[アップデート] AWS Well-Architected フレームワークおよび AWS Well-Architected ツールが更新されたので、どこが変わったのかを調べてみた
※以降で利用している図は、私自身がまとめたマインドマップと比較表を除いてホワイトペーパーから引用させていただいています。
ホワイトペーパーの構成
PDF版で122ページとボリューミーなホワイトペーパーなので、まずはドキュメントの構造を理解すると読みやすいと感じました。
以下に構造をマインドマップにまとめてみました。
メインコンテンツはおおまかに以下の3つのパートに分かれます。
- 信頼性
- 信頼性を実現するベストプラクティス
- 可用性目標の実装例
それぞれについて見ていきたいと思います。
信頼性
信頼性とは何であって、どのように考えるべきであるか、また用語の定義などがまとまっています。
- 設計原則
- 定義
- 可用性のニーズについて
設計原則
信頼性の向上のための設計原則が書かれています。
ワークロードのモニタリングで重要なのはビジネスメトリクスという点や、クラウドならではの復旧手順をテストする(障害のシミュレーションや過去の障害の再現)といった点が印象的だなと感じました。
定義
弾力性、可用性といった、(よく聞くし、なんとなくわかるけど、腹落ちさせづらい)言葉の定義がなされています。
以下は特に重要な概念なので押さえておくと良いと思います。
弾力性
弾力性とは、インフラストラクチャやサービスの中断から復旧し、需要に適したコンピューティングリソースを動的に獲得し、設定ミスや一時的なネットワークの問題などの、中断の影響を緩和するワークロードの能力です。
- 信頼性の主たるコンポーネントが、弾力性 (Resiliency)
※ Resiliencyは回復力と訳されることもあります。
可用性
可用性 (サービスの可用性とも呼ばれます) は、信頼性を定量的に測定するために一般的に使用されるメトリクスです。
- 信頼性を定量するメトリクスが可用性 (Availability)
- 可用性は一定期間(通常は1年)の稼働率(99.9%など)で示される
アプリケーションのタイプごとに求められる可用性の参考値も示されています。
また、目標復旧時間(RTO)および目標復旧ポイント(RPO)についても触れられています。
本項には書かれていませんが、以降に「Gameday」という言葉が出てきます。Gamedayは文脈によって異なる意味で利用されることがあります。Well-Architedフレームワークにおいての定義はこちらです。
可用性のニーズについて
ビジネスニーズに合わせた可用性への適切な労力と費用の投資が必要なことに言及されています。
- アプリケーションやサービスは特定の側面によって求められる可用性が異なる
- 1日のうち特定の時間帯だけ高い可用性を求められるサービスなど
- ワークロードに求められる可用性のニーズは、ビジネスのニーズと重要度に合わせる必要がある
- RTO、RPO、および可用性を明確にしてビジネスにとって何が重要なのかを明確にすることで、ワークロードを正しく評価できる
信頼性を実現するベストプラクティス
信頼性を実現するベストプラクティスについて、基盤、ワークロードアーキテクチャ、変更管理、障害管理の4つの大項目で解説されています。
基盤
システムを構築する前に考慮すべき大枠であるAWSのサービス上限とネットワークについてのベストプラクティスが書かれています。
- サービスクォータと制約の管理
- ネットワークトポロジを計画する
※ サービスクォータは以前「サービス上限」と呼ばれていました
個人的なポイント
- 信頼性を実現する上で必要なリソース(サービスクォータ・ネットワーク)が重要
- 責任共有モデルにおいて、十分なネットワーク性能とコンピューティング性能を満たすのはAWSの責任で、ユーザはリソースのサイズと割り当てを担当
- サービスクォータはService Quotasで一元管理可能
- ネットワークの接続には可用性の高いマネージドサービスを利用
- 拡張と可用性を考慮したIPサブネット割り当て
- Transit Gatewayを利用したハブパンドスポークトポロジー
- フェイルオーバーに対応するため、現在の使用量と最大使用量の間に十分な余裕があることを押さえておく
ワークロードのアーキテクチャ
高い信頼性を保つために従うべきパターンのベストプラクティスについて書かれています。
- 適切なサービスアーキテクチャを実装する
- 障害を防ぐための分散システムでの相互作用の設計
- 障害を軽減または耐えるための分散システムでの相互作用の設計
個人的なポイント
- サービスを分割することで最も可用性ニーズの高い部分に投資することが可能
- サービス指向アーキテクチャもしくはマイクロサービスアーキテクチャを採用する
- 疎結合と冪等性で弾力性と俊敏性を高める
- SQS, Kinesis, Step Functions, Event Bridge
- 分散システムならではの相互作用についての設計も必要
- 依存関係をソフトにするためにグレイスフルデグラデーションを実装
- ヘルスチェックとSorryページみたいなイメージ
- サーキットブレーカーを利用する場合もある
- 再試行呼び出しの制御と制限
- クライアント側から大量の再試行が行われてもリソースの飽和を避ける設計
- クライアントのタイムアウトも重要
- 可能な場合はサービスをステートレスにする
- ElastiCache, DynamoDB等にステートをオフロード
- 水平方向スケーリングが可能になる
- 緊急レバーを実装する
- サービスのアクティブ/インアクティブを切り替える
- 前提として、サービスを分割しグレイスフルデグラデーションを実装していること
- サービスのアクティブ/インアクティブを切り替える
変更管理
ワークロードの内外の環境変化を予測して対応することについてのベストプラクティスが書かれています。 内部的な変化には、パッチやデプロイ、外部的な変化には、リクエストの急増などが挙げられます。
- ワークロードリソースをモニタリングする
- 需要の変化に適応するようにワークロードを設計する
- 変更を実装
個人的なポイント
- 最悪の障害ケースとは管理側がそれに気づかず、エンドユーザからクレームがくること
- AWSのモニタリングは以下の4つのフェーズがあ
- 生成 – ワークロードのすべてのコンポーネントをモニタリングする
- 各サービスは豊富なモニタリング情報を提供している
- CloudWatch Syntheticsによる合成監視も可能
- 集計 – メトリクスを定義して計算する
- CloudWatchとS3に集約と保存
- リアルタイム処理とアラート
- SNS, SQS
- ストレージと分析
- CloudWatch Logs Insights, Athenaによる分析
- 参考: Amazon Athena,Amazon CloudWatch Logs Insightsの使い分けについて考えてみる
- 巨大な場合はEMRも利用可能
- ストレージするデータのライフサイクルも意識する
- S3のライフサイクル機能が便利
- 生成 – ワークロードのすべてのコンポーネントをモニタリングする
- モニタリングの中心になるのはビジネスメトリクス
- リソースの交換やスケーリングは自動で行う
- ワークロードの負荷テストを行う
- Gamedayの一部として考える
- デプロイなどの標準的なアクティビティにはランブック(運用手順書)を使用する
- 類義語:プレイブック(障害対応手順書)
- 手動ではじめてコード化していく
- 機能テスト、弾力性テストをデプロイパイプラインに統合する
- インフラをイミュータブルにする
- CanaryデプロイもしくはBlue/Greenデプロイを使用
- 本番システムに変更を加えることは多くの組織において最大級のリスクの1つ
- 機能をフラグで明示的にオンオフできるようにしておく
- デプロイはAZ単位で行い、問題のAZを切り離せるようにする
- 定期的(年1回など)に運用準備レビューを実施
障害の管理
どんな高品質なコンポーネントやを利用しても障害の発生を避けることはできません。ワークロードの信頼性を確保するために、どのように障害と付き合い、弾力性を持たせるかのベストプラクティスについて書かれています。
- バックアップデータ
- 障害分離を使用してワークロードを保護する
- コンポーネントの障害に耐えるようにワークロードを設計する
- テストの信頼性
- 災害復旧(DR)の計画
個人的なポイント
- 目標復旧時間 (RTO) と目標復旧時点 (RPO) の要件を満たすように、データ、アプリケーション、設定をバックアップ
- 自動化しておく
- データの定期的な復旧を行って、バックアップの完全性とプロセスを確認する
- 要件を満たしているのか実際にやってみる
- ワークロードを複数のAZもしくはリージョンで分散
- バルクヘッドアーキテクチャ/セルベースアーキテクチャ
- セルには完全なサービスが含まれ、そのサイズは固定
- 負荷が増加するとセルが追加されることで対応
- 1つのセルに障害が発生しても原則、他のセルには影響しないので爆風半径を小さくできる
- ワークロードのすべてのコンポーネントをモニタリングして、障害を検出、必要に応じてフェイルオーバー
- モニタリングにおいて注目すべきはビジネスメトリクス
- 修復の自動化
- サービスがステートレスであればやりやすい
- プレイブックを使用して障害を調査する/インシデント後の分析を実行する
- ビジネスロジックのテストとスケーリングのテスト
- カオスエンジニアリングで弾力性をテスト
- AWSサービスとしてはSystems Managerが利用できる
- 他には、Netflix Simian Army(Chaos Monkey etc.), Gremlinといったサードパーティオプション
- Gamedayの実施
- CI/CDへの統合で自動化
- DR戦略にも複数が存在するので、復旧目標に合わせて選ぶ
- バックアップと復元
- パイロットライト
- ウォームスタンバイ
- マルチリージョンのアクティブ/アクティブ
- DRの実装を定期的にテストして、RTOとRPOが満たされていることを確認
- 自動化との組み合わせ
可用性目標の実装例
ここまで見てきたベストプラクティスについて、可用性目標(99% ~ 99.999%)ごとに何をどのように実装すべきか、という例が挙げられています。
前提となる構成
- アプリケーションサーバ: Amazon EC2
- DB: Amazon RDS
- DNS: Amazon Route 53
- ロードバランサ: Elastic Load Balancing
- バックアップと静的コンテンツ: Amazon S3
評価するトピック
可用性目標ごとの比較表
可用性目標ごとに比較できるように、表にまとめてみました。
可用性目標の上がる右側にいくにつれて、実装がリッチになっていくことが分かると思います。ワークロードを実行中の方は実装できているトピックとの差分について考えてみると良いかもしれません。
おわりに
システムの基本ともいえる信頼性について、改めてホワイトペーパーを読んでみて様々な発見がありました。
特にカオスエンジニアリングが推奨されているのは非常に興味深いと思いました。可用性について設計だけで終わらせず、実験的に示し続けることは一部のテックカンパニーのみならず、クラウド利用者にとって一般的な概念になっていけば良いなと思います。
以上、何かのお役に立てれば幸いです。