Fargateについて
FargateはAWSのサービスで、Dockerコンテナを実行する基盤の一つです。
以下、Fargateの利点とECSとの違いを説明しています。
https://aws.amazon.com/jp/fargate/
クラスター管理が不要
まず、ECSとの一番の違いはクラスターを事前に用意しなくていいところです。
ECSではEC2インスタンスを用意して、その上でTaskやServiceを設定していました。
FargateではTaskやServiceを作るだけでコンテナを動かすことができます。
https://aws.amazon.com/jp/about-aws/whats-new/2018/08/aws-fargate-now-supports-time-and-event-based-task-scheduling/
AWS Fargate が時間とイベントベースのタスクスケジューリングをサポート
https://aws.amazon.com/jp/fargate/pricing/
AWS Fargate の料金は、コンテナイメージのダウンロード (docker pull) を開始した時点から Amazon ECS タスク* が終了するまでに使用された vCPU およびメモリリソースに基づいて計算され、最も近い秒数に切り上げられます。1 分の最低料金が適用されます。
さらに最近、時間やイベントをトリガーに動かすことができるようになりました。
これを使えば、バッチ実行時のみ課金されるので利用料を節約できます。
例えばECSだと、バッチ利用時にEC2インスタンスを起動し、利用後に停止するという手順が必要でした。
しかし、FargateではEC2インスタンスを管理する必要はなく、Taskが動いている時間だけ課金されます。
気をつける点として、Fargateでは使用するvCPUによって使えるメモリ量が制限されます。
例えば、メモリを大量に使用する処理の場合、最大で30GBのメモリを使うには4vCPUを選択する必要があります。
費用対効果を考えてEC2やECSを使い分ける必要はあると思います。
実装
それでは実装に入って行きます。
今回はCloudFormationのみでFargateを作っていきます。
ポイント
- バッチ名やバッチ実行に必要なコマンド、cronの設定は
Parameters
に記述しています。 - 今回実行する
バッチ(Dockerコンテナ)はCFnで環境を構築後にECRにPush
してください。- Dockerhubから直接取ってくる場合は、
ECR
の部分を削除後ECSTaskDefinition
のimage
を書き換えてください。
- Dockerhubから直接取ってくる場合は、
- Fargateには
vCPUは1024、memoryは2048
を設定しています。- コンテナにはMemoryReservationで1024を設定しています。
- バッチを実行するだけなので
AssignPublicIpはDISABLED
にしています。 -
セキュリティグループは事前に作成
し、SecurityGroupsに設定します。- CFnで作っている場合は、importValueなどを使って設定してください。
-
Privateサブネットも事前に作成
し、Subnetsに設定します。-
AssignPublicIpはDISABLED
なので、サブネットもPrivateなものを使います。
-
-
DesiredCountは0
に設定しています。- 実はここが味噌で、サービスは作るけど普段は動かさないので、0に設定します。
-
TaskCountは1
に設定しています。- サービスは動かしませんが、定期実行用のTaskは動かしたいので、1に設定します。
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'fargate scheduled task for batch execution'
Parameters:
BatchName:
Type: String
Description: A name of batch
Default: 'fargate-batch'
EntryPoint:
Type: String
Description: A command execute at start
Default: '/bin/sh'
ScheduleExpression:
Type: String
Description: Cron settings
Default: 'cron(0 1 * * ? *)'
Resources:
ECR:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Sub "${BatchName}"
CloudwatchLogsGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "${BatchName}/app"
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub "${BatchName}"
TaskRole:
Type: AWS::IAM::Role
Properties:
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
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
Path: /
RoleName: { "Fn::Join" : ["-", [ !Sub "${BatchName}-ecs-task", { "Ref" : "AWS::Region" }]] }
ECSTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Cpu: 1024
Memory: 2048
Family: !Sub "${BatchName}"
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole"
TaskRoleArn: !Ref TaskRole
NetworkMode: awsvpc
ContainerDefinitions:
- Name: !Sub "${BatchName}"
Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${BatchName}"
MemoryReservation: 1024
EntryPoint:
- !Sub "${EntryPoint}"
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Sub "${BatchName}/app"
awslogs-region: !Sub "${AWS::Region}"
awslogs-stream-prefix: !Sub "${BatchName}"
ECSService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref BatchName
LaunchType: "FARGATE"
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- <<SecurityGroups>>
Subnets:
- <<Subnets>>
DesiredCount: 0
TaskDefinition: !Ref ECSTaskDefinition
TaskScheduleEvents:
Type: AWS::Events::Rule
Properties:
Name: cron-event
ScheduleExpression: !Ref ScheduleExpression
State: ENABLED
Targets:
- Id: 1
RoleArn: !GetAtt TaskRole.Arn
EcsParameters:
TaskDefinitionArn: !Ref ECSTaskDefinition
TaskCount: 1
Arn: !GetAtt ECSCluster.Arn
所感
Scheduled task
を使ってFargateを動かすとdocker compose run
と同じように、
1回きりの実行(one-off)になり、バッチには最適な実行環境だなと感じました。
EC2インスタンスを使用しないので、手間が省けていいです。
ただし、Fargateに限らずECSもそうなんですが、エラーの確認が大変です。
EC2インスタンスがあれば、sshしてログやリソース使用量を確認できるのですが、Fargateでは難しそうです。
簡単にお安くバッチ環境がほしいという方には最適かなと思います。