AWS Updeteにより、AWS FISにECS・EKSの新しいアクションが追加されていました。
現時点で行えるアクションは以下の通りです。
太文字のものが恐らく今回のアップデートで追加されたアクションです。
タスクの停止だけではなく、タスクのCPUストレステストやネットワークのテスト等も追加されました。
- ECS
- EKS
なお、以下のECSアクションに関しては、Fargeteに未対応のようです。
- aws:ecs:task-kill-process
- aws:ecs:task-network-blackhole-port
- aws:ecs:task-network-latency
- aws:ecs:task-network-packet-loss
また、実行前にECS Execを無効化する必要があるようです。
試してみる
新規追加されたタスクへのstressテストを試してみます。
テストを行うタスクの実行環境はFargateです。
なお、stressをかけるコンテナは以下を参考に作成しています。
前提
FISからアクションを実行する前提を満たすために準備を行います。
- FIS実験ロールに権限を追加
- ssm:SendCommand
- ssm:ListCommands
- ssm:CancelCommand
- ECSタスクロールに権限を追加
- ssm:CreateActivation
- ssm:AddTagsToResource
- iam:PassRole
- ECSタスク実行ロールに以下の権限を追加
- マネージドポリシー:AmazonECSTaskExecutionRolePolicy
- SSMマネージドインスタンスロールの作成
- 許可ポリシー
- ssm:DeleteActivation
- ssm:DeregisterManagedInstance
- 信頼されたエンティティ
- ssm.amazonaws.com
- 許可ポリシー
- アクション実行用のSSMエージェントがインストールされたサイドカーコンテナの作成
- 以下の定義のコンテナをタスク定義から追加
- なお、環境変数
MANAGED_INSTANCE_ROLE_NAME
のValueには上記で作成したSSMマネージドインスタンスロール名を入れること
サイドカーコンテナの定義
{
"name": "amazon-ssm-agent",
"image": "public.ecr.aws/amazon-ssm-agent/amazon-ssm-agent:latest",
"cpu": 0,
"links": [],
"portMappings": [],
"essential": false,
"entryPoint": [],
"command": [
"/bin/bash",
"-c",
"set -e; yum upgrade -y; yum install jq procps awscli -y; term_handler() { echo \"Deleting SSM activation $ACTIVATION_ID\"; if ! aws ssm delete-activation --activation-id $ACTIVATION_ID --region $ECS_TASK_REGION; then echo \"SSM activation $ACTIVATION_ID failed to be deleted\" 1>&2; fi; MANAGED_INSTANCE_ID=$(jq -e -r .ManagedInstanceID /var/lib/amazon/ssm/registration); echo \"Deregistering SSM Managed Instance $MANAGED_INSTANCE_ID\"; if ! aws ssm deregister-managed-instance --instance-id $MANAGED_INSTANCE_ID --region $ECS_TASK_REGION; then echo \"SSM Managed Instance $MANAGED_INSTANCE_ID failed to be deregistered\" 1>&2; fi; kill -SIGTERM $SSM_AGENT_PID; }; 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 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/.$//'); 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; 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 \"ECS Container Metadata not found, exiting\" 1>&2; exit 1; fi; else echo \"SSM agent is already running, exiting\" 1>&2; exit 1; fi"
],
"environment": [
{
"name": "MANAGED_INSTANCE_ROLE_NAME",
"value": "SSMManagedInstanceRole"
}
],
"environmentFiles": [],
"mountPoints": [],
"volumesFrom": [],
"secrets": [],
"dnsServers": [],
"dnsSearchDomains": [],
"extraHosts": [],
"dockerSecurityOptions": [],
"dockerLabels": {},
"ulimits": [],
"logConfiguration": {},
"systemControls": []
}
上記前提のもと、サービスを立ち上げてテスト用コンテナとサイドカーコンテナが立ちあがり、SSMフリートマネージャからサイドカーコンテナが確認できるようになれば準備完了です。
AWS FIS実験テンプレートの作成
AWS FISのコンソールから実験テンプレートを作成します。
アクションタイプ:ECSから「aws:ecs:task-cpu-stress」を選択し、アクションパラメータを設定します。
ターゲットでは負荷をかけるタスクのIDを指定します。
実験を開始する
実験を開始して実際に負荷がかかっているか確認します。
実験を行う前のメトリクスは以下の通りです。
テンプレートを選択し、「実験を開始」を押下し、開始します。
実験を開始してから数分後、メトリクス上でCPU使用率が50%程上がっていることが分かります。
10分後には正常状態に戻りました。
まとめ
AWS FISに新規アクションが追加されていました。ECSで利用する場合はサイドカーコンテナにSSM エージェントをインストールする必要があったりと少し手間な部分はありますが、これによりECSのカオスエンジニアリングが非常にやり易くなりました。
参考