#概要
2021年3月AWS の公式ブログに、「NEW – Amazon ECSExecを使用してAWSFargateとAmazonEC2のコンテナにアクセスする」記事が発表された。これまでSSM(System Manager Session Manager)とコンテナー側のSSM エージェントのインストールの併用によるコンテナーへの
面倒なアクセス手順より、アクセス手順は大分簡略化された。本記事は、この新しいECS Exec機能を利用し、プライベートVPCにおけるFargateのコンテナーへのアクセス方法を紹介と検証する。
以下はこの方法の利点である。
1. ECSのコンテナーにSSMエージェントのインストールは要らない。既存コンテナーにすぐアクセスできる。
2. インターネットゲートウェイやNATなどを設置されていないプライベートVPCに格納されたコンテナーにもアクセスできる。
3. Blue/Green CodeDeploy のECSサービスにも適用。
4. VPCにcom.amazonaws.xxxxxxxx.ssmサービスのエンドポイント設定が必要である。
5. AWS CLI、マネジメントコンソールやCloudFormationやどちらでも作ったECSコンテナーに適用する。
#機能概要と制限
Amazon ECS Execは、AWS Systems Manager(SSM)Session Managerを使用してコンテナとの接続を確立し、AWSIAMポリシーを使用してコマンドを実行するためのアクセス許可を制御する。
AmazonECSエージェントまたはAWSFargateエージェントは、SSMエージェントを指定されたコンテナーに配置する。これによりECS内部と外部を連携する。ただ、以下の制限がある。
- 現時点ECS Execは、Linuxコンテナーでのみサポートする。
- ECS Execは現在、AWSマネジメントコンソールの使用を対応しない。
- ECS Execは現在、アジア太平洋(大阪)地域ではサポートされないようである。
- 既存のタスクに対してはECS Execを有効にすることはできません。 新しいタスクにのみ有効
#事前環境準備
ECRリポジトリ
VPC
Subnet1a
Subnet1c
SecurityGroup
#検証方法
1. AWS CLI とセッションマネージャープラグインを用意する。
対応するAWS CLIバージョン;
AWS CLI v1 1.19.28以降~最新版
AWS CLI v2 2.1.31以降
AWS CLI 用の Session Manager pluginは、以下の手順によりインストールする。
$ curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm" -o "session-manager-plugin.rpm"
インストール:
$ sudo yum install –y session-manager-plugin.rpm
インストール確認:
$ session-manager-plugin
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
2. 以下のssm-task-policyとこのポリシーを含むタスクロールecs-ssm-task-roleを作成する。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
3. ECSのサービスに対し、Amazon ECS ExecをEnableにする。
$ aws ecs update-service
--cluster your-cluster-name
--service your-service-name
--task-definition your-td-family-name:N
--force-new-deployment
--enable-execute-command
Blue/Green Deployされたサービスには“--force-new-deployment”オプションを使えないことをご注意ください。例:
$ aws ecs update-service --service xxx-dev-xxxx-app-service --cluster xxx-dev-xxxx-app-fargate1 --enable-execute-command --force-new-deployment
出力に「”enableExecuteCOmmand”: true」あることをご確認ください。
4. 既存ECSタスクを停止させ、新しい起動されるタスクIdをメモする。
5. 既存ECSタスクを停止させ、新しい起動されるタスクIdをメモする。
6. Fargate のコンテナにアクセスする。
$ aws ecs execute-command --cluster your-cluster-name
--task your-task-id
--container your-container-name
--interactive
--command "/bin/bash"
例:
$ aws ecs execute-command --cluster xxx-dev-xxxx-app-fargate1 --task xxxxxxxxxxxxxxxxxx --container xxx-dev-xxxx-app-container --interactive --command /bin/bash
コンテナーにアクセスされたら、AWS SSM GUIでセッションが接続されたこと確認もできる。
以上でプライベートVPCのFargateにあるコンテナーにログインすることができた。
#補足
- タスクのContainerDefinitionにLinuxParameterのInitProcessEbanbled: true
LinuxParameters:
InitProcessEnabled: true
このパラメータは、コンテナ内でinitプロセスを実行し、ゾンビになる可能性のあるSSMエージェントとその子プロセスをクリアするものである、設定しなくてもコンテナーにアクセスすることができるが、SSMエー人とのゾンビプロセスが生じる可能性がある。
- タスクのContainerDefinitionのReadonlyRootFilesystem: false
ReadonlyRootFilesystem: false
SSMエージェントでは、必要なディレクトリとファイルを作成するために、コンテナファイルシステムに書き込むことができる必要がある。 したがって、readonlyRootFilesystem: falseまたはその他の方法を使用してSSMエージェント用のファイルシステムを書き込む必要である。
ただ、タスク定義する時に、このパラメータを明確に設定していない場合はfalseになる。
“An error occurred (TargetNotConnectedException) when calling the ExecuteCommand operation: The execute command failed due to an internal error. Try again later.”のエラーが出るときに、このパラメータを”true”に設定しているかをご確認ください。
- Private VPCに格納するコンテナーをアクセスする際、ECSサービスを定義する際、VPCのデフォルトPermitAll SecurityGroupをインクルードする必要がある。
例:
SecurityGroups:
VPC default SG, must included. - sg-xxxxxxxxxx
- sg-xxxxxxxxxx
- sg-xxxxxxxxxx
4. VPCのエンドポイントについて
本検証では、com.amazonaws.xxxxxxxx.ssmmessage、com.amazonaws.xxxxxxxx.ec2サービスのエンドポイントが必須、その他の2つサービスのエンドポイントを設定しなくてもアクセスできることを確認された。
com.amazonaws.xxxxxxxx.ssmmessage (must)
com.amazonaws.xxxxxxxx.ec2 (must)
com.amazonaws.xxxxxxxx.ec2messages (optional)
com.amazonaws.xxxxxxxx.ssm (optional)
SSMエンドポイントの詳細は下記ご参照ください。
#完成したECSとタスクのCloudFormation作成
今回の検証に、CloudFormationによる作成されたECSサービス、タスクのテンプレートを添付する。ご参照ください。
AWSTemplateFormatVersion: 2010-09-09
Description: Xxxx - ECS Cluster Set up.
#########################################################################################
# パラメータセクション
#########################################################################################
Parameters:
###################################################################
# 共通パラメータ
###################################################################
# プロジェクト定義
HojokinService:
Type: String
Default: xxxx
# 環境定義
HojokinEnvironment:
Type: String
Default: dev
# リージョン定義
# ap-northeast-1(東京リージョン)
AwsTokyoRegion:
Type: String
Default: xxxxxxxx
# アベイラビリティゾーン(ap-northeast-1a)
TokyoRegionAvailabilityZone1a:
Type: String
Default: xxxxxxxxa
# アベイラビリティゾーン(ap-northeast-1c)
TokyoRegionAvailabilityZone1c:
Type: String
Default: xxxxxxxxc
EcsExecBucketName:
Type: String
Default: xxx-xxxx-dev-hook-s3-xxxxxxxx
#########################################################################################
# リソースセクション
#########################################################################################
Resources:
#################################################
# ECS Cluster作成(画面)
#################################################
XxxDevxxxxAppEcsCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: xxx-dev-xxxx-app-fargate1
#################################################
# ECS LogGroup作成
#################################################
XxxDevAppEcsLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /ecs/logs/xxx-dev-xxxx-app-ecs-group
# IAM Role for TaskExecutionRole definition
XxxDevXxxxEcsTaskExecIamRole:
Type: AWS::IAM::Role
Properties:
RoleName: xxx-dev-xxxx-ecs-taskexec-role
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
#################################################
# ECS TaskDefinition作成
#################################################
XxxDevxxxxAppTask:
Type: AWS::ECS::TaskDefinition
Properties:
Cpu: 4096
# ExecutionRoleArn: !Ref XxxDevxxxxEcsTaskExecIamRole
ExecutionRoleArn: arn:aws:iam::xxxxxxxxxxxx:role/ecsTaskExecutionRole
Family: dev-xxxx-ecs-task
Memory: 8192
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
# コンテナ設定
ContainerDefinitions:
- Name: xxx-dev-xxxx-app-container
Image: xxxxxxxxxxxx.dkr.ecr.xxxxxxxx.amazonaws.com/xxx-dev-xxxx-jdk-ecr:latest
# LinuxParameters:
# InitProcessEnabled: true
LogConfiguration:
LogDriver: awslogs
Options:
# awslogs-group: !ImportValue TestEcsLogGroup
awslogs-group: /ecs/logs/xxx-dev-xxxx-app-ecs-group
awslogs-region: !Ref AwsTokyoRegion
awslogs-stream-prefix: xxxx-unk
# MemoryReservation: 128
PortMappings:
- HostPort: 80
Protocol: tcp
ContainerPort: 80
# ReadonlyRootFilesystem: false
TaskRoleArn: arn:aws:iam::xxxxxxxxxxxx:role/ecs-ssm-task-role
#################################################
# ECS Service作成
#################################################
XxxDevxxxxAppEcsService:
Type: AWS::ECS::Service
Properties:
# Cluster: !ImportValue TestEcsCluster
Cluster: !Ref XxxDevxxxxAppEcsCluster
DeploymentController:
Type: CODE_DEPLOY
# Type: ECS
DesiredCount: 1
LaunchType: FARGATE
LoadBalancers:
-
# TargetGroupArn: arn:aws:elasticloadbalancing:xxxxxxxx2:xxxxxxxxxxxx:targetgroup/xxx-dev-xxxx-nlb-tg/xxxxxxxx
TargetGroupArn: !ImportValue DevxxxxTargetGroupArn
ContainerPort: 80
ContainerName: xxx-dev-xxxx-app-container
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
# - !ImportValue DevxxxxAppSG
# - !ImportValue DevxxxxPermitAllSG
- sg-xxxxxxxx
Subnets:
- !ImportValue DevxxxxAppSubnet1a
- !ImportValue DevxxxxAppSubnet1c
ServiceName: xxx-dev-xxxx-app-service
TaskDefinition: !Ref XxxDevxxxxAppTask
DependsOn:
- XxxDevxxxxAppEcsCluster
- XxxDevxxxxAppTask
Outputs:
ECSAppClster1:
Value: !Ref XxxDevxxxxAppEcsCluster
Export:
Name: DevxxxxEcsAppCluster1
ECSAppTask1:
Value: !Ref XxxDevxxxxAppTask
Export:
Name: DevxxxxEcsAppTask1
ECSAppService1:
Value: !Ref XxxDevxxxxAppEcsService
Export:
Name: DevxxxxEcsAppService1
#所感
今回、ECS Exec機能を使って、簡単且つ迅速にプライベートVPCのECS Fargateに格納されたコンテナーにログインすることができた。実際複雑な商用システムでも、このアクセス方法は充分活用できると思います。