AWS ECS/Fargateのコストを最適化する方法

  1. はじめに
  2. ECS/Fargateの課金体系を理解する
    1. ECSの課金
    2. Fargateの課金詳細
  3. コスト最適化のための10の戦略
    1. 1. タスク定義のリソース設定を最適化する
      1. vCPUとメモリの最適な組み合わせを選択
      2. リソース最適化の手順
    2. 2. Fargateスポットキャパシティプロバイダーを活用する
      1. スポットキャパシティプロバイダーの設定
      2. スポット利用時の注意点
    3. 3. サービスのオートスケーリングを最適化する
      1. ターゲット追跡スケーリングの設定
      2. スケーリングの最適化ポイント
    4. 4. コンテナイメージを最適化する
      1. イメージ最適化のベストプラクティス
    5. 5. タスク配置戦略を最適化する
      1. 効率的なタスク配置戦略
      2. 主なタスク配置戦略
    6. 6. コンピューティングの節約プランを検討する
      1. Fargateに適用可能な節約プラン
      2. 節約プランの検討手順
    7. 7. サービスディスカバリの最適化
      1. コスト効率の良いサービスディスカバリの設定
    8. 8. Application Load Balancerのプロビジョニングを最適化
      1. ALBコスト最適化のポイント
    9. 9. CloudWatchの使用を最適化する
      1. CloudWatchコスト最適化のポイント
    10. 10. 開発環境と本番環境の分離
      1. 環境別の最適化戦略
        1. 開発環境
        2. 本番環境
  4. 実際のケーススタディ
    1. ケース1: Eコマースサイトのコスト最適化
    2. ケース2: マイクロサービスアーキテクチャの最適化
  5. コスト分析と可視化のためのツール
    1. AWS提供のツール
    2. サードパーティツール
  6. まとめ
  7. 参考リソース

はじめに

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 vCPU0.5GB〜2GB
0.5 vCPU1GB〜4GB
1 vCPU2GB〜8GB
2 vCPU4GB〜16GB
4 vCPU8GB〜30GB
8 vCPU16GB〜60GB
16 vCPU32GB〜120GB

リソース最適化の手順

  1. 現在の使用状況を分析: CloudWatchメトリクスを使用してCPUとメモリの使用率を分析
  2. 段階的に調整: 一度に大幅な変更を避け、段階的に調整して影響を観察
  3. 定期的に見直し: トラフィックパターンの変化に応じて定期的に見直す
{
  "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. コンテナイメージを最適化する

コンテナイメージのサイズと起動時間を最適化することで、間接的にコスト削減が可能です。

イメージ最適化のベストプラクティス

  1. マルチステージビルドを使用
# ビルドステージ
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"]
  1. 軽量ベースイメージを選択(Alpine Linuxなど)
  2. レイヤーキャッシュを効果的に活用
  3. 不要なファイルを含めない(.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%の割引
  • 利用コミットメント: 時間あたりのドル支出にコミット

節約プランの検討手順

  1. 過去の使用パターンを分析: AWS Cost Explorerを使用
  2. 推奨事項を確認: AWSが提供する節約プラン推奨事項を確認
  3. 適切なコミットメントレベルを決定: 予測可能な基本負荷に対してのみコミット

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コマースサイトのコスト最適化

課題: ピーク時以外の過剰なリソースプロビジョニング

施策:

  1. CloudWatchメトリクスに基づいたターゲット追跡スケーリングの実装
  2. 夜間と早朝のスケジュールベースのスケーリング導入
  3. バックオフィス処理をFargateスポットに移行

結果: 月間コストを約35%削減

ケース2: マイクロサービスアーキテクチャの最適化

課題: 多数の小規模サービスによるリソースの断片化

施策:

  1. コンテナリソース設定の標準化
  2. サービスの統合によるALB数の削減
  3. EC2起動タイプにbinpackプレイスメント戦略を実装

結果: 月間コストを約40%削減

コスト分析と可視化のためのツール

コストを継続的に最適化するには、適切な分析ツールが必要です:

AWS提供のツール

  • AWS Cost Explorer: 詳細なコスト分析とトレンド把握
  • AWS Budgets: 予算設定とアラート
  • AWS Trusted Advisor: コスト最適化の推奨事項
  • AWS Cost Anomaly Detection: 異常な支出の自動検出

サードパーティツール

  • CloudHealth: 詳細なクラウドコスト管理
  • Kubecost: Kubernetesと統合したコスト分析(EKS用)
  • Cloudability: 詳細なコスト分析とレポート作成

まとめ

ECSとFargateのコスト最適化は、一度限りのアクションではなく継続的なプロセスです。本記事で紹介した10の戦略を実装することで、パフォーマンスを犠牲にすることなくコストを削減できます:

  1. タスク定義のリソース設定を最適化する
  2. Fargateスポットキャパシティプロバイダーを活用する
  3. サービスのオートスケーリングを最適化する
  4. コンテナイメージを最適化する
  5. タスク配置戦略を最適化する
  6. コンピューティングの節約プランを検討する
  7. サービスディスカバリの最適化
  8. Application Load Balancerのプロビジョニングを最適化する
  9. CloudWatchの使用を最適化する
  10. 開発環境と本番環境の分離

これらの戦略を組み合わせることで、ECSとFargateのコストを30〜50%削減することも可能です。

重要なのは、ビジネス要件とパフォーマンス目標を常に念頭に置き、定期的にリソースの使用状況を見直すことです。適切に最適化されたECSとFargateの環境は、コスト効率だけでなく、より優れたスケーラビリティと信頼性ももたらします。

参考リソース

コメント

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