Fargateですで起動しているコンテナ(運用中)にあとからecs execする


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

  1. 実行中のタスクのECSタスクロールに、SSMを経由してAWSサービスとやりとりするための権限を付与する
  2. 実行中のタスクにECSタスク実行ロールが付与されていることを確認する(されていなければ付与する)
  3. 実行中のタスクのenableExecuteCommandtrueに変更する
  4. 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"

実行中のタスクのenableExecuteCommandtrueに変更する

aws ecs describe-services --services yourServiceNameを実行すると、以下のように表示される。enableExecuteCommandfalseになっているので、現状、このコンテナに対してecs execできない状態であることがわかる。

{
    "services": [
        {
            "networkConfiguration": {
                "awsvpcConfiguration": {
                    "subnets": [

(中略)

            "enableExecuteCommand": false
        }
    ], 
    "failures": []
}

下記のコマンドを発行し、実行中のタスクを更新する。ここでは、ecs execできるように状態を変更する(サービスでない場合は、run-taskコマンドを使い、タスクを再デプロイする)。ここが本稿のキモである。enableExecuteCommandFalseの既存のコンテナであっても、 exec 機能をオプトインすることができる。なお、新規にサービスを実行したり、タスクを実行したりする場合は、--enable-execute-commandオプションを付けることで、exec機能を有効にしてデプロイできる。

$ aws ecs update-service \
    --cluster yourClusterName \
    --service yourServiceName \
    --enable-execute-command

実行した結果、下記のように、enableExecuteCommandtrueに切り替わっている(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シェルでログインする手順を記載した。運用中のコンテナのトラブルシューティングの際に役立つ。