AWS

プライベートサブネット内のFargateコンテナをALBにアタッチ

スポンサーリンク
プライベートサブネット内のFargateコンテナをALBにアタッチする AWS
スポンサーリンク
スポンサーリンク

プライベートサブネット内のFargateコンテナをALBにアタッチするための構成

以下のページで、ALBの3種類のターゲットタイプを確認しました。

具体的には、instance, ip, lambdaです。
今回はFargateをALBにアタッチする方法を確認します。
ポイントはターゲットタイプをipに設定する必要があるという点です。

構築する環境

Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Diagram of attaching Fargate in Private subnet to ELB.

FargateはAuto Scalingの設定を行います。
デフォルトのタスク数は1ですが、CPUの使用率に応じて、最大3つまでスケールアウトするように設定します。

環境構築用のCloudFormationテンプレートファイル

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

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

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

プライベートサブネット内のリソースを、ALBにアタッチする方法については、以下のページをご確認ください。

Fargateの基本については、以下のページをご確認ください。

本ページでは、上記の2ページとは異なる点と、FargateをALBにアタッチする際の、ALBターゲットグループの設定にフォーカスします。

プライベートサブネットからECRにアクセスするためには、3つのVPCエンドポイントが必要

ポイントは、プライベートサブネット内のFargateが、ECRリポジトリにアクセスするための経路としてのVPCエンドポイントを作成する必要があるという点です。

Resources: ECRDkrEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref EndpointSecurityGroup ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.dkr" SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 VpcEndpointType: Interface VpcId: !Ref VPC ECRApiEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref EndpointSecurityGroup ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.api" SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 VpcEndpointType: Interface VpcId: !Ref VPC S3Endpoint: Type: AWS::EC2::VPCEndpoint Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: "*" Action: - s3:* Resource: - !Sub "arn:aws:s3:::prod-${AWS::Region}-starport-layer-bucket/*" RouteTableIds: - !Ref PrivateRouteTable ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3" VpcId: !Ref VPC
Code language: YAML (yaml)

プライベートサブネットのFargateがECRにアクセスするためには、3種類のVPCエンドポイントを作成する必要があります。
ECRに関するエンドポイントが2つ、S3に関するエンドポイントが1つです。

詳細は以下のページをご確認ください。

ALBにFargateをアタッチするためには、TargetGroupのTargetTypeをipにする

ポイントは、TargetGroupです。

Resources: ALBTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: VpcId: !Ref VPC Name: !Sub ${Prefix}-ALBTargetGroup Protocol: HTTP Port: !Ref HTTPPort HealthCheckProtocol: HTTP HealthCheckPath: / HealthCheckPort: traffic-port HealthyThresholdCount: !Ref HealthyThresholdCount UnhealthyThresholdCount: !Ref UnhealthyThresholdCount HealthCheckTimeoutSeconds: !Ref HealthCheckTimeoutSeconds HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds Matcher: HttpCode: !Ref HttpCode TargetType: ip
Code language: YAML (yaml)

TargetTypeプロパティが重要です。
「ip」に設定する必要があります。
本プロパティのデフォルト値は「instance」ですが、この値は、以下の引用の通り、ALBにFargateをアタッチする際の条件を満たしません。

[Target type] (ターゲットタイプ) で、[Instance] (インスタンス) または [IP] を選択します。

重要: サービスのタスク定義で awsvpc ネットワークモード (AWS Fargate 起動タイプで必須) を使用している場合は、ターゲットタイプとして [IP] を選択する必要があります。これは、awsvpc ネットワークモードを使用するタスクが Elastic Network Interface に関連付けられているためです。

Application Load Balancer を作成し、Amazon ECS タスクを自動的に登録する方法を教えてください。

ECSサービスでアタッチするALBを指定する

コンテナ用のサービス、タスクおよびAutoScalingグループを定義します。

本テンプレートのポイントの1つは、ALBにFargateをアタッチする方法に関する設定です。
アタッチはECSサービスリソース側の設定で行います。

Resources: Service: Type: AWS::ECS::Service Properties: Cluster: !Ref Cluster DesiredCount: 1 LaunchType: FARGATE LoadBalancers: - ContainerName: !Sub "${Prefix}-${ServiceName}-container" ContainerPort: !Ref HTTPPort TargetGroupArn: !Ref ALBTargetGroup NetworkConfiguration: AwsvpcConfiguration: SecurityGroups: - !Ref ServiceSecurityGroup Subnets: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 ServiceName: !Sub "${Prefix}-${ServiceName}-service" TaskDefinition: !Ref TaskDefinition
Code language: YAML (yaml)

LoadBalancersプロパティで、本サービスに関連付けるELBを指定します。

ALBおよびFargateのポート番号まとめ

ALBのTargetGroupのPortプロパティ、ECSサービスのContainerPortプロパティに加えて、ECSタスク定義にもポート情報の設定項目があります。

Resources: TaskDefinition: Type: AWS::ECS::TaskDefinition Properties: ContainerDefinitions: - Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${MyRepository}:latest" LogConfiguration: LogDriver: awslogs Options: awslogs-group: !Ref LogGroup awslogs-region: !Ref AWS::Region awslogs-stream-prefix: !Ref Prefix Name: !Sub "${Prefix}-${ServiceName}-container" PortMappings: - ContainerPort: !Ref HTTPPort HostPort: !Ref HTTPPort Cpu: !Ref ServiceCpu ExecutionRoleArn: !Ref FargateTaskExecutionRole Memory: !Ref ServiceMemory NetworkMode: awsvpc RequiresCompatibilities: - FARGATE TaskRoleArn: !Ref TaskRole
Code language: YAML (yaml)

PortMappingsプロパティです。
配下の2つのパラメータがあります。
このように複数のリソースでポート番号に関するパタメータが存在します。
これらの値を統一的に設定しなければ、正常に通信することはできません。
以下に今回登場したパラメータを整理します。

加えて実行するコンテナ内のポート設定も関係してきます。
今回実行するNginxは、デフォルトで80番ポートでリッスンする設定ですので、上記の値を全て80に統一します。

Fargateタスク用のAutoScalingグループ

最後にFargateタスクのスケーリングさせるためのリソースを確認します。
まずスケーリングする対象をターゲットとして定義します。

Resources: ServiceScalableTarget: Type: AWS::ApplicationAutoScaling::ScalableTarget DependsOn: - Service Properties: MaxCapacity: 3 MinCapacity: 1 ResourceId: !Select [5, !Split [":", !Ref Service]] RoleARN: !GetAtt ServiceTaskScalingRole.Arn ScalableDimension: ecs:service:DesiredCount ServiceNamespace: ecs
Code language: YAML (yaml)

FarateタスクのスケーリングはECSサービスに対して設定します。これはECSサービスがタスク数を調整する働きを行なっているためです。ResourceIdプロパティで対象のサービスを指定し、ScalableDimensionプロパティでタスクの希望数を意味する「ecs:service:DesiredCount」を指定します。今回はデフォルトで1つのタスクが動作し、CPUの使用率に応じてスケールアウトさせる予定ですので、MinCapacityプロパティに「1」、MaxCapacityプロパティに「3」を指定します。

次にスケーリングの条件などをまとめたポリシーを定義します。

Resources: ServiceScalingPolicy: Type: AWS::ApplicationAutoScaling::ScalingPolicy DependsOn: - Service - ServiceScalableTarget Properties: PolicyName: ServiceScalingPolicy PolicyType: TargetTrackingScaling ScalingTargetId: !Ref ServiceScalableTarget TargetTrackingScalingPolicyConfiguration: DisableScaleIn: false PredefinedMetricSpecification: PredefinedMetricType: ECSServiceAverageCPUUtilization ScaleInCooldown: 0 ScaleOutCooldown: 0 TargetValue: !Ref ServiceScalingTargetValue
Code language: YAML (yaml)

CPUの使用率を条件としますので、PolicyTypeプロパティにターゲット追跡スケーリングポリシーを意味する「TargetTrackingScaling」を指定します。TargetTrackingScalingPolicyConfigurationプロパティにて、ターゲットや追跡するメトリクスを定義します。ECSサービスのCPU使用率に関するメトリックはAWS側で事前に用意されているため、PredefinedMetricTypeプロパティに「ECSServiceAverageCPUUtilization」を指定することができます。

最後にスケーリングを実行するために必要な権限を、IAMロールとして用意します。

Resources: ServiceTaskScalingRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole
Code language: YAML (yaml)

AWS管理ポリシーには、ECSのスケーリングを実行するため必要な最低限の権限をまとめた「AmazonEC2ContainerServiceAutoscaleRole」が用意されてあります。今回はこちらを使用します。ちなみに本ポリシーでは、以下のアクションが許可されます。

  • ecs:DescribeServices
  • ecs:UpdateService
  • cloudwatch:DescribeAlarms
  • cloudwatch:PutMetricAlarm

サービスの更新や、スケーリングのためのCloudWatchアラームの作成に関するアクションが許可されます。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
今回は2回に分けてCloudFormationスタックを作成します。

ECRリポジトリを作成する

まずECRリポジトリを作成します。詳細は別ページをご確認ください。

残りのCloudFormationスタックを作成する

CloudFormationスタックを作成します。引き続きスタックの作成および各スタックの確認方法については、以下のページをご確認ください。

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

  • ECSクラスター:fa-019-cluster
  • ECSサービス名:fa-018-container1-service
  • ALB名:fa-019-ALB

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

An ECS cluster has been created.

確かにクラスターが作成されていることがわかります。クラスターの詳細を確認します。

One ECS service has been created in the ECS cluster.

クラスター内にサービスが1つ動作していることがわかります。それぞれのサービス上で動作しているタスクの詳細を確認します。

One ECS task has been created for the ECS service.

現時点では、1つのタスクが実行されていることがわかります。次にALBの詳細を確認します。

Public DNS name of ALB.

ALBに設定されたパブリックDNS名がわかりました。今回は「fa-019-ALB-1804817577.ap-northeast-1.elb.amazonaws.com」でした。ALBのTargetGroupも確認します。

The Fargate task is registered in the group whose target type is ip.

1つのタスクがターゲットとして登録されていることがわかります。

検証1:プライベートサブネット内のFargateにALBからアクセスする

準備が整いましたので、実際にブラウザからALBにアクセスします。

Access Fargate containers in private subnet via ALB.

正常に表示されました。プライベートサブネット内のFargateがALBにアタッチされていることが確認できました。CloudWatch Logsにもアクセスログが書き込まれます。

The access log will be written to CloudWatch Logs.

検証2:Fargateをスケールアウトさせる

スケールアウトを確認します。今回の構成では、CPUの使用率の増加がトリガーとなりますので、ページを繰り返しリロードし、ECSサービスの負荷を高めます。しばらく待つと、CPU使用率が閾値(0.01%)を超えてきます。

CPU utilization of ECS service.

するとスケーリングが開始されます。Eventsタブで詳細を確認することができます。

Logging about scaling out ECS tasks in the ECS service.

タスク数が3つにスケールアウトされました。アクティブなタスク数を確認します。

The number of ECS tasks has increased to three.

確かにタスク数が3つに増えています。正常にスケールされました。最後にCloudWatch Logsを確認します。

A CloudWatch Logs log streams is created for each ECS task.

ご覧の通り、タスクごとにログストリームが作成されています。ログはタスクごとに保存されるということです。

まとめ

プライベートサブネット内のFargateをALBにアタッチすることができました。

Fargateのスケールアウトの設定方法や挙動を確認しました。

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