abstract
2021年の3月より、AWS ECSがアップデートされ、実行中のコンテナにecs exec
できるようになった。AWSの公式ドキュメントでは、新しいコンテナをデプロイする際に、あらかじめecs exec
できるようにする手段が記載されているが、ここでは、すでに実行中のコンテナに対して、ecs exec
できるようにするために行った手順を記録しておく。先述のリンク先にも記載のある通り、コンテナにexec機能を事後にオプトインすることで、デプロイ時にはecs execできない設定のコンテナも、あとからecs execを利用できる。なお、EC2上で起動するECSタスクは本稿の対象でない。
prerequisite
client-side
AWS CLIを利用可能な最新バージョンにアップグレードすること
必要であればSSM Pluginをインストールすること
なお、AWSCloudShellを用いるとクライアント側のツール導入作業フリーで本稿の作業を実施できるのでおすすめである
server-side
Fargate v 1.4.0以上を利用すること
assumption
nginxコンテナを実行中。80ポートで通信を受け付けている。
タスクロールとしてecsTaskRoleTest(カスタムロール)を使用。タスク実行ロールとしてecsTaskExecutionRole(AWSマネージドロール)を使用。
今のnginxコンテナは、ecs exec
を受け付けない状態。
protocol
- 実行中のタスクのECSタスクロールに、SSMを経由してAWSサービスとやりとりするための権限を付与する
- 実行中のタスクにECSタスク実行ロールが付与されていることを確認する(されていなければ付与する)
- 実行中のタスクの
enableExecuteCommand
をtrue
に変更する - ecs execを使ってコンテナの中に入れることを確認する
実行中のタスクのECSタスクロールに、SSMを経由してAWSサービスとやりとりするための権限を付与する
まず、SSMを使う権限をECSタスクロールに付与する。
以下の内容は、ecs exec
するにあたって最低限必要なSSMに関する部分のみの抜粋である。このほか、対象とするコンテナがDynamoDBとやりとりしたり、S3とやりとりしたりする必要がある場合は、それらも明示的な許可が必要である。すでに運用中のコンテナであれば、タスクロールですでにそれらが明示的に許可されているはずであるので、その場合は、すでに許可されているエンティティに追加して、以下のjsonで示すエンティティも許可する。以下の内容をecsExecTestTaskRolePolicy.json
として保存する。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
ここでは、ecsTaskRoleTest
というすでに付与しているタスクロールに対して、上記のecsExecTestTaskRolePolicy
をアタッチする。以下のコマンドを実行する(マネコンからも実施可能である)。
aws iam put-role-policy \
--role-name ecsTaskRoleTest \
--policy-name ecsExecTestTaskRolePolicy \
--policy-document file://ecsExecTestTaskRolePolicy.json
これでタスクロールにecs exec
するうえで最低限必要な権限が付与できた。
実行中のタスクにECSタスク実行ロールが付与されていることを確認する(されていなければ付与する)
ここでは、タスク実行ロールは、タスク定義を作成するときにecsTaskExecutionRole
(AWSマネージドロール)を利用した想定である。参考までに、もし、独自のロールを設定した場合、次のコマンドで、すでに実行中のタスクのタスク実行ロールにecsTaskExecutionRole
を付与できそうである。
aws iam attach-role-policy \
--role-name yourCustomRoleName \
--policy-arn "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
実行中のタスクのenableExecuteCommand
をtrue
に変更する
aws ecs describe-services --services yourServiceName
を実行すると、以下のように表示される。enableExecuteCommand
がfalse
になっているので、現状、このコンテナに対してecs exec
できない状態であることがわかる。
{
"services": [
{
"networkConfiguration": {
"awsvpcConfiguration": {
"subnets": [
(中略)
"enableExecuteCommand": false
}
],
"failures": []
}
下記のコマンドを発行し、実行中のタスクを更新する。ここでは、ecs exec
できるように状態を変更する(サービスでない場合は、run-task
コマンドを使い、タスクを再デプロイする)。ここが本稿のキモである。enableExecuteCommand
がFalse
の既存のコンテナであっても、 exec 機能をオプトインすることができる。なお、新規にサービスを実行したり、タスクを実行したりする場合は、--enable-execute-command
オプションを付けることで、exec機能を有効にしてデプロイできる。
$ aws ecs update-service \
--cluster yourClusterName \
--service yourServiceName \
--enable-execute-command
実行した結果、下記のように、enableExecuteCommand
がtrue
に切り替わっている(aws ecs describe-tasks
コマンドでも確認できる)。
(前略)
"enableExecuteCommand": true
}
}
最後に、サービス自体を再デプロイする必要がある。コンソールで、サービスを強制的にデプロイにチェックを入れ、再デプロイする。これで、これまで実施してきた変更が実行中のタスクに対して適用される。
ecs execを使ってコンテナの中に入れることを確認する
以上で、ecs execの準備は整った。以下のコマンドで、コンテナの中に入る。なお、タスクのIDはマネコンから確認可能である。
aws ecs execute-command \
--region yourAWS_REGION \
--cluster yourClusterName \
--task yourTaskId \
--container nginx \
--command "/bin/bash" \
--interactive
下記のように、コンテナの中でBashシェルを操作できている。
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
Starting session with SessionId: ecs-execute-command-013e4b9c436ac6bbe
root@1a098f439dc742ef98a596612e581195-2531612879:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 managed-agents media mnt opt proc root run sbin srv sys tmp usr var
root@1a098f439dc742ef98a596612e581195-2531612879:/#
Summary
すでに運用しているタスク(の中のコンテナ)に、ecs exec
を使い、Bashシェルでログインする手順を記載した。運用中のコンテナのトラブルシューティングの際に役立つ。