AWS

プライベートサブネットにECS(Fargate)を作成する

スポンサーリンク
プライベートサブネットにECS(Fargate)を作成する AWS
スポンサーリンク
スポンサーリンク

プライベートサブネットにECS(Fargate)を作成する

以下のページでFargateタイプのECSコンテナを作成する方法をご紹介しました。

今回はプライベートサブネットにFargateを作成する方法を確認します。

構築する環境

Diagram of create ECS(Fargate) in Private Subnet.

ECSクラスターを作成し、FargateタイプのECSタスクをプライベートサブネットに関連付けます。
タスクは以下の2種類のイメージを使用して作成します。

  1. DockerHubで公開されている公式のNginxイメージ
  2. 自作し、ECRにプッシュしたカスタムのNginxイメージ

公式Nginxイメージを取得するために、パブリックサブネットにNATゲートウェイを配置します。

ECRにプッシュしたイメージを取得するために、ECR用およびS3用VPCエンドポイントを作成します。

EC2インスタンスを作成します。
2つのイメージ作成されたコンテナにアクセスするためのクライアントして使用します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

awstut-fa/068 at main · awstut-an-r/awstut-fa
Contribute to awstut-an-r/awstut-fa development by creating an account on GitHub.

テンプレートファイルのポイント解説

ECSおよびFarfagateに関する基本的な事項については、冒頭のページをご確認ください。
本ページでは、プライベートサブネットにFargateを構成するポイントを取り上げます。

イメージを取得するための構成

タスクを作成する上で、Dockerイメージを取得する必要があります。
取得するイメージがDockerHubに公開されているイメージか、ECRにプッシュされたイメージかによって対応が異なります。

プライベートサブネットからDockerHubのイメージを取得する

Resources: IGW: Type: AWS::EC2::InternetGateway IGWAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref IGW EIP: Type: AWS::EC2::EIP Properties: Domain: vpc NATGateway: Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt EIP.AllocationId SubnetId: !Ref PublicSubnet PublicSubnet: Type: AWS::EC2::Subnet Properties: CidrBlock: !Ref CidrIp1 VpcId: !Ref VPC AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone1}" ContainerRouteTable1: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC RouteToInternet: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref IGW RouteToNATGateway: Type: AWS::EC2::Route Properties: RouteTableId: !Ref ContainerRouteTable1 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NATGateway PublicRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet RouteTableId: !Ref PublicRouteTable ContainerRouteTableAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref ContainerSubnet1 RouteTableId: !Ref ContainerRouteTable1
Code language: YAML (yaml)

DockerHubで公開されているイメージを取得するためには、インターネットへの経路を用意する必要があります。
プライベートサブネット内に配置されるECSクラスターからインターネットに接続するために、パブリックサブネットにNATゲートウェイを配置します。

さらにNATゲートウェイ経由でインターネットにアクセスするために、ルートテーブルの設定も行います。
ECSクラスターが配置されるプライベートサブネットに関連づけるルートテーブルには、NATゲートウェイ向けのルートを設定します。
NATゲートウェイが配置されるパブリックサブネットに関連づけるルートテーブルには、インターネットゲートウェイ向けのルートを設定します。

プライベートサブネットからECRにプッシュされたイメージを取得する

Resources: ContainerSubnet2: Type: AWS::EC2::Subnet Properties: CidrBlock: !Ref CidrIp4 VpcId: !Ref VPC AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone3}" ContainerRouteTable2: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC ContainerRouteTableAssociation2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref ContainerSubnet2 RouteTableId: !Ref ContainerRouteTable2 S3Endpoint: Type: AWS::EC2::VPCEndpoint Properties: RouteTableIds: - !Ref ContainerRouteTable2 ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3" VpcId: !Ref VPC ECRDkrEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref EndpointSecurityGroup2 ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.dkr" SubnetIds: - !Ref ContainerSubnet2 VpcEndpointType: Interface VpcId: !Ref VPC ECRApiEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref EndpointSecurityGroup2 ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.api" SubnetIds: - !Ref ContainerSubnet2 VpcEndpointType: Interface VpcId: !Ref VPC
Code language: YAML (yaml)

Fargateにはいくつかプラットフォームバージョンがありますが、デフォルトではLATEST(1.4.0)が選ばれます。
バージョン1.4.0のFartateでは、ECR用のVPCエンドポイントは3種類必要です。

Fargate 起動タイプおよびプラットフォームバージョン 1.4.0 以降を使用する Amazon ECS タスクでは、com.amazonaws.リージョンecr.dkrおよびcom.amazonaws.リージョンecr.apiAmazon ECR VPC エンドポイントおよび Amazon S3 ゲートウェイエンドポイントは、この機能を利用します。

Amazon ECR VPC エンドポイントに関する考慮事項

ECR用のVPCエンドポイントはインターフォース型、S3用のVPCエンドポイントはゲートウェイ型で作成します。

タスクにパブリックアドレスは割り当てない

Parameters: Service1: Type: AWS::ECS::Service Properties: #Cluster: !Ref Cluster1 Cluster: !Ref Cluster LaunchType: FARGATE DesiredCount: 1 TaskDefinition: !Ref TaskDefinition1 ServiceName: !Sub "${Prefix}-service1" NetworkConfiguration: AwsvpcConfiguration: #AssignPublicIp: ENABLED SecurityGroups: - !Ref ContainerSecurityGroup Subnets: - !Ref ContainerSubnet1 Service2: Type: AWS::ECS::Service Properties: #Cluster: !Ref Cluster1 Cluster: !Ref Cluster LaunchType: FARGATE DesiredCount: 1 TaskDefinition: !Ref TaskDefinition2 ServiceName: !Sub "${Prefix}-service2" NetworkConfiguration: AwsvpcConfiguration: #AssignPublicIp: ENABLED SecurityGroups: - !Ref ContainerSecurityGroup Subnets: - !Ref ContainerSubnet2
Code language: YAML (yaml)

AssignPublicIpプロパティで、タスク(コンテナ)にパブリックアドレスを付与するか設定できます。
今回はプライベートサブネット内にタスクが作成されるため、本プロパティは使用しません。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

操作は冒頭のページと同様です。
まずECRリポジトリ用CloudFormationスタックを作成し、その後に残りのスタックを作成します。

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • ECRリポジトリ:[account-id].dkr.ecr.ap-northeast-1.amazonaws.com/fa-068:latest
  • ECSクラスター:fa-068-cluster
  • ECSサービス1:fa-068-service1
  • ECSサービス2:fa-018-service2
  • EC2インスタンス:i-0daf944e613851dd3

作成されたリソースをAWS Management Consoleから確認します。
まずECRを確認します。

Detail of ECR Repository.

正常にECRリポジトリが作成され、イメージがプッシュされていることがわかります。

続いてECSクラスターを確認します。

Detail of ECS Cluster 1.

正常にクラスターが作成され、2つのECSサービスが作成されていることがわかります。

以下が各サービス内に作成されたタスクの詳細です。

Detail of ECS Cluster 2.
Detail of ECS Cluster 3.

それぞれDockerHubおよびECRリポジトリから取得したイメージをベースとして、各コンテナが作成されていることがわかります。

また各タスク(コンテナ)にライベートサブネットが割り当てられている一方、パブリックサブネットは割り当てられていないことがわかります。
以下に割り当てられたプライベートアドレスを整理します。

  • タスク1:10.0.3.83
  • タスク2:10.0.4.91

動作確認

EC2インスタンスにアクセス後、2つのタスクにアクセスします。

インスタンスへのアクセスはSSM Session Managerを使用します。

% aws ssm start-session --target i-0daf944e613851dd3 Starting session with SessionId: root-0f881269c9b4cb613 sh-4.2$
Code language: Bash (bash)

SSM Session Managerの詳細につきましては、以下のページをご確認ください。

タスク1

curlコマンドでタスク1内のコンテナにアクセスします。

sh-4.2$ curl http://10.0.3.83 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
Code language: Bash (bash)

正常にアクセスできました。
公式イメージから生成されたコンテナであることがわかります。

タスク2

続いてタスク2内のコンテナにcurlコマンドでアクセスします。

sh-4.2$ curl http://10.0.4.91 <html> <head> </head> <body> <h1>fa-068 index.html</h1> </body> </html>
Code language: JavaScript (javascript)

こちらも正常にアクセスできました。
カスタムイメージから生成されたコンテナであることがわかります。

まとめ

プライベートサブネットにFargateを作成する方法を確認しました。

タイトルとURLをコピーしました