ECS Execを使ってFargateにログインする方法

■はじめに

現在参画している案件で管理コストの観点からECSonEC2 から ECSonFargateへ移行することになりました。
移行するにあたって、従来のコンテナへの接続方法からECS Execを使用した方法に変更することになったので、そちらの方法を紹介できればと思います。
 

■構成図

■EC2からFargateへ移行することでのメリット・デメリット(ざっくりと)

メリット
・ホストマシンのOSやミドルウェアなどの構築・管理が不要
・インスタンスタイプやクラスター管理が不要
・実行環境のオートスケーリングが不要

デメリット
・パブリックIPの固定割り当てができない
・sshやdocker execが使えない
 └今回のポイントです!
 

■ECSonFargateでコンテナへ接続する方法

コンテナへ接続できないと障害が発生した際に、トラブルシューティングに必要な情報を集めるのが難しくなります。
ここで登場するのが、ECS Execです。
ECS Execでは、AWS Systems Manager (SSM) の「セッションマネージャー」の仕組みを使うことで、クライアントからSSMコンポーネントを経由してコンテナにアクセスすることを実現しています。

■ECS Execが利用できるようになるまでの手順

以下の順番で手順を紹介していきます。

  1. 前提条件
  2. AWS CLI バージョン確認
  3. Session Manager プラグインをインストール
  4. ECS Execの有効化
  5. タスクロールの付与
  6. IAMポリシーの作成・アタッチ
     

-前提条件

・下記サイトを参考にECS on Fargateの構築が完了していること。
AWS Hands-on for BeginnersAmazon Elastic Container Service 入門 コンテナイメージを作って動かしてみよう
協栄情報ブログ
 

踏み台サーバでの作業

前提条件で作成したCloud9を踏み台サーバとして利用していきます。
 

-AWS CLI バージョン確認

AWS公式ドキュメントに、以下の記載があるので確認します。

AWS CLI バージョン 1.22.3 以降、または AWS CLI バージョン 2.3.6 以降を使用する必要があります。AWS CLI をアップデートする情報については、AWS Command Line Interface ユーザーガイドバージョン 2 の「AWS CLI の最新バージョンのインストールまたはアップデート」を参照してください。
 

引用:AWS公式ドキュメント
 

# aws --version
aws-cli/2.15.17 Python/3.11.6 Linux/6.1.72-96.166.amzn2023.x86_64 exe/x86_64.amzn.2023 prompt/off

 

-Session Manager プラグインをインストール

AWS Command Line Interface (AWS CLI) を使用してマネージドノードとの Session Manager セッションを開始するには、ローカルマシンに Session Manager プラグインをインストールする必要があるので、下記コマンドでインストールします。

引用:AWS公式ドキュメント
 

# sudo yum install -y https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm

インストール実施後、下記コマンドで正常にインストールできたことの確認をします。
次のメッセージが出力されたらOKです。

# session-manager-plugin
The Session Manager plugin is installed successfully. Use the AWS CLI to start a session.

-ECS Execの有効化

下記コマンドで、ECSサービスのenableExecuteCommandの値を確認し、falseであれば、有効化します。

# aws ecs describe-services --region [リージョン] --cluster [クラスター名] --services [サービス名] | grep enableExecuteCommand
            "enableExecuteCommand": false
# aws ecs update-service /
--region [リージョン] /
--cluster [クラスター名] /
--service [サービス名] /
--enable-execute-command
# aws ecs describe-services --region [リージョン] --cluster [クラスター名] --services [サービス名] | grep enableExecuteCommand
            "enableExecuteCommand": true

 

タスク定義での作業

事前作業ではタスクロールを付与せずにタスク定義を作成したので、付与していきます。

-タスクロールの付与

作成したタスク定義を選択して「JSONを使用した新しいリビジョンでの作成」を押下、「ecsTaskExecutionRole」を設定します。
※追加でAWSで推奨しているinitProcessEnabledtrue に設定しておきましょう。

Exec を実行する前に、InitProcessEnabled パラメーターを true に設定するのがベストプラクティスです。これにより、AWS Systems Manager Agent (SSM Agent) の子プロセスが孤立するのを防ぐことができます。(オプション) アプリケーションコンテナにスリープコマンドを追加して、指定した期間コンテナを稼働させ続けます。

引用:AWS公式ドキュメント


 

 

IAMポリシーの作成・アタッチ

IAMの管理画面から「ecsTaskExecutionRole」に付与するポリシーを作成し、アタッチします。
※ECSからセッションマネージャーにアクセスするためのIAMポリシーとなります。
ポリシーは以下になります。

{
"Version": "2012-10-17",
"Statement": [
   {
   "Effect": "Allow",
   "Action": [
        "ssmmessages:CreateControlChannel",
        "ssmmessages:CreateDataChannel",
        "ssmmessages:OpenControlChannel",
        "ssmmessages:OpenDataChannel"
   ],
  "Resource": "*"
  }
]
}

 

コンテナ接続

先ほど作成した新たなリビジョンのテスク定義を指定して、タスクを起動してください。
※ECS Exec機能は「enableExecuteCommand」を有効にした後に起動したタスクでのみ利用可能となります。
 
ECSサービス画面にてサービスを選択し更新を押下、「新しいデプロイの強制」にチェックを入れることで強制的にタスクの起動行います。
※新たなコンテナに生まれ変わります。

 

-ECS Execを実行

踏み台サーバにログインし、下記コマンドを実行します。
次のメッセージが出力されたらコンテナに接続できたことになります。

# aws ecs execute-command /
--region [リージョン] /
--cluster [クラスター名] /
--task [タスクのARN] /
--interactive /
--command "/bin/sh"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.

Starting session with SessionId: ecs-execute-command-XXXXXXXXXXXXXXXXX
/ #

 
ちなみに、このままだとAWS CloudShellからもコンテナに接続出来てしまうのでIAMユーザに踏み台サーバのVPCを選択してアクセス制御するなどした方が良いかもですね。
例として、次のようなポリシーを作成しIAMユーザにアタッチしてみました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Deny",
            "Action": "ecs:ExecuteCommand",
            "Resource": "arn:aws:ecs:[リージョン]:[アカウントID]:cluster/[クラスター名]",
            "Condition": {
                "StringNotEqualsIfExists": {
                    "ecs:ResourceTag/Login": "true"
                }
            }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Deny",
            "Action": "ecs:ExecuteCommand",
            "Resource": "arn:aws:ecs:[リージョン]:[アカウントID]:cluster/[クラスター名]",
            "Condition": {
                "ForAnyValue:StringNotEqualsIfExists": {
                    "aws:SourceVpc": "[VPC ID]"
                }
            }
        }
    ]
}

上記ポリシーでは、次の2つの条件にマッチした場合にのみ"Resource"に記載のクラスター内のコンテナにログインできるようにしています。

  1. クラスターのタグが、「キー:Login」、「値:true」
  2. 接続元VPCが、「踏み台サーバの存在するVPC」

各々要件に合わせて制御していきましょう。
 

■まとめ

ECSだけで、クラスター・サービス・タスク・タスク定義・コンテナ。
タスク定義上で設定する、タスクロール(ポリシー)・タスク実行ロール。。
更には、IAMロールにアタッチするポリシーと扱うリソースが多くどこの作業をしているか混乱しました。
混乱したら一度手を止め、構成図に戻り目的を再確認し、どのリソースに対しての作業を実施するのかを考えるといいですね。

Last modified: 2024-02-12

Author