金曜日, 7月 4, 2025
金曜日, 7月 4, 2025
- Advertisment -
ホームニューステックニュースAWS Fault Injection ServiceでECS on FargateのAZ障害にトライ! #FIS

AWS Fault Injection ServiceでECS on FargateのAZ障害にトライ! #FIS



AWS Fault Injection ServiceでECS on FargateのAZ障害にトライ! #FIS

 2025/4/15にAWSの東京リージョンで障害が発生しました。
 「AZ内の特定のEC2インスタンスへの主電源と二次電源が遮断されたことが原因」ということがAWSから公表されています。今回の障害では、EC2単体の障害だけではなく、EC2を基盤として提供されていると思われる以下のサービスにも影響がありました。

  • AWS CodeCommit
  • AWS Lambda
  • AWS NAT Gateway
  • AWS Network Firewall
  • AWS Systems Manager
  • AWS Transit Gateway
  • AWS VPCE PrivateLink
  • Amazon CloudWatch
  • Amazon Elastic Container Service
  • Amazon Elastic Load Balancing
  • Amazon Location Service
  • Amazon Redshift
  • Amazon Relational Database Service
  • Amazon Simple Storage Service
  • Amazon WorkSpaces

 (AWS〜だったり、Amazon〜だったり、名称統一して欲しいですよね・・・)
 久しぶりに、それなりの規模の影響範囲の障害になったなと感じた事象でした。

さて、障害については、AmazonのCTO、Dr.Werner氏もこう話されています。

Everything fails, all the time.
(全てのものはいつでも壊れうる)

 Well-Architected Frameworkでも、信頼性の柱(Reliability)が提唱されています。本記事を読まれている方も目標とする信頼性を確保するため、設計段階から色々と検討して構築、試験で確認をされていると思います。今回、2025/4/15に起きたAZ障害を踏まえて、Fault Injection Service(以下、FISと記載)を利用してAZ障害を起こして、検証を行ってみることにしました。
 本内容は、2025/5/24に開催されたJAWS-UG 栃木支部でLTさせていただいた内容をベースにしています。LTでお話をさせていただいた内容の補足と、LT内で引き続き挑戦していくとお話をしていたECS on FargateにおけるAZ障害について、備忘も含めて投稿しておきます。

 Amazon ECS on FargateでAZ障害を試そうとされる方の参考になれば幸いです。(注:お急ぎの方は、最初に「まとめ」をお読みください)

AWS Fault Injection Service とは

 AWS FISは、AWS上で稼働するアプリケーションの回復力を高めるためのマネージドサービスです。カオスエンジニアリングの概念に基づき、システムに意図的に障害を発生させることで、その挙動や耐性を事前に確認することができます。

FISにおける主要なキーワード(私の理解)は以下となります。

キーワード 概要
ターゲット 障害を注入する対象リソース
(例)EC2インスタンス、RDSクラスター、ECSタスクなど
アクション ターゲットに対して実行される障害
(例)EC2インスタンスの停止・再起動・CPU高負荷、ネットワーク遮断
実験テンプレート 複数のターゲットとアクションを組み合わせたもの。アクションの実行順序や時間の制御を設定して、本番障害に近づけることができる
(マネコンでの操作の他、JSON、YAMLでも記述可能)
実験 事前に作成した実験テンプレートを元に一連の擬似障害を発生させること

 FISについては過去にもQiitaに投稿しています。Lambda関連での障害に興味があれば、こちらもご参照ください。

今回の構成、FISのシナリオ

今回の標的

 こちらのマルチAZ構成のAmazon ECS on FargateとAmazon RDSの構成を利用しました。Application Load Balancer(ALB)を利用して各AZにトラフィックを分散しています。また、Amazon RDSもマルチAZ構成でフェイルオーバが可能な構成になっています。片AZで障害が発生した場合でも、障害の発生していないAZで継続して稼働できることが期待値です。

fis000.png

利用したシナリオ

 FISにはシナリオライブラリという事前に準備されたシナリオ集があります。2025年6月時点では12種類提供されています。(2023年のre:Inventの時期で、すでに12種類が提供されていました)

fis001.png

今回は、その中で「AZの可用性:電源の中断」を使用することにしました。

fis002.png

概要として以下が記載されています。内容を読む限り、Amazon ECS、Amazon RDSの障害ということで、今回の期待する実験の内容になっています。

複数のリソースタイプに影響する、AZ の電源が完全に遮断されるという予想される症状を、タグと ARN でターゲット化します。

このシナリオは、1 回の完全な AZ 停電時にマルチ AZ アプリケーションが期待通りに動作することを実証するために使用できます。これには、ゾーンコンピューティング (Amazon EC2、EKS、ECS) の喪失、AZ 内のコンピューティングの再スケーリング不能、サブネット接続の喪失、RDS フェイルオーバー、ElastiCache フェイルオーバー、EBS ボリュームの応答不能などが含まれます。ゾーンオートシフト対応リソースは、復旧中に AZ から移行します。デフォルトでは、ターゲットが見つからないアクションはスキップされます。

シナリオを使用して、障害発生の準備

 それでは当該のシナリオを選択して、「実験テンプレートを作成」をクリックして、実験の設定をしていきます。

fis003.png

アクションとターゲットを指定の画面にきました。
全部で10個のアクションが準備されています。それぞれターゲットで指定したAWSリソースに対して障害を投入できるようになっています。

アクションを見ていきますが・・・、EC2障害が半分を占めています。

fis004.png

 NW切断やAmazon RDS障害はあったものの、Amazon ECSに関する障害が見つかりません。ここで気づきました。こちらのシナリオ、Amazon ECS on EC2を前提とした障害シナリオになっていました(EC2障害が起こせれば、その上で動くAmazon ECSタスクに対する障害が再現できます)。一方で今回の構成はFargateを前提に考えていましたので、適合するアクションがありませんでした。

 まずはできるだけの設定を実施しようと考え、Amazon RDS障害を起こすため、Amazon RDSクラスターのターゲットを編集しました。今回はタグ指定AzImpairmentPower:DisruptRds、AZ指定us-east-1aで設定を行いました。

fis005.png

 NWの一時的な通信断も起こすため、Subnetのターゲットを設定しておきます。AZ、VPCを指定して保存します。

fis007.png

 次に、実験を実行するためのIAMロールを作成します。私は過去に作成していたIAMロールを利用しました。

fis009.png

 新規でIAMロールを作り、ポリシーを付与していく場合、実験対象のターゲットに応じて、ポリシーの追加が必要になります。アクションを実行する際に、どのアクセス許可が必要かは、ドキュメントに記載があります。
(AWS FISのシナリオを使って実験テンプレートを作成する際に合わせてIAMロールも作成する場合、シナリオに含まれるアクションに必要なポリシーは自動で紐付けられます)

 個別にIAMロールを作成する場合、信頼関係は、FISのサービスに対してAllowにする必要があります。

信頼関係

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "fis.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

ログ出力の設定を行い、次へをクリックします。

fis010.png

設定値を確認して、実験テンプレートを作成をクリックします。
少々待つと、以下のような形で実験テンプレートができあがります。

fis011.png

ターゲットリソースへのタグ付け

 先ほど設定したターゲットに合わせて、障害対象のDB、サブネットにもタグを追加しておきます。今回、DBについては、Auroraクラスターにタグ付けをしました。

fis006.png

 サブネットについてもAmazon ECSタスクを起動するAZのうち、障害を発生させたいAZにタグをつけました。

fis008.png

 一旦、設定を終えましたが、このまま実行してもAmazon ECSのAZ障害が発生させられません。シナリオは自由にアクション、ターゲットの追加、削除が可能なため、Amazon ECSに対するアクションを調べて、追加してみることにしました。

Amazon ECS単体のアクション、実行準備

 Amazon ECSとしては、以下のアクションが提供されています。

アクション 障害内容
aws:ecs:drain-container-instances クラスター内のインスタンスを停止する
aws:ecs:stop-task 指定したECSタスクを停止する
aws:ecs:task-cpu-stress コンテナにCPU負荷をかける
aws:ecs:task-io-stress コンテナにI/O負荷をかける
aws:ecs:task-kill-process コンテナの特定のプロセスを強制終了する
aws:ecs:task-memory-stress コンテナのメモリ使用率を上げる
aws:ecs:task-network-blackhole-port コンテナの特定のポートへのトラフィックをドロップする
aws:ecs:task-network-latency コンテナのネットワーク通信に遅延を発生させる
aws:ecs:task-network-packet-loss コンテナのネットワーク通信でパケットドロップを発生させる

 Amazon ECSに対するアクションを実行する際の事前作業については以下のドキュメントを参照して準備しました。

1. AWS FIS 実験テンプレートのIAMロールにAmazon ECS操作用のマネージドポリシーを追加

 実験テンプレートに紐づけてあるIAMロールにAWSマネージドポリシーであるAWSFaultInjectionSimulatorECSAccessを追加します。

aws iam attach-role-policy \
  --role-name  \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorECSAccess

 上記のロールを付与することで、ドキュメントに記載のある以下3つの権限が付与されます。

  • ssm:SendCommand
  • ssm:ListCommands
  • ssm:CancelCommand

2. Amazon ECSタスクのIAMロールに権限追加

 ドキュメントに記載されている権限をECS実行時のIAMロールに付与していきます。

  • ssm:CreateActivation
  • ssm:AddTagsToResource
  • iam:PassRole

 以下のCLIでポリシーを作成して、既存のIAMロールに紐付けました。

# カスタムポリシーを作成
aws iam create-policy \
  --policy-name FIS-ECS-TaskRole \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "ssm:CreateActivation",
          "ssm:AddTagsToResource"
        ],
        "Resource": "*"
      },
      {
        "Effect": "Allow",
        "Action": [
          "iam:PassRole"
        ],
        "Resource": "*",
        "Condition": {
          "StringEquals": {
            "iam:PassedToService": "ssm.amazonaws.com"
          }
        }
      }
    ]
  }'

# カスタムポリシーをIAMロールにアタッチ
aws iam attach-role-policy \
  --role-name  \
  --policy-arn arn:aws:iam:::policy/FIS-ECS-TaskRole

3. SSMエージェント用マネージドインスタンスロールを作成

 ドキュメントに記載されているSSMエージェント用のマネージドインスタンスロールを作成して、必要な権限を付与していきます。

# IAMロールを作成
aws iam create-role \
  --role-name  \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "Service": "ssm.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
      }
    ]
  }'

# カスタムポリシーを作成
aws iam create-policy \
  --policy-name  \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "ssm:DeleteActivation",
          "ssm:DeregisterManagedInstance"
        ],
        "Resource": "*"
      }
    ]
  }'

# カスタムポリシーをIAMロールにアタッチ
aws iam attach-role-policy \
  --role-name  \
  --policy-arn arn:aws:iam:::policy/

# AWS管理ポリシーをIAMロールにアタッチ
aws iam attach-role-policy \
  --role-name  \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

4. Amazon ECSタスク定義の編集

 Amazon ECSタスク定義を編集してアクションを実行できるようにしていきます。
 タスク定義の画面にて、新しいリビジョンの作成を選択して以下の設定をしていきます。

 まずはインフラストラクチャの要件において、フォールトインジェクションを有効にするにチェックを入れます。

fis025.png

 続いて、既存のコンテナ定義の下の+コンテナを追加ボタンを洗濯して、ドキュメント記載のコンテナ定義を追加していきます。

fis026.png

項目名 設定値
コンテナ名 amazon-ssm-agent
イメージ public.ecr.aws/amazon-ssm-agent/amazon-ssm-agent:latest
※私はプライベートリポジトリから取得する形にしていたため、画像は以下となっています
AWSアカウントID.dkr.ecr.us-east-1.amazonaws.com/amazon-ssm-agent:latest
Docker設定 コマンド とても長いので、表外に記載します
環境変数(キー) MANAGED_INSTANCE_ROLE_NAME
環境変数(値) 実際に作成したSSMマネージドインスタンスロール名を設定します
私の場合はFIS-ECS-ManagedInstanceroleというロール名で作りましたので、その名前を設定しました

ssm-Agentをパブリックのイメージで使用する場合、NATゲートウェイ等のインターネット向け通信が必要になります。実行される環境に応じて、必要な基盤をご準備ください。

  • Docker設定 コマンドは、以下を無心で貼り付けてください
/bin/bash,-c,"set -e; dnf upgrade -y; dnf install jq procps awscli -y; term_handler() { echo \"Deleting SSM activation $ACTIVATION_ID\"; if [[ -n $ACTIVATION_ID && -n $ECS_TASK_REGION ]]; then aws ssm delete-activation --activation-id $ACTIVATION_ID --region $ECS_TASK_REGION 2>/dev/null || echo \"SSM activation $ACTIVATION_ID failed to be deleted\" 1>&2; fi; if [ -f /var/lib/amazon/ssm/registration ]; then MANAGED_INSTANCE_ID=$(jq -e -r .ManagedInstanceID /var/lib/amazon/ssm/registration 2>/dev/null); if [[ -n $MANAGED_INSTANCE_ID && -n $ECS_TASK_REGION ]]; then echo \"Deregistering SSM Managed Instance $MANAGED_INSTANCE_ID\"; aws ssm deregister-managed-instance --instance-id $MANAGED_INSTANCE_ID --region $ECS_TASK_REGION 2>/dev/null || echo \"SSM Managed Instance $MANAGED_INSTANCE_ID failed to be deregistered\" 1>&2; fi; fi; kill -SIGTERM $SSM_AGENT_PID 2>/dev/null || true; }; trap term_handler SIGTERM SIGINT; if [[ -z $MANAGED_INSTANCE_ROLE_NAME ]]; then echo \"Environment variable MANAGED_INSTANCE_ROLE_NAME not set,exiting\" 1>&2; exit 1; fi; if ps ax | grep amazon-ssm-agent | grep -v grep > /dev/null; then echo \"Stopping existing SSM agent\"; pkill -f amazon-ssm-agent || true; sleep 2; fi; if [[ -n $ECS_CONTAINER_METADATA_URI_V4 ]] ; then echo \"Found ECS Container Metadata,running activation with metadata\"; TASK_METADATA=$(curl \"${ECS_CONTAINER_METADATA_URI_V4}/task\"); ECS_TASK_AVAILABILITY_ZONE=$(echo $TASK_METADATA | jq -e -r '.AvailabilityZone'); ECS_TASK_ARN=$(echo $TASK_METADATA | jq -e -r '.TaskARN'); ECS_TASK_REGION=$(echo $ECS_TASK_AVAILABILITY_ZONE | sed 's/.$//' | sed 's/[a-z]$//'); echo \"Extracted region: $ECS_TASK_REGION from AZ: $ECS_TASK_AVAILABILITY_ZONE\"; ECS_TASK_AVAILABILITY_ZONE_REGEX='^(af|ap|ca|cn|eu|me|sa|us|us-gov)-(central|north|(north(east|west))|south|south(east|west)|east|west)-[0-9]{1}[a-z]{1}$'; if ! [[ $ECS_TASK_AVAILABILITY_ZONE =~ $ECS_TASK_AVAILABILITY_ZONE_REGEX ]]; then echo \"Error extracting Availability Zone from ECS Container Metadata,exiting\" 1>&2; exit 1; fi; ECS_TASK_ARN_REGEX='^arn:(aws|aws-cn|aws-us-gov):ecs:[a-z0-9-]+:[0-9]{12}:task/[a-zA-Z0-9_-]+/[a-zA-Z0-9]+$'; if ! [[ $ECS_TASK_ARN =~ $ECS_TASK_ARN_REGEX ]]; then echo \"Error extracting Task ARN from ECS Container Metadata,exiting\" 1>&2; exit 1; fi; if [[ -n $ECS_TASK_REGION ]]; then CREATE_ACTIVATION_OUTPUT=$(aws ssm create-activation --iam-role $MANAGED_INSTANCE_ROLE_NAME --tags Key=ECS_TASK_AVAILABILITY_ZONE,Value=$ECS_TASK_AVAILABILITY_ZONE Key=ECS_TASK_ARN,Value=$ECS_TASK_ARN Key=FAULT_INJECTION_SIDECAR,Value=true --region $ECS_TASK_REGION); ACTIVATION_CODE=$(echo $CREATE_ACTIVATION_OUTPUT | jq -e -r .ActivationCode); ACTIVATION_ID=$(echo $CREATE_ACTIVATION_OUTPUT | jq -e -r .ActivationId); if ! amazon-ssm-agent -register -code $ACTIVATION_CODE -id $ACTIVATION_ID -region $ECS_TASK_REGION; then echo \"Failed to register with AWS Systems Manager (SSM),exiting\" 1>&2; exit 1; fi; amazon-ssm-agent & SSM_AGENT_PID=$!; wait $SSM_AGENT_PID; else echo \"Failed to extract region from metadata,exiting\" 1>&2; exit 1; fi; else echo \"ECS Container Metadata not found,exiting\" 1>&2; exit 1; fi"

5. Amazon ECSサービスでECS Execを有効化

 SSMの機能を使用してタスク内の障害を発生させますので、Amazon ECS Execの機能を有効化します。 私はCLIで以下のコマンドを実行して有効化しました。

 aws ecs update-service \
  --cluster  \
  --service  \
  --enable-execute-command

Amazon ESC Execが有効化されるのは、次回起動時になります。
今回、私はこの仕様を失念していて、しばらく待ってしまいました。タスクを再起動すれば反映されますのでお忘れ無く。

 以上で準備が整いましたので、以下、AZ障害に近い動きをしてくれそうなアクションを実行していきました。

Amazon ECSタスクに対するアクションの実行

1. Amazon ECSタスク停止の障害を起こしてみる ecs:stop-task

 ecs:stop-taskアクションを使用して、障害を起こすAZで稼働しているタスクを強制的に止めるという障害を起こすことにしました。

 アクションは以下になります。

fis013.png

 ターゲットは以下になります。
 リソースパラメータでクラスター、サービスのarnを指定しました。また、リソースフィルターはAvailabilityZone:us-east-1を指定しました。

fis014.png

実行結果

 実行した結果ですが、ダメでした。タスクは停止できましたが、1回停止するのみですので、サービス側でタスクのダウンを検知して、同じAZ上でタスクが起動してきてしまいました。

2. NW障害時にタスク停止を起こす aws:network:disrupt-connectivity & ecs:stop-task

 タスクの停止単体ではダメということであれば、NW関連の障害中に、タスク停止を起こすことを考えました。障害を発生させるAZでNW断を起こせばタスクが立ち上げられず、健全なAZでタスクが起動するのではないか、という期待を抱いて、aws:network:disrupt-connectivityアクションを追加してみました。
 aws:network:disrupt-connectivityアクションは、サブネットに紐づくNACLをAWS FIS側で差し替えて、Inside、Outside両方を全てDenyに変更するアクションです。aws:network:disrupt-connectivityアクションを実行した状態で、ecs:stop-taskアクションで当該のタスクを停止すれば、健全なAZ側でタスクは起動してくれるのではないかと考えました。

実行結果

 結果は、またもやダメでした。正確には、実験を16回実施して、1回だけ健全なAZでタスクが起動してくれました。ただ、うまくいったのはその1回だけでした。その他の回は障害中のAZで起動しようとして失敗しました。障害中のAZで起動したタスクは、保留中のステータスから先に進むことはありませんでした。

 障害を発生させるAZの特定のサブネットの通信が全断となるため、Amazon ECSのサービスからVPCエンドポイントへのアクセスもできなくなります。一方で、Amazon ECSサービスは基盤となるFargateが元気に稼働しているAZでタスクを起動させようとします。障害中のAZのサブネットでもFargate自体は元気に稼働していますので、Amazon ECSサービスも障害中AZのサブネットでタスクを起動させようとします。その結果、ECRからイメージが取得できず、タスクが保留中のまま起動できないという結果になったと想定しています。
 実験が終了(NWが正常に通信できるようになる)すると、保留中から実行中へステータスが遷移しました。

3. NW障害を起こす aws:ecs:task-network-blackhole-port

 サブネットに対するNW障害はダメということで、続いてタスクの通信についてパケットロストを起こすアクションを実行してみました。

 aws:ecs:task-network-blackhole-portアクションでは、特定のポート番号に到達したパケットをロストさせる形で障害を発生させます。

fis029.png

 Fargate環境で実行する場合、最後のUse ECS fault Injection endpointsはチェックを入れておく必要があります。

実行結果

 ALBが通信障害を検知して、ターゲットグループ上でUnhealthyのステータスとなり、異常と判断され、ECSタスクが追加で起動するという動きになりました。ただ、タスクが起動されたAZは、障害を発生させたAZでした。

 また、タスクが再起動しても、改めて通信障害が発生することはなく、起動したECSタスクは元気に過ごしていました。ssm-AgentのRun CommandによるアクションはAWS FISのアクション起動時の1回だけ実行されるような動きのようです。継続してNW障害を発生させる場合はNACLを書き換えるアクション等、他のアクションを採用した方が良さそうです。
 こちらのアクションでも数回繰り返した結果、2回は健全なAZで起動しました。この結果からも、Fargateの場合は、起動するAZは制御できないということがわかりました。

4. (番外編)Application Recovery Controller(ARC)ゾーンオートシフトの試行

 Amazon ECSのタスク障害、NW障害での再現が難しいということで壁にぶつかりました。他にAZ障害のようなものを起こせないかと調べていたところ、Application Recovery Controller(ARC)ゾーンオートシフトに目が止まりました。
 Application Recovery Controller(ARC)ゾーンオートシフトとは、AZ障害が発生した際、トラフィックを別のAZへ流す仕組みになります。AWS側でAZ障害を検知し、自動で別AZへルーティングさせるものになります。

 ただ、サポートリソースはEC2、EKS、ALB、NLBといったリソースになっており、Amazon ECSは含まれていませんでした。
ALBからの通信が途切れた場合、という仮定をして、今回は、ALBでARCゾーンシフトを設定して試してみることにしました。
 ALBの属性タブから参照できますが、デフォルトは無効になっています。

fis015.png

 ARCゾーンシフトは、編集で有効化を選ぶのみで利用可能となります。

fis016.png

 AWS FISの実験テンプレートも確認しておきます。ターゲットはリソースタグAzImpairmentPower:RecoverAutoshiftResourcesを付与する形で指定します。

fis017.png

 そのため、ALB側にもタグ付けを行いました。
fis018.png

実行結果

 ALBの画面にて、しっかりとゾーンシフトを検出して、障害の発生していないAZに振り分けがされていることを確認できました。

fis019.png

ターゲットグループにおいても、ゾーンシフトが起きていることが確認できました。

fis020.png

 しかしながら、ALBがターゲットグループの振り分けを制御しているのみで、実際のAmazon ECSタスクはそのままのAZで稼働し続けていました。結果として、健全なAZで必要なタスク数は起動できていませんので、障害発生したAZにはルーティングされないものの、必要な処理能力は確保できていないという、中途半端な稼働状態となってしまいました。

 ここまでが、LTでお話をしていた事柄がベースの内容となります。その後、どうすればAZ障害時のFargateの動作をAWS FISで再現できるのだろうかと、AWSサポートへ問い合わせをしました。その結果、以下の回答をいただきました。

ご期待に添えず大変恐縮ではございますが、Fargateの仕様上AZを指定してタスクを起動することはできません[1]。
よって、片方のAZを指定してAWS FISの実験を行った場合、実験対象のAZにてECSタスクの起動を実施する可能性がございます。

【補足資料】
[1] アベイラビリティーゾーン間での Amazon ECS サービスの調整 – Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/service-rebalancing.html
===== 資料より抜粋 =====
タスク配置戦略および制約事項は、Fargate 起動タイプを使用しているタスクをサポートしていません。Fargate は、アクセス可能なアベイラビリティーゾーンにタスクを分散するよう最善を尽くします。キャパシティープロバイダーに Fargate と Fargate Spot の両方が含まれている場合、スプレッドの動作はキャパシティープロバイダーごとに異なります。
==================

ということで、サポートに確認をした結果でも、仕組み上、FargateでのAZ障害の再現は不可という結論に至りました。

補足、学んだこと

ここまでに書いていなかった補足や実験時に失敗して学んだことを記載しておきます。

大規模障害も最初は短時間の試行から

 1つずつのアクションの実行時間が長いですが、最初は動作確認をした方が良いです。対象リソースにタグをつけ忘れていたり、障害対象のAZで起動し忘れていたり、最初の頃は色々あります。今回のAZ障害のシナリオは60分ものになっています。何度も繰り返し実行すると長くなってしまうため、今回は各アクションの時間を調整して全体で20分弱で一通りの実験を行えるようにしました。

実験の結果は保管期間が120日

 昨年12月に実施した実験の結果を参照しようとしたところ、実験結果が見つかりませんでした。リージョンを間違えたのかと思ったのですが、実験テンプレートは該当のリージョンにあり、正しいリージョンを参照していました。保管期間を設定した記憶もなく、ドキュメントを検索した結果(AWS Documentation MCP Serverを使ってQ Developerに聞いた結果)、クォータの記載がドキュメントにありました。
 デフォルトで120日間の保管、延長(クォータ引き上げ)は不可とのこと。昨年の実験結果に会うことは叶いませんでした。

 その他にも色々とクォータが設定されていました。大規模に実験を実施される方はご注意ください。

シナリオは自由に変更可能

 アクションは前後関係を自由に設定できるため、待ち時間を冒頭に入れたり、複数の障害を順番に発生させるといったこともできます。

以下のようにアクションを編集する画面で、先行するアクションを指定できます。Waitのアクションを指定すると、一定時間経過後にアクションを実行できます。

fis012.png

実験テンプレートはエクスポート・インポートできる

 実験テンプレート自体はコピー&ペーストできませんが、エクスポート&インポートで実現できます。インポートは別アカウントに対しても実施できますので、NW的に繋がっていないAWSアカウントへテンプレートを移すことも可能です。

実験終了後、Amazon RDSは再フェイルオーバしない

 AWS FISは実験終了後に環境が自動で元の状態に戻ることが、個人的なおすすめポイントです。ただ、Amazon RDSについては、実験終了後に実験開始前のAZに戻る(再フェイルオーバする)ことはありません。同一のAZに対して、繰り返し実験を実施する場合、手動でAmazon RDSが稼働するAZを戻す必要があります。
 何度も実験を繰り返す中で、私はあまりにも戻し忘れるので、AZ障害の実験の最後に一定時間のWaitを入れて(aws:fis:waitアクション)、Amazon RDSをフェイルオーバするaws:rds:failover-db-clusterアクションを追加しました。Waitアクションは切り替わった後の健全性確認を行うためのバッファの時間を設定しました。
 シナリオ化すると1回の実験でそれなりに時間を使ってしまうので、時間を無駄にできない方にはおすすめのシナリオです。他にこんな方法もあるよ、といったアイデアがあれば教えていただけると助かります。

料金

 以下のサイトに記載があります。

 https://aws.amazon.com/jp/fis/pricing/?nc1=h_ls

With AWS FIS, you pay for what you use. There are no upfront costs or minimum fees. You are charged based on the duration that an action is active and the number of accounts included in an experiment. The AWS FIS price is $0.10 per action-minute plus an additional $0.10 per action-minute for each additional account, for all regions except AWS GovCloud (US-East and US-West)

以下、機械翻訳の内容です

AWS FIS は、使用した分だけ料金が発生します。初期費用や最低料金はありません。アクションがアクティブだった期間と、実験に含まれるアカウント数に基づいて課金されます。AWS FIS の料金は、AWS GovCloud (米国東部および米国西部) を除くすべてのリージョンで、アクション 1 分あたり 0.10 ドルで、追加アカウントごとに 1 分あたり 0.10 ドルが加算されます。

マルチアカウントでの実験も可能ですので、その場合はアカウント数分、掛け算していくことになります。また、Amazon CloudWatch LogsやAmazon S3にログを出力した場合は、その保管分のコストも発生します。
そこまで心配しなくても良い金額だと思います。

 結論、AWS FISでは、Amazon ECS on FargateのAZ障害時の動作を再現することはできませんでした。Fargateは、マネージドサービスであることから、責任共有モデルの分担を踏まえるとAWSによる管理を信頼するというのが正しいですね。また、コントロールプレーンの障害か、データプレーンの障害かによっても、単にAZ障害といっても、サービス提供に影響が出る・出ないというパターンも出てくるかと思います。AWS FISを活用しながら、引き続き障害時の運用について考えていきたいと思います。
 この記事の内容がAWS FISで障害試験を実施しようとするどなたかの参考になれば幸いです。





Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -