Amazon Web Services ブログ

Amazon EC2 および AWS Fargate 上の Windows コンテナにアクセスするための Amazon ECS Exec のご紹介

この記事は、Introducing Amazon ECS Exec to access your Windows containers on Amazon EC2 and AWS Fargate を翻訳したものです。

本投稿は、Software Engineer の Harsh Rawat により寄稿されました。

2022 年 4 月 4 日 (米国時間)、Amazon Elastic Compute Cloud (Amazon EC2)AWS Fargate または Amazon ECS Anywhere 上で Windows コンテナを実行する Amazon Elastic Container Service (Amazon ECS) をご利用の方向けに、Amazon ECS Exec 機能の提供を開始します。この機能により、Amazon EC2 上で動作しているコンテナ内でコマンドを実行したり、Shell を取得したりできます。この記事では、必要なインフラストラクチャをセットアップする手順を説明し、Amazon EC2 および AWS Fargate 上で動作する Amazon ECS Windows ワークロードのための Amazon ECS Exec の機能をご紹介します。

バックグラウンド

この機能の提供開始以前、デバッグのためにコンテナ内でコマンドを実行する必要がある場合、Fargate 起動タイプではそのオプションはありませんでした。EC2 起動タイプでは次のような複雑なプロセスを経る必要がありました。

  • Windows のリモートデスクトッププロトコル (RDP) または AWS Systems Manager Session Manager を使用して、ホストの EC2 インスタンスにアクセスします。セキュリティ向上のためにインスタンスへの RDP アクセスが無効になっていたり Session Manager の IAM ポリシーが存在しないシナリオでは、セキュリティ対策を回避してホスト EC2 インスタンスにアクセスする必要があります。
  • アクセスしたいタスクの特定のコンテナのコンテナ ID を検索します。本番環境では、1 つの EC2 インスタンス上で複数のコンテナを持つ複数のタスクが実行されることがあります。その場合、特定のタスクのコンテナ ID を見つけるには、複数の CLI コマンドが必要になります。
  • docker exec を使って、コンテナ内でコマンドを実行します。

これらのプロセスは面倒なだけでなく、そのようなセッションのロギングに対するネイティブサポートもありませんでした。本番環境でそのようなセッションのロギングと監査を行わないことは、セキュリティにおいて望ましいことではありません。この機能リリースによってこれらの問題に対処し、Amazon ECS for Windows をご利用の方向けにシームレスなカスタマーエクスペリエンスを継続的に提供いたします。

この機能によって利用できる主な機能は、次のとおりです。

  • Amazon EC2 上で動作するタスクの Windows コンテナに対して安全な対話型セッションを確立し、スタンドアロンコマンドを実行する機能
    • Amazon ECS Exec は、AWS Systems Manager、特に Systems Manager Session Manager を活用して、exec コマンドを実行するデバイスとターゲットコンテナとの間に安全なチャネルを作成します。
    • Amazon ECS Exec は、クライアントプラットフォームに依存しません。つまり、AWS CLI または AWS Copilot をインストールしているすべての Windows、Linux、Mac ユーザーは、Amazon ECS Exec を使用して、EC2 Windows インスタンス上で動作するコンテナでコマンドを実行することができます。
    • Amazon ECS Exec は、AWS SDK を経由して使用することもできます。
  • セッションコマンド出力の Amazon S3 や Amazon CloudWatch へのロギングのネイティブサポート
  • 監査用の Amazon ECS Exec セッション情報の AWS CloudTrail へのロギング
    • AWS API 呼び出しのみが (コマンドとともに) AWS CloudTrail に記録されることに注意してください。他のコマンドとその出力は、設定に応じて CloudWatch または Amazon Simple Storage Service (Amazon S3) に記録されます。
  • クライアントとコンテナ間のデータチャンネルを保護するための、独自の AWS Key Management Service (AWS KMS) キーを使用するためのサポートを追加。デフォルトでは、通信は TLS1.2 を使用して保護されます。

留意点

  • Amazon ECS Exec は、AWS SDKAWS CLI および AWS Copilot でサポートされています。今後、本機能のマネジメントコンソールでのサポートを追加する予定です。
  • Amazon ECS Exec 機能は、EC2 起動タイプを使用する場合の Windows Server 2016 ではサポートされていません。
  • コンテナ上に存在するコマンド、スクリプト、Shell のみを使用することができます。例えば、Windows Nanoserver をベースにしたイメージに同じものが存在しない場合 (訳注 : 利用するベースイメージに期待する PowerShell パッケージが含まれていない場合)、PowerShell を起動することはできません。
  • コンテナ上に存在するコマンド、スクリプト、シェルのみを使用することができます。例えば PowerShell は、イメージに同じものが存在しない場合はイメージ上で起動させることができません。
  • 既存のタスクに対して Amazon ECS Exec を有効にすることはできません。タスク起動時に --enable-execute-command フラグを指定することで、新しいタスクに対してのみ有効にすることができます。

前提条件

Amazon ECS Exec を Windows ワークロードで使用するには、いくつかの要件を満たす必要があります。

  • AWS CLI (Mac、Linux または Windows 用) および PowerShell 用 AWS Tools (Windows 用のみ) がコンピューターに正しくインストールされ、設定されている必要があります。
  • AWS CLI 用の Session Manager プラグインがマシンにインストールされている必要があります。
  • EC2 インスタンスには、Amazon ECS エージェントのバージョン 1.56.0 以上が必要です。
    • Amazon ECS に最適化された AMI を使用している場合、最新の AMI を使用することで本機能をすぐに使用することができます。
    • また、カスタムコンポーネントを使用して、Amazon ECS Exec をサポートするカスタム AMI を構築することもできます。詳細は、Amazon ECS デベロッパーガイドをご覧ください。

はじめに

インフラストラクチャの設定

Amazon ECS Exec を使用して Amazon EC2 で実行されているコンテナに対して実行する前に、必要なインフラストラクチャをセットアップする必要があります。これには以下が含まれます。

  • (任意) Amazon ECS Exec を使用してコンテナインスタンスにアクセスする際に、通信を暗号化するための AWS KMS キー
  • (任意) Amazon S3 や CloudWatch などのロギングオプション
  • タスクに適切な権限を付与するための関連する IAM ロール

AWS KMS キーを作成する

  1. AWS KMS のコンソールにアクセスします。
  2. コンソールにてキーの作成を押します。
  3. 「キーの作成」ウィザードにて、以下のように進めます。
    1. キーのタイプは「対称」を選択します。
    2. 適切なキーのエイリアス名を指定します。例えば、ecs_exec_windows_demo_key などです。
    3. 「キーの管理アクセス許可を定義」で次へを選択します。
    4. 「キーの使用アクセス許可を定義」で次へを選択します
    5. 完了を押して、AWS KMS キーを作成します。
    6. キー ID は次のステップで使用しますので、メモしておいてください。

詳しくは、キーの作成に関するドキュメントをご覧ください。

Key Management Service console key configuration

続いて、セッションログを保存するための Amazon S3 バケットと CloudWatch ロググループを作成します。

Amazon S3 バケットを作成する

  1. Amazon S3 のコンソールにアクセスします。
  2. コンソールにてバケットを作成を押します。
  3. 「バケットを作成」ウィザードにて、以下のように進めます。
    1. 適切なバケット名を指定します。例えば、ecs-exec-windows-demo-bucket のように入力します。
    2. バケットを配置するリージョンを選択します。
    3. 「このバケットのブロックパブリックアクセス設定」で、バケットに適用したいブロックパブリックアクセス設定を選択します。今回のデモでは、すべてのパブリックアクセスをブロックすることができます。
    4. バケットを作成を押し、S3 バケットを作成します。

詳しくは、Amazon S3 ユーザーガイドをご覧ください。

Creating S3 bucket in console

CloudWatch ロググループを作成する

  1. CloudWatch のコンソールにアクセスします。
  2. サイドメニューのログからロググループを選択します。
  3. コンソールにてロググループを押します。
  4. 「ロググループを作成」ウィザードにて、以下のように進めます。
    1. ロググループ名を入力します。例えば、ecs_exec_windows_demo_log_group のようにします。
    2. 必要に応じて、保持期間の設定を選択します。
    3. 作成を押して、ロググループを作成します。>

詳しくは、こちらで公開されているドキュメントをご覧ください。

Creating CloudWatch log group in console

Amazon ECS Exec を有効にするためのタスクに必要な IAM ロールを作成する

  1. AWS Identity and Access Management (IAM) コンソールにアクセスします。
  2. サイドメニューのアクセス管理からロールを選択します。
  3. 必要なタスクロールを作成するために、以下のように進めます。
    1. コンソールにてロールを作成を押します。
    2. 「信頼されたエンティティを選択」にて、信頼されたエンティティタイプは AWS のサービスを、ユースケースとして他の AWS のサービスのユースケース中から Elastic Container Service を選択し、プルダウン下に表示される選択肢から Elastic Container Service Task を選択します。
    3. 「許可を追加」画面で、AmazonECSTaskExecutionRolePolicy ポリシーをアタッチします。
    4. レビュー画面で適切なロール名を指定します。例えば ecs_exec_windows_demo_task_role などです。
    5. ロールを作成を押して、タスクロールを作成します。UI to select create role option
    1. 必要なタスク実行ロールを作成するため、以下のように進めます。
      1. タスク実行ロールを作成する前に、このロールに必要な IAM ポリシーを作成しておきます。
        1. サイドメニューのアクセス管理からポリシーを選択し、コンソールにてポリシーの作成を押します。
        2. 「ポリシーの作成」ウィザードで、タブにて JSON を選択してポリシーを設定していきます。
        3. ポリシーエディタに以下の JSON をコピーします。AWS_REGIONACCOUNT_IDLOG_GROUP_NAMEECS_EXEC_BUCKET_NAMEKMS_KEY_ARN を追加するために JSON を編集することを忘れないでください。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
            },
            {
            "Effect": "Allow",
            "Action": [
                "logs:DescribeLogGroups"
            ],
            "Resource": "*"
            },
            {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:DescribeLogStreams",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:<AWS_REGION>:<ACCOUNT_ID>:log-group:<Log_GROUP_NAME>:*"
            },
            {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::< ECS_EXEC_BUCKET_NAME>/*"
            },
            {
            "Effect": "Allow",
            "Action": [
                "s3:GetEncryptionConfiguration"
            ],
            "Resource": "arn:aws:s3:::<ECS_EXEC_BUCKET_NAME>"
            },
            {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": "<KMS_KEY_ARN>"
        }
    ]
}
      1. このポリシーに適切な名前を指定します。例えば、ecs_exec_windows_demo_task_execution_role_policy などです。
      2. ウィザードを進め、最後のステップでポリシーの作成を押して、このポリシーを作成します。
    1. タスク実行ロールを作成します。
      1. コンソールにてロールを作成を押します。
      2. 「信頼されたエンティティを選択」にて、信頼されたエンティティタイプは AWS のサービスを、ユースケースとして他の AWS のサービスのユースケース中から Elastic Container Service を選択し、プルダウン下に表示される選択肢から Elastic Container Service Task を選択します。
      3. 「許可を追加」画面で、上記で作成したポリシーをアタッチします。
      4.  レビュー画面で適切なロール名を指定します。例えば ecs_exec_windows_demo_task_execution_role のようにします。
      5. ロールを作成を押して、タスク実行ロールを作成しますUI to select create role option

タスク実行ロールの作成についての詳細は、Amazon ECS デベロッパーガイドを参照してください。

クラスターの作成

ここからは、前出の「インフラストラクチャの設定」で作成した AWS KMS キー、S3 バケット、CloudWatch ロググループを使用するデモ用のクラスターを作成していきます。

aws ecs create-cluster \
    --cluster-name <CLUSTER_NAME> \
    --region <AWS_REGION> \
    --configuration executeCommandConfiguration="{logging=OVERRIDE,\ kmsKeyId=<KMS_KEY_ID>,\ logConfiguration={cloudWatchLogGroupName=<LOG_GROUP_NAME>,\ s3BucketName=<S3_BUCKET_NAME>,\ s3KeyPrefix=exec-output}}"

:現時点では、AWS CLI、AWS SDK または AWS Copilot を使用して実行する必要があります。また、ロギングの設定が不要な場合は、コンソール自体からクラスターを作成し、Amazon ECS Exec を使用して Windows コンテナにアクセスするために使用することができます。

クラスターを作成した後は、Fargate 起動タイプを使ってタスクを起動することで、コンテナインスタンスを管理する必要がなくなります。また、最新の Amazon ECS 最適化Windows AMI で EC2 インスタンスを起動し、ECS Exec を使用することもできます。

タスクの実行

必要なインフラストラクチャが作成できたので、上記で作成した IAM ロールを使って簡単なタスク定義を登録してみます。以下にタスク定義のサンプルを示します。タスク定義にあるように、このタスク定義では Amazon ECS Exec への参照を追加していないため、既存のタスク定義でこの機能を利用することができます。

{
  "family": "ecs-exec-demo",
  "executionRoleArn": "<ARN_OF_THE TASK_EXECUTION_ROLE_CREATED_EARLIER>",
  "taskRoleArn": "<ARN_OF_THE TASK_ROLE_CREATED_EARLIER>",
  "runtimePlatform": {
    "cpuArchitecture": "X86_64",
    "operatingSystemFamily": "WINDOWS_SERVER_2019_CORE"
  },
  "requiresCompatibilities": [
    "EC2",
    "FARGATE"
  ],
  "containerDefinitions": [
    {
      "entryPoint": [
        "powershell",
        "-Command"
      ],
      "command": [
        "ping -t localhost"
      ],
      "cpu": 1024,
      "memory": 1024,
      "image": "mcr.microsoft.com/windows/servercore:ltsc2019",
      "name": "windows_container"
    }
  ],
  "memory": "4096",
  "cpu": "2048",
  "networkMode": "awsvpc"
}

以下の手順でタスク定義を登録します。

  1. Amazon ECS のコンソールにアクセスします。
  2. ナビゲーションバーからタスク定義を選択します。
  3. コンソールにて新しいタスク定義の作成を押します。
  4. 「新しいタスク定義の作成」ウィザードにて、以下のように進めます。
    1. 起動タイプの互換性の選択で EC2 を選択します。
    2. 「タスクとコンテナの定義の設定」画面においてJSON による設定を使用し、上記の JSON を追加します。
    3. 作成を押して、タスク定義を作成します。

詳しくは、タスク定義の作成のドキュメントをご覧ください。

これで、Fargate 起動タイプまたは EC2 起動タイプを使って Amazon ECS タスクを実行し、Amazon ECS Exec を使用しながら起動する準備が整いました。
注:今のところ、Amazon ECS Exec の有効化は AWS CLI、AWS SDK または AWS Copilot 経由でのみサポートされています。

EC2 起動タイプの場合

aws ecs start-task --cluster <CLUSTER_NAME> \
--container-instances <ECS_CONTAINER_INSTANCE_ID> \
--enable-execute-command \
--task-definition <TASK_DEFINITION_NAME>

Fargate 起動タイプの場合

aws ecs run-task \ 
--cluster <CLUSTER_NAME> \
--task-definition <TASK_DEFINATION> \
--network-configuration awsvpcConfiguration="{subnets=[<PUBLIC_SUBNET_ID>],securityGroups=[<SECURITY_GROUP_ID>],assignPublicIp=ENABLED}" \
--enable-execute-command \
--launch-type FARGATE \
--region <AWS_REGION>

上記コマンドでの PUBLIC_SUBNET_ID および SECURITY_GROUP_ID は、それぞれご利用の VPC における適切な値に置き換えてください。

--enable-execute-command フラグを使用すると、そのタスクの Amazon ECS Exec がオンになります。同じことはタスクを記述することで確認できます。これは describe-tasks コマンドを実行することで確認できます。内部的には ExecuteCommandAgent というマネージドエージェントが、このタスクのために ecs-agent によって起動されます。このマネージドエージェントは Amazon ECS Exec のコア機能を担っています。

describe-tasks によるタスクに問い合わせした結果において、enableExecuteCommand フラグが true に設定されていて、マネージドエージェント ExecuteCommandAgent が実行状態になっていることを確認できます。

aws ecs describe-tasks \
--cluster <CLUSTER_NAME> \
--region <AWS_REGION> \
--tasks <TASK_ID>

Amazon ECS Exec との対話セッションの開始

EC2 インスタンス上で Amazon ECS タスクが実行されました。Amazon ECS Exec を使って、実行中のタスクのコンテナとの対話セッションを開始してみます。

aws ecs execute-command \
--region <AWS_REGION> \
--cluster <CLUSTER_NAME> \
--task <TASK_ID> \
--container windows_container \
--interactive \
--command powershell.exe

以下のように、コンテナ内で動作している PowerShell セッションにアタッチして、新しいディレクトリを作成します。

Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\> Get-ChildItem


 Directory: C:\

Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 10/8/2021 10:53 PM Program Files
d----- 9/13/2021 4:08 AM Program Files (x86)
d-r--- 9/13/2021 4:11 AM Users
d----- 10/8/2021 10:57 PM Windows
-a---- 5/7/2020 4:48 AM 5510 License.txt



PS C:\> New-Item -Path . -Name "demo" -ItemType "directory"


 Directory: C:\


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/8/2021 11:19 PM demo


PS C:\> Get-ChildItem


 Directory: C:\


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/8/2021 11:19 PM demo
d-r--- 10/8/2021 10:53 PM Program Files
d----- 9/13/2021 4:08 AM Program Files (x86)
d-r--- 9/13/2021 4:11 AM Users
d----- 10/8/2021 10:57 PM Windows
-a---- 5/7/2020 4:48 AM 5510 License.txt

Amazon ECS Exec でスタンドアロンコマンドを実行する

インタラクティブセッションの他に、コンテナ内でスタンドアロンコマンドを実行することも可能です。

aws ecs execute-command   \
--region <AWS_REGION> \
--cluster <CLUSTER_NAME> \
--task <TASK_ID> \
--container windows_container \
--interactive \
--command Get-ChildItem

これによって、次のような応答が得られます。

Starting session with SessionId: ecs-execute-command-0236343166de7c108

 Directory: C:\


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/8/2021 11:19 PM demo
d-r--- 10/8/2021 10:53 PM Program Files
d----- 9/13/2021 4:08 AM Program Files (x86)
d-r--- 9/13/2021 4:11 AM Users
d----- 10/8/2021 10:57 PM Windows
-a---- 5/7/2020 4:48 AM 5510 License.txt

Exiting session with sessionId:   ecs-execute-command-0236343166de7c108.

Amazon S3 および CloudWatch Logs

上記の「インフラストラクチャの設定」で作成した CloudWatch のロググループを確認すると、Amazon ECS Exec のセッションに対して生成されたログストリームを確認することができます。次のスクリーンショットは、先ほど実行したスタンドアロンコマンドの結果です。

Snapshot of the result of the standalone command

同様に、Amazon S3 バケット内のログも確認することができます。

Exec output logs in the S3 bucket

インフラストラクチャのクリーンアップ

最後に、デモのために作成したインフラストラクチャを削除しましょう。そうしないと、将来的にコストが発生する可能性があります。もし、作成したリソースの中に使っていないものがあれば、削除することをお勧めします。このクリーンアップには、デモの一部として作成された以下のリソースが含まれます。

  • 起動したタスクの停止
  • 起動した EC2 インスタンスの終了
  • Amazon ECS クラスタの削除
  • CloudWatch のロググループの削除
  • S3 バケットの削除
  • タスク IAM ロールの削除
  • タスク実行 IAM ロールの削除
  • AWS KMS キーの削除

リソースの削除の詳細については、こちらで公開されているドキュメントをご覧ください。

まとめ

今回の記事では、Amazon EC2 および AWS Fargate 上で動作する Windows コンテナのための Amazon ECS Exec 機能について説明しました。Amazon ECS Exec の機能に必要なセットアップを行い、Amazon ECS Exec を有効にしてタスクを実行しました。対話型セッションとスタンドアロンモードで、Amazon ECS Exec の機能を検証しました。

Amazon EC2、AWS Fargate、または Amazon ECS Anywhere 上の Windows タスクのための Amazon ECS Exec を開始するには、Amazon ECS デベロッパーガイドをご覧ください。

翻訳はソリューションアーキテクト 杉本 晋吾 が担当しました。原文はこちらです。