手が空いたのでecs-cliでもやってみようとチュートリアルを試してみたら、ハマったのでメモ。
やりたいこと
- ecs-cliでFargateクラスターとサービスを立ち上げる。
ハマったこと
- タスクを上げる最後の最後のところで失敗する。
ecs-cliでFargateクラスターを立ち上げ、タスク定義を投入してサービスを立ち上げるというのが大まかなチュートリアルの流れなのだが、この最後のコマンドが失敗する。
% ecs-cli compose --project-name myFargateSvc service up
INFO[0005] Using ECS task definition TaskDefinition="myFargateSvc:2"
INFO[0005] Auto-enabling ECS Managed Tags
INFO[0011] (service myFargateSvc) has started 1 tasks: (task 610ec5cbc7f346569f9f1d42ec37497a). timestamp="2020-06-09 02:48:02 +0000 UTC"
INFO[0257] (service myFargateSvc) has started 1 tasks: (task 8de67ade75754c58a4d44b47ab712c09). timestamp="2020-06-09 02:52:10 +0000 UTC"
INFO[0308] Created an ECS service service=myFargateSvc taskDefinition="myFargateSvc:2"
FATA[0308] Deployment has not completed: Running count has not changed for 5.00 minutes
コンソールを見ると、どうやらタイムアウトエラーで起動に失敗している模様。
直接の原因はこれらしい。
DockerTimeoutError: Could not transition to started; timed out after waiting 3m0s
切り分け開始
詳しいログでも出てないかと、まずはタスクからログを送っている先であるCloudWatch Logs(awslogs)を見てみるも、空のまま。ただし、ロググループまでは作成されている。ロググループだけがない状態。
タスク定義(docker-compose.yml
)もECS定義(ecs-params.yml
)も間違っているようには見えない。そもそもそんなに複雑なことはしていない。
一体何が原因だ。。。
version: '3'
services:
web:
image: amazon/amazon-ecs-sample
ports:
- "80:80"
logging:
driver: awslogs
options:
awslogs-group: /ecs/myFargate0609
awslogs-region: ap-northeast-1
awslogs-stream-prefix: web
version: 1
task_definition:
task_execution_role: ecsTaskExecutionRole
ecs_network_mode: awsvpc
task_size:
mem_limit: 0.5GB
cpu_limit: 256
run_params:
network_configuration:
awsvpc_configuration:
subnets:
- "subnet-XXXX"
- "subnet-YYYY"
security_groups:
- "sg-ZZZZ"
assign_public_ip: ENABLED
調べてみると、同じエラーでハマっている先人を発見。
Stopped Reason field not populated on "Failed to Start"
awslogsドライバーで送り込んでいるログ設定が間違っていたとのこと。確かに怪しい。
試しに、CloudWatch Logsにログを送り込んでいる箇所を削ってみる。
version: '3'
services:
web:
image: amazon/amazon-ecs-sample
ports:
- "80:80"
あっさり動いた。
% ecs-cli compose --project-name myFargateSvc service up
INFO[0000] Using ECS task definition TaskDefinition="myFargateSvc:3"
INFO[0000] Auto-enabling ECS Managed Tags
INFO[0010] (service myFargateSvc) has started 1 tasks: (task af78daabe9374bf6ae347c6526108201). timestamp="2020-06-09 03:20:49 +0000 UTC"
INFO[0041] Service status desiredCount=1 runningCount=1 serviceName=myFargateSvc
INFO[0041] (service myFargateSvc) has reached a steady state. timestamp="2020-06-09 03:21:19 +0000 UTC"
INFO[0041] ECS Service has reached a stable state desiredCount=1 runningCount=1 serviceName=myFargateSvc
INFO[0041] Created an ECS service service=myFargateSvc taskDefinition="myFargateSvc:3"
スケーリングも自由自在。
ecs-cli compose --project-name myFargateSvc service scale 3
INFO[0000] Updated ECS service successfully desiredCount=3 force-deployment=false service=myFargateSvc
INFO[0000] Service status desiredCount=3 runningCount=1 serviceName=myFargateSvc
INFO[0010] (service myFargateSvc) has started 2 tasks: (task 7a6cef0567be470aa37f959a21764130) (task 8a75f3e18be443a28524fb357bed1375). timestamp="2020-06-09 03:37:25 +0000 UTC"
INFO[0025] Service status desiredCount=3 runningCount=2 serviceName=myFargateSvc
INFO[0030] Service status desiredCount=3 runningCount=3 serviceName=myFargateSvc
INFO[0030] ECS Service has reached a stable state desiredCount=3 runningCount=3 serviceName=myFargateSvc
いったいどういうことだ・・・?
最初に疑ったのは権限。
FargateからCloudWatchLogsにログを送り込むのに必要なのは、ecs-param.ymlにもあったこのロール、ecsTaskExecutionRoleのようだ。正確にはそこにアタッチされているAWS管理ポリシーAmazonECSTaskExecutionRolePolicy、もっと言うとlogs:XX
の権限とみられる。
ecsTaskExecutionRoleに絞ってググってみると、以下がヒットした。
ecsTaskExecutionRoleを自作したらFargateにデプロイできなくなった注意点
Unable to assume the service linked role when following the fargate tutorial #733
うーん、おかしくはなさそうだ。ポリシー上は、ログストリームを作成してログを送り込めない理由が見当たらない。
となるとネットワークか?
とさらにググって、参考になりそうなのを発見。
Fargate: support launching tasks in offline subnets #48
だが、よくよく考えてみると自分の設定はプライベートではなくパブリックサブネットなので、CloudWatch LogsへのPrivateLinkはいらないはず。念のため確認してみたがやはりインターネットへのコネクティビティがしっかり設定されているパブリックサブネットだった。これもボツ。
公式を見ながら、ecs-params.ymlに足りてなさそうなパラメーターがないか探す。
手がかりなし。
そろそろ途方に暮れてきたので、投げやり気味な実力行使で打開を試みることにする。
先程のecsTaskExecitionRoleに立ち戻り、試しにCloudWatchLogsのフル権限(CloudwatchLogsFullAccess
)を与えてみる。
何と動いた。
ロググループ内のストリームも、今度は作成されている。
これはecsTaskExecutionRoleに割り当てられているAWS管理ポリシーが、Fargateを動かす上で実際には不足しているということか・・・?(似た経験あり)
と疑いつつも一応、もう一度フル権限を外して仮説検証してみると、設定上は不動状態に戻ったはずなのにやっぱり動いてしまった。
そしてこの後は、何度作り直しても何の問題もなく動作するようになったのだった・・・
結論
世の中には不思議なこともある。
(切り分け的には何の結論も出てませんが、トライアンドエラーの過程がどなたかの助けになるかも知れないので一応残しておきます)