【AWS】ECSのサービス検出を作ってみました。【CloudFormation】
こんにちは。インフラ統括部のASUHARUです。
AWSに触れ始めて早半年。
CloudFormationで作成したECSのサービス検出を、備忘も兼ねて共有します。
本記事では初めてECSのサービス検出を構築する方を対象にしています。
ECS自体のテンプレートも記載してますので、初めてECSをCloudFormationで作成される方の参考にもなれば幸いです。
ECSのサービス検出(サービスディスカバリ)とは?
ECSの同一クラスター内で各コンテナ間の名前解決を可能にし、フロントエンドとバックエンドでECS サービスを分離するシステムの構成などで使われる機能です。
他コンテナへアクセスするためのDNS名に対応するレコードを、ECSとRoute 53が自動的に登録してくれます。
オートスケーリングでコンテナが増減した場合でも、連動してRoute 53のレコードが自動的に書き換えられます。
同じような機能としてバック側のコンテナの前にELBを配置し、フロント側ではそのELBに対して名前解決を行う方法があります。
一概にサービス検出がELBの代替にはならず、ELBでのパスルーティングや固定レスポンスの機能はサービス検出では設定できません。
ただコンテナ間での通信のみを目的とするのであれば、ECSの機能のみで解決でき設計時の考慮点が減る点からサービス検出の方が使い勝手が良いかなと思います。
作成【CloudFormation】
前提として起動タイプはFargateを採用します。
また、VPCやセキュリティグループ等は、事前に作成しているものを使用しています。
本記事ではCloudFormationのテンプレートのみ記載しておりますので、スタックの作成方法がご不明な方は以下公式リファレンスをご参照ください。
○作成済みのリソース
・VPC
・サブネット
・セキュリティグループ
・タスク用ロール(「test-ecs-role」)
・タスク実行用ロール(「ecsTaskExecutionRole」)
・ECRリポジトリ(「test-ecr」)
AWSTemplateFormatVersion: 2010-09-09
Description: This CloudFormation template to create ECS
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
Parameters:
### VPC ID
VpcId:
Description: Select VPC-ID
Type: AWS::EC2::VPC::Id
### Subnet ID
SubnetIds:
Description: Select two Subnet IDs
Type: List<AWS::EC2::Subnet::Id>
### Source Security Group ID
SourceSecurityGroupId:
Description: Specify the security group ID of the access source.
Type: AWS::EC2::SecurityGroup::Id
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
### FunctionConfigration
- Label:
default: Function Configuration
Parameters:
- VpcId
- SubnetIds
- SourceSecurityGroupId
# ------------------------------------------------------------#
# Resources
# ------------------------------------------------------------#
Resources:
### ECS Cluster ###
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: test-ecs-cluster
ClusterSettings:
- Name: containerInsights
Value: disabled
Tags:
- Key: Name
Value: test-ecs-cluster
### ECS TaskDefinition ###
ECSTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: test-ecs-task
RequiresCompatibilities:
- FARGATE
TaskRoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/test-ecs-role
NetworkMode: awsvpc
RuntimePlatform:
OperatingSystemFamily: LINUX
CpuArchitecture: X86_64
ExecutionRoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole
Cpu: 256
Memory: 512
Tags:
- Key: Name
Value: test-ecs-task
### ECS Container ###
ContainerDefinitions:
- Name: test-ecs-container
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/test-ecr
PortMappings:
- ContainerPort: 80
Protocol: tcp
Essential: true
### ECS Service ###
ECSService:
Type: AWS::ECS::Service
Properties:
LaunchType: FARGATE
TaskDefinition: !Ref ECSTaskDefinition
PlatformVersion: LATEST
Cluster: !Ref ECSCluster
ServiceName: test-ecs-service
SchedulingStrategy: REPLICA
DesiredCount: 0
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
NetworkConfiguration:
AwsvpcConfiguration:
SecurityGroups:
- !Ref SourceSecurityGroupId
Subnets:
- !Select [ 0, !Ref SubnetIds]
- !Select [ 1, !Ref SubnetIds]
AssignPublicIp: ENABLED
ServiceRegistries:
- RegistryArn: !GetAtt ECSServiceDiscovery.Arn
Tags:
- Key: Name
Value: test-ecs-service
### ECS Service Discovery ###
ECSServiceDiscovery:
Type: AWS::ServiceDiscovery::Service
Properties:
HealthCheckCustomConfig:
FailureThreshold: 1
DnsConfig:
DnsRecords:
- Type: A
TTL: 30
NamespaceId: !GetAtt ECSPrivateDnsNamespace.Id
Name: test-ecs-service
ちなみにタスク実行用ロール(「ExecutionRoleArn」)で選択している「ecsTaskExecutionRole」にアタッチされているポリシー「AmazonECSTaskExecutionRolePolicy」(AWS 管理ポリシー)の権限は以下になります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
ECRからDockerイメージを取得する場合やコンテナログをCloudWatchへ出力する場合には「AmazonECSTaskExecutionRolePolicy」に含まれている権限が必要となります。
(本記事で構築するECSではECRを使用するためこちらのポリシーを使用しています)
タスク実行用ロールについての詳細やユースケースは公式のドキュメントをご参照ください。
Amazon ECS タスク実行IAM ロール
以下、上記ECSのテンプレート内のサービス検出に関わる部分について説明します。
「ECSPrivateDnsNamespace」は名前空間の設定です。
NameではVPCに紐づく名前空間名を指定します。
VPCにプライベートな名前空間が作成されます。
### ECS Private DnsNamespace ###
ECSPrivateDnsNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Properties:
Vpc: !Ref VpcId
Name: test-local
次に「ECSServiceDiscovery」の設定です。
ここではECSのサービス検出の設定を行なっています。
サービスの検出名(「Name」)は作成されるDNSレコードのプレフィックスとなる値になります。
「サービスの検出名.名前空間名」となるので、今回の設定では「test-ecs-service.test-local」というDNS名になります。
レコードのタイプについては公式リファレンスに以下のように記載されています。
本記事ではレコードのタイプはAレコードを選択しています。
尚、ServiceDiscovery 関連リソースのテンプレート記載方法の参照先は、公式リファレンスの「Cloud Map」のセクションにあります。
AWS Cloud Map resource type reference
ECSServiceDiscovery:
Type: AWS::ServiceDiscovery::Service
Properties:
HealthCheckCustomConfig:
FailureThreshold: 1
DnsConfig:
DnsRecords:
- Type: A
TTL: 30
NamespaceId: !GetAtt ECSPrivateDnsNamespace.Id
Name: test-ecs-service
挙動確認
作成したテンプレートを基にECSのサービスが構築できたので、挙動を確認していきます。
ECSの「名前空間」にプライベートホストゾーン「test-local」が出来ており、指定したVPCも関連づけられています。
それでは、構築されたホストゾーンにAレコードが作成されるか確認していきます。
ECS サービスのコンソール画面から、「サービスを更新」をクリックします。
更新画面にてデプロイ設定の「必要なタスク」を変更します。
Route 53のホストゾーン「test-local」を確認してみると、Aレコードが一つ作成されています。
試しにタスク数を4つにしてみましょう。
タスク数の増加に連動してAレコードも増加しています。
「必要なタスク」の数を0に変更すると、タスク数の減少に連動しAレコードも削除されました。
ちなみに、Aレコードに割り当てられるIPアドレスについては公式で以下のように記載されています。
まとめ
今回はECSのサービス検出について構築していきました。
便利な機能が多いECS、もっと使いこなしていければと思います。
本記事がECS初学習者の方の参考になれば幸いです。
それでは!
ALHについて知る
↓ ↓ ↓ 採用サイトはこちら ↓ ↓ ↓
↓ ↓ ↓ コーポレートサイトはこちら ↓ ↓ ↓
↓ ↓ ↓ もっとALHについて知りたい? ↓ ↓ ↓