- はじめに
- ECS/Fargateの課金体系を理解する
- コスト最適化のための10の戦略
- 実際のケーススタディ
- コスト分析と可視化のためのツール
- まとめ
- 参考リソース
はじめに
AWS ECS(Elastic Container Service)とFargateは、コンテナ化されたアプリケーションを実行するための強力なサービスです。特にFargateはサーバーレスのコンテナ実行環境として、インフラストラクチャの管理負担を大幅に軽減しますが、適切に設定しないとコストが予想以上に膨らむことがあります。
本記事では、ECSとFargateを利用する際のコスト最適化戦略について詳しく解説します。これらの手法を適用することで、パフォーマンスを維持しながらAWSの請求額を削減することが可能になります。
ECS/Fargateの課金体系を理解する
まずはECSとFargateの課金モデルを正確に把握することが重要です。
ECSの課金
- EC2起動タイプ: 基盤となるEC2インスタンスに対して課金され、ECSサービス自体は無料
- Fargate起動タイプ: プロビジョニングされたvCPUとメモリに基づいて課金
Fargateの課金詳細
- vCPU時間: プロビジョニングしたvCPU数 × 実行時間
- メモリGiB時間: プロビジョニングしたメモリ量 × 実行時間
- 最小課金単位: 1分間(2023年7月以降)
- 追加コスト: データ転送料金、EBSボリューム(使用時)、ALB/NLB(使用時)
コスト最適化のための10の戦略
1. タスク定義のリソース設定を最適化する
Fargateのコストは割り当てるリソース量に直接関係します。必要以上のリソースを割り当てないことが重要です。
vCPUとメモリの最適な組み合わせを選択
Fargateでは、特定のvCPUに対して選択できるメモリ量が決まっています:
vCPU | メモリ範囲 |
---|---|
0.25 vCPU | 0.5GB〜2GB |
0.5 vCPU | 1GB〜4GB |
1 vCPU | 2GB〜8GB |
2 vCPU | 4GB〜16GB |
4 vCPU | 8GB〜30GB |
8 vCPU | 16GB〜60GB |
16 vCPU | 32GB〜120GB |
リソース最適化の手順
- 現在の使用状況を分析: CloudWatchメトリクスを使用してCPUとメモリの使用率を分析
- 段階的に調整: 一度に大幅な変更を避け、段階的に調整して影響を観察
- 定期的に見直し: トラフィックパターンの変化に応じて定期的に見直す
{
"containerDefinitions": [
{
"name": "app",
"image": "app:latest",
"cpu": 256, // 0.25 vCPU
"memory": 512, // 0.5 GB
"essential": true
}
],
"family": "optimized-task",
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "256",
"memory": "512"
}
2. Fargateスポットキャパシティプロバイダーを活用する
スポットキャパシティプロバイダーを使用すると、通常のFargate料金と比較して最大70%のコスト削減が可能です。
スポットキャパシティプロバイダーの設定
# キャパシティプロバイダー戦略を設定したサービスの作成
aws ecs create-service \
--cluster my-cluster \
--service-name my-service \
--task-definition my-task-def \
--capacity-provider-strategy capacityProvider=FARGATE_SPOT,weight=1 \
--network-configuration "awsvpcConfiguration={subnets=[subnet-12345],securityGroups=[sg-12345]}" \
--desired-count 2
スポット利用時の注意点
- 中断に強いアプリケーション設計: スポットキャパシティは中断される可能性があるため、ステートレスアプリケーションに適している
- キャパシティプロバイダーのミックス: 重要なワークロードに対しては、通常のFargateとスポットを組み合わせる
- 再試行メカニズムの実装: タスクが中断された場合の再試行ロジックを実装する
3. サービスのオートスケーリングを最適化する
需要に応じて自動的にタスク数を調整することで、無駄なリソース使用を防ぎます。
ターゲット追跡スケーリングの設定
# Application Auto Scalingのターゲットを登録
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/my-cluster/my-service \
--min-capacity 1 \
--max-capacity 10
# ターゲット追跡スケーリングポリシーを設定
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/my-cluster/my-service \
--policy-name cpu70-target-tracking-scaling-policy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 70.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ECSServiceAverageCPUUtilization"
},
"ScaleOutCooldown": 60,
"ScaleInCooldown": 300
}'
スケーリングの最適化ポイント
- 適切なターゲット値の設定: CPU/メモリ使用率のターゲットを70-80%に設定
- クールダウン期間の調整: スケールアウト(60秒)とスケールイン(300秒)で異なる値を設定
- カスタムメトリクスの活用: アプリケーション固有のメトリクスに基づいたスケーリングを検討
4. コンテナイメージを最適化する
コンテナイメージのサイズと起動時間を最適化することで、間接的にコスト削減が可能です。
イメージ最適化のベストプラクティス
- マルチステージビルドを使用
# ビルドステージ
FROM node:14 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 実行ステージ
FROM node:14-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
RUN npm install --only=production
EXPOSE 3000
CMD ["npm", "start"]
- 軽量ベースイメージを選択(Alpine Linuxなど)
- レイヤーキャッシュを効果的に活用
- 不要なファイルを含めない(.dockerignoreの活用)
5. タスク配置戦略を最適化する
EC2起動タイプを使用する場合、タスク配置戦略を最適化することで、EC2インスタンスの使用効率を高めることができます。
効率的なタスク配置戦略
{
"placementStrategy": [
{
"type": "binpack",
"field": "memory"
}
]
}
主なタスク配置戦略
- binpack: リソースの使用率を最大化(コスト最適化向け)
- spread: 可用性を最大化(パフォーマンス向け)
- random: タスクをランダムに配置
6. コンピューティングの節約プランを検討する
頻繁に使用するリソースには、AWSのSavings Plans(節約プラン)を利用してコストを削減できます。
Fargateに適用可能な節約プラン
- Computeの節約プラン: EC2、Fargate、Lambdaにわたって適用可能
- 一般的な割引率: 1年契約で最大66%、3年契約で最大72%の割引
- 利用コミットメント: 時間あたりのドル支出にコミット
節約プランの検討手順
- 過去の使用パターンを分析: AWS Cost Explorerを使用
- 推奨事項を確認: AWSが提供する節約プラン推奨事項を確認
- 適切なコミットメントレベルを決定: 予測可能な基本負荷に対してのみコミット
7. サービスディスカバリの最適化
AWS Cloud Mapを使用したサービスディスカバリにも料金が発生します。使用方法を最適化することでコストを削減できます。
コスト効率の良いサービスディスカバリの設定
- TTL(Time To Live)を適切に設定: 頻繁に変更されないサービスには長いTTLを設定
- ヘルスチェックの頻度を調整: 必要最小限のヘルスチェック頻度に設定
- APIクエリの最適化: 不要なDiscoverInstancesおよびUpdateInstanceCustomHealthStatusの呼び出しを削減
{
"serviceRegistries": [
{
"registryArn": "arn:aws:servicediscovery:region:account-id:service/srv-12345",
"containerName": "app",
"containerPort": 3000
}
],
"healthCheckCustomConfig": {
"failureThreshold": 3
}
}
8. Application Load Balancerのプロビジョニングを最適化
ALBは基本時間料金と処理されたデータ量に基づいて課金されます。
ALBコスト最適化のポイント
- 単一ALBの共有: 複数のサービスで1つのALBを共有
- ルールの統合: 類似したパスパターンを1つのルールに統合
- アイドル状態のALBを削除: 使用していないALBを特定して削除
# ALBのルールを一覧表示
aws elbv2 describe-rules --listener-arn arn:aws:elasticloadbalancing:region:account-id:listener/app/my-alb/1234567890/abcdef1234567890
# 複数サービス用のルールを1つのリスナーに追加
aws elbv2 create-rule \
--listener-arn arn:aws:elasticloadbalancing:region:account-id:listener/app/my-alb/1234567890/abcdef1234567890 \
--priority 10 \
--conditions Field=path-pattern,Values='/service1/*','/service2/*' \
--actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:account-id:targetgroup/my-target-group/1234567890abcdef
9. CloudWatchの使用を最適化する
ECSはデフォルトでCloudWatchにメトリクスやログを送信しますが、これには追加コストが発生します。
CloudWatchコスト最適化のポイント
- ログの保持期間を設定: デフォルトは無期限ですが、ビジネス要件に合わせて調整
# ロググループの保持期間を30日に設定
aws logs put-retention-policy \
--log-group-name /ecs/my-task-definition \
--retention-in-days 30
- 詳細度の高いメトリクスは選択的に有効化: カスタムメトリクスは料金が高いため必要なものだけを選択
- フィルタリングされたログの活用: すべてのログではなく、重要なログのみを保存
{
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-service",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs",
"awslogs-multiline-pattern": "^\\[\\d{4}-\\d{2}-\\d{2}" // マルチラインログのパターン
}
}
}
10. 開発環境と本番環境の分離
開発環境と本番環境を明確に分離し、非本番環境ではよりコスト効率の良い設定を使用します。
環境別の最適化戦略
開発環境
- 小さなタスクサイズ: vCPUとメモリを最小限に設定
- Fargateスポットを優先的に使用: 中断の許容度が高い環境に最適
- 自動シャットダウン: 営業時間外は自動的にタスク数をゼロに削減
# 開発環境のサービスを時間外にスケールダウン
aws application-autoscaling put-scheduled-action \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/dev-cluster/dev-service \
--scheduled-action-name night-shutdown \
--schedule "cron(0 20 ? * MON-FRI *)" \
--scalable-target-action MinCapacity=0,MaxCapacity=0
# 翌朝再開
aws application-autoscaling put-scheduled-action \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/dev-cluster/dev-service \
--scheduled-action-name morning-startup \
--schedule "cron(0 8 ? * MON-FRI *)" \
--scalable-target-action MinCapacity=1,MaxCapacity=2
本番環境
- 高可用性を確保: 最低でも2つのタスクを実行
- リソース余裕を持たせる: 予期せぬ負荷に対応するための余裕を確保
- 通常のFargateとスポットを混合: 安定性とコスト削減のバランスを取る
実際のケーススタディ
ケース1: Eコマースサイトのコスト最適化
課題: ピーク時以外の過剰なリソースプロビジョニング
施策:
- CloudWatchメトリクスに基づいたターゲット追跡スケーリングの実装
- 夜間と早朝のスケジュールベースのスケーリング導入
- バックオフィス処理をFargateスポットに移行
結果: 月間コストを約35%削減
ケース2: マイクロサービスアーキテクチャの最適化
課題: 多数の小規模サービスによるリソースの断片化
施策:
- コンテナリソース設定の標準化
- サービスの統合によるALB数の削減
- EC2起動タイプにbinpackプレイスメント戦略を実装
結果: 月間コストを約40%削減
コスト分析と可視化のためのツール
コストを継続的に最適化するには、適切な分析ツールが必要です:
AWS提供のツール
- AWS Cost Explorer: 詳細なコスト分析とトレンド把握
- AWS Budgets: 予算設定とアラート
- AWS Trusted Advisor: コスト最適化の推奨事項
- AWS Cost Anomaly Detection: 異常な支出の自動検出
サードパーティツール
- CloudHealth: 詳細なクラウドコスト管理
- Kubecost: Kubernetesと統合したコスト分析(EKS用)
- Cloudability: 詳細なコスト分析とレポート作成
まとめ
ECSとFargateのコスト最適化は、一度限りのアクションではなく継続的なプロセスです。本記事で紹介した10の戦略を実装することで、パフォーマンスを犠牲にすることなくコストを削減できます:
- タスク定義のリソース設定を最適化する
- Fargateスポットキャパシティプロバイダーを活用する
- サービスのオートスケーリングを最適化する
- コンテナイメージを最適化する
- タスク配置戦略を最適化する
- コンピューティングの節約プランを検討する
- サービスディスカバリの最適化
- Application Load Balancerのプロビジョニングを最適化する
- CloudWatchの使用を最適化する
- 開発環境と本番環境の分離
これらの戦略を組み合わせることで、ECSとFargateのコストを30〜50%削減することも可能です。
重要なのは、ビジネス要件とパフォーマンス目標を常に念頭に置き、定期的にリソースの使用状況を見直すことです。適切に最適化されたECSとFargateの環境は、コスト効率だけでなく、より優れたスケーラビリティと信頼性ももたらします。
コメント