経緯
業務で分散ロードテストフレームワークを作るために ECS on Fargate を使用する。
最終的にはECSクラスターをTerraformでデプロイする予定。その前段階としてAWS console上でぽちぽちいじりながら作ってみる。
やりたいこと
最終的に以下をできるようにする。
- AWS ECS task をローカルの aws cli で実行する。この際に、コンテナ内実行時に参照可能な環境変数を指定する。
- AWS ECS task では、ECR上のプライベートレポジトリ内のDocker imageを使用してコンテナを立ち上げる。
- AWS ECS task 内で、S3へファイルをアップロードする。
ステップ
1. ECS cluster の初期化
2. Task definition の作成
以下のように作成された。
3. Task を実行してみる
以下のように実行された。
4. カスタマイズ(1)
自前の Docker image をECR内に用意し、ECSがそれをpullしてきて実行させたい。
ECRのレポジトリの作成
ローカルでDockerfileを作成する。
FROM ubuntu:latest
CMD echo "Hello from Daiki in custom docker file"
これをビルドしてプッシュする。
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111111111111.dkr.ecr.us-east-1.amazonaws.com
docker build -t daiki-test .
docker tag daiki-test:latest 111111111111.dkr.ecr.us-east-1.amazonaws.com/daiki-test:latest
docker push 111111111111.dkr.ecr.us-east-1.amazonaws.com/daiki-test:latest
ECR上にイメージが存在するのを確認できた。
これを使って、ECS task definition の新しいrevisionを作成する。
daiki-loadtesting-test-task:2
が完成した。
自分のMacは、arm64
なので、以下のようにECSクラスターの定義を更新した。
このECSタスクを実行する。
実行完了。以下がログ。
AWS CLIから実行する
以下をローカルで実行する。subnetは、default subnetを指定した。
(AWS console上でタスクを実行した場合はこれが使用されていた。)
aws ecs run-task \
--cluster daiki-load-testing-test \
--task-definition daiki-loadtesting-test-task:3 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-6331723a],assignPublicIp=ENABLED}"
( assignPublicIp=ENABLED
は ECRからベースイメージをfetchしてくる場合に必要そう?)
5. カスタマイズ(2)
タスク実行時できるパラメータを、環境変数としてrun task時に外部から注入したい。
まずは、Dockerfileを以下のように更新し、push。
FROM ubuntu:latest
CMD echo "Hello from Daiki in custom docker file. I got injected_var=${injected_var}"
docker build -t daiki-test .
docker tag daiki-test:latest 1111111111111.dkr.ecr.us-east-1.amazonaws.com/daiki-test:latest
docker push 111111111111.dkr.ecr.us-east-1.amazonaws.com/daiki-test:latest
Task definition内から、containerDefinitions.name
を調べる。
これと、環境変数を指定して、以下をローカル上で実行する。
aws ecs run-task \
--cluster daiki-load-testing-test \
--task-definition daiki-loadtesting-test-task:3 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-6331723a],assignPublicIp=ENABLED}" \
--overrides '{
"containerOverrides": [
{
"name": "daiki-test-image-in-ecr",
"environment": [
{
"name": "injected_var",
"value": "injected_from_aws_cli_ecs_run_task"
}
]
}
]
}'
ECSの実行ログから、環境変数が注入されているのを確認できた。
6. カスタマイズ(3)
タスク内でログをファイルに書き出し、それをS3へアップロードしたい。
S3に bucket daiki-test-ecs
を作成する。
ローカルのDockerfileを以下のように更新する。
(TODO: aws-cli を含むベースイメージがないか調べる)
FROM ubuntu:latest
RUN apt-get update && apt-get install -y less vim curl unzip sudo
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN sudo ./aws/install
CMD echo "Hello from Daiki in custom docker file. I got injected_var=${injected_var}" >> "/log.txt" && \
aws s3 cp /log.txt s3://daiki-test-ecs/
ビルドしてECRにpushする。
docker build -t daiki-test . && \
docker tag daiki-test:latest 111111111111.dkr.ecr.us-east-1.amazonaws.com/daiki-test:latest && \
docker push 111111111111.dkr.ecr.us-east-1.amazonaws.com/daiki-test:latest
ecsTaskExecutionRole
に、AmazonEC2ContainerRegistryReadOnly
ポリシーを付与してやる。
ECSのタスクを実行する。
aws ecs run-task \
--cluster daiki-load-testing-test \
--task-definition daiki-loadtesting-test-task:3 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-6331723a],assignPublicIp=ENABLED}" \
--overrides '{
"containerOverrides": [
{
"name": "daiki-test-image-in-ecr",
"environment": [
{
"name": "injected_var",
"value": "injected_from_aws_cli_ecs_run_task"
}
]
}
]
}'
結果はUnable to locate credentials
とのこと。
必要な権限をECS task definitionに付与する。
IAM policyの作成
IAM roleの作成
作成したIAM roleをECS taskに紐付ける。
新しく、daiki-loadtesting-test-task:4
を発行した。
aws ecs run-task \
--cluster daiki-load-testing-test \
--task-definition daiki-loadtesting-test-task:4 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-6331723a],assignPublicIp=ENABLED}" \
--overrides '{
"containerOverrides": [
{
"name": "daiki-test-image-in-ecr",
"environment": [
{
"name": "injected_var",
"value": "injected_from_aws_cli_ecs_run_task"
}
]
}
]
}'
タスク内でS3へのアップロードが完了していた。
S3内にファイルが存在することも確認した。
Ref.