· 17 分で読める · 8,627 文字
KubernetesとServerlessのコスト比較:実務で判断すべき5つの指標
Kubernetes と Serverless(AWS Lambda など)のコスト構造は根本的に異なります。本記事では、実際のプロジェクトでどちらを選ぶべきか判断できる5つの指標と、各プラットフォームの隠れたコスト要因を解説します。
Kubernetes vs Serverless コスト構造の根本的な違い
実務では、単純に「月額料金が安い」だけでは判断できません。Kubernetes と Serverless は課金モデルが全く異なるため、ワークロードの特性によってコストが大きく変わります。
Kubernetes(オーケストレーション型)は、ノード(VM)の時間単価で課金されます。CPU やメモリの使用率が 10% でも 100% でも、ノードがある限り料金は変わりません。一方、Serverlessは実際の実行時間とメモリ使用量に基づいて従量課金されるため、アイドル時間に費用が発生しません。
graph TD
A[アプリケーションのワークロード特性を分析] --> B{継続的に稼働?}
B -->|はい| C[Kubernetes推奨
固定コスト最小化]
B -->|いいえ| D{急激な
スパイク?}
D -->|あり| E[Serverless推奨
スケール性重視]
D -->|なし| F[小規模で
バースト?]
F -->|はい| G[Serverless推奨
従量課金]
F -->|いいえ| C
コスト指標1:計算リソース(コンピュート)の実効コスト
実務でよくあるケースを計算してみます。以下のシナリオを想定してください。
Kubernetes での計算コスト
GKE(Google Kubernetes Engine)で 3 ノード の e2-medium インスタンス(0.5 CPU、2 GB メモリ)を 24 時間稼働させる場合:
# GKE ノード構成例
- e2-medium インスタンス × 3 ノード
- 月額料金(東京リージョン):約 $15 / ノード
- 固定月額:$45(ノード料金)
- 加えて、GKE クラスタ管理料:$0.10 / クラスタ / 時間(月額 $73.80)
合計月額:約 $118.80
CPU 使用率が 20% でも 80% でも料金は同じ
Serverless での計算コスト
AWS Lambda で同等のワークロード(平均 0.5 GB、実行時間 100 時間 / 月)を実行する場合:
# AWS Lambda 料金計算
- メモリ割り当て:512 MB(0.5 GB)
- 実行時間:100 時間 / 月
- 月額料金:
- リクエスト料:0.2 百万リクエスト × $0.2 / 百万 = $0.04
- 実行時間料:100 時間 × 3,600 秒 × $0.0000166667 / GB-秒
= 360,000 GB-秒 × $0.0000166667 = $6.00
- 合計:約 $6.04
CPU 使用率が 20% なら実際は月額 $50 程度で足りる可能性がある
結論:CPU 使用率が 30% 以下の間欠的なワークロードなら、Serverless が明らかに安いです。一方、常時 70% 以上の負荷なら Kubernetes が有利になります。
コスト指標2:ストレージと周辺サービス
コンピュート料金だけで判断すると失敗します。実務では、ストレージ、ネットワーク、ロードバランサ、ログ管理など周辺コストが 30〜50% を占めることもあります。
Kubernetes 環境でのストレージコスト
# GKE での周辺サービス費用例
- Persistent Volume(SSD):100 GB × $0.17 / GB / 月 = $17
- Google Cloud Load Balancer:$18 / 月
- Cloud Logging(ログ保存):100 GB ログ × $0.50 / GB = $50
- Cloud Monitoring(メトリクス):基本無料(一部有料)
周辺費用月額:約 $85
クラスタ運用で発生する追加支出も考慮が必要
Serverless 環境でのストレージコスト
# AWS Lambda での周辺サービス費用例
- S3 ストレージ:100 GB × $0.025 / GB = $2.50
- API Gateway:100 万リクエスト × $3.5 / 百万 = $0.35
- CloudWatch Logs:100 GB ログ × $0.50 / GB = $50
- DynamoDB(if 使用):オンデマンド課金(変動)
周辺費用月額:約 $53
スケーリングに伴う追加コストが予測困難
筆者の実務経験上、Kubernetes では「ストレージは予測可能」ですが、Serverless では「ログやデータ転送が予期せず増加する」ケースが多いです。
コスト指標3:運用・保守コストの隠れた負担
この項目は、費用見積もりで最も見落とされやすいものです。
Kubernetes の運用コスト
Kubernetes は自分たちで運用する場合、以下の負担が発生します:
- 人件費:SRE/DevOps エンジニア 1 名以上の専任(年間 $80K 〜)
- セキュリティパッチ:定期的なアップデート、テスト、ダウンタイム対応
- トラブルシューティング:ノード障害、ネットワーク問題の復旧
- キャパシティプランニング:将来の増加に備えたノード拡張
マネージドサービス(GKE、EKS)を使えば若干軽減されますが、完全にオフロードはできません。
Serverless の運用コスト
- 人件費:最小限(主にアプリケーション開発に集中)
- 自動スケーリング:インフラ側で完全自動化
- セキュリティ更新:プロバイダー側で自動適用
- デバッグ:CloudWatch や X-Ray で可視化(学習曲線あり)
ただし、コールドスタート遅延やベンダーロックインのリスクは存在します。
sequenceDiagram
participant User as ユーザーリクエスト
participant LB as Load Balancer
participant K8s as Kubernetes Pod
participant Db as Database
User->>LB: HTTP リクエスト
LB->>K8s: リクエスト転送
即座に処理開始
K8s->>Db: クエリ実行
Db-->>K8s: 結果返却
K8s-->>LB: レスポンス(~10ms)
LB-->>User: レスポンス返却
Note over K8s: コールドスタートなし
常時稼働
コスト指標4:スケーリングシナリオ別の総コスト比較
実際のケーススタディで、スケーリングがコストに与える影響を検証してみます。
ケース1:トラフィックが 2 倍に急増した場合
Kubernetes の対応
# kubectl で HPA(Horizontal Pod Autoscaler)を設定
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
# 注記:ノード数も自動スケーリング必要
# Cluster Autoscaler で対応
トラフィック 2 倍 → Pod が自動増加 → ノード追加(5 ノードまで拡張)
増加コスト:
- ノード 2 → 5(+3 ノード)× $15 = +$45 / 月
- 実際には新ノード起動に 2〜5 分要する(この間レイテンシ増加の可能性)
- 合計月額:$118.80 → $163.80(+37%)
Serverless の対応
# Lambda は自動スケーリング(設定不要)
# ただしコンカーレンシー制限に注意
import json
import boto3
lambda_client = boto3.client('lambda')
def lambda_handler(event, context):
# 関数は自動的に並行実行
# AWS が必要に応じて新しいコンテナを起動
return {
'statusCode': 200,
'body': json.dumps('リクエスト処理完了')
}
# 予約コンカーレンシーを設定したい場合:
# AWS Lambda コンソールで「予約コンカーレンシー」を設定
# 例:1000 リクエスト / 秒を想定 → 予約コンカーレンシー:1000
トラフィック 2 倍 → 自動スケーリング(即座に対応)→ 追加課金のみ
増加コスト:
- 実行時間が 100 時間 → 200 時間(倍増)
- 追加料金:100 時間分の実行コスト
- 合計月額:$6.04 → $12.08(+100%)
- ただし即座にスケール(遅延なし)
考察:Kubernetes は事前にノード数を調整する「計画的スケーリング」、Serverless は「即座の自動スケーリング」です。予測可能なトラフィック増なら Kubernetes、予測不可能なスパイクなら Serverless が有利です。
コスト指標5:長期運用での総保有コスト(TCO)の試算
3 年間の長期運用を想定し、総保有コストを比較してみます。
Kubernetes の 3 年間 TCO
=== Kubernetes(GKE)での 3 年総コスト ===
固定コスト:
- ノード料金:$118.80 × 36 ヶ月 = $4,276.80
- GKE クラスタ管理料:$73.80 × 36 ヶ月 = $2,656.80
変動コスト(周辺サービス):
- ストレージ・ロードバランサ等:$85 × 36 = $3,060
運用コスト:
- SRE エンジニア(専任 0.5 名相当):$40K × 3 年 = $120,000
- パッチ適用・トラブルシューティング(外部委託想定):$5,000 / 年 × 3 = $15,000
トラフィック増加対応(年 30% 成長想定):
- 1 年目:+$0(ユーティライゼーション向上で吸収)
- 2 年目:+$40(ノード追加)×12 = +$480
- 3 年目:+$80(さらに追加)×12 = +$960
3 年間総額:$4,276.80 + $2,656.80 + $3,060 + $120,000 + $15,000 + $1,440
= 約 $146,434
Serverless の 3 年間 TCO
=== AWS Lambda での 3 年総コスト ===
固定コスト(ほぼなし):
- API Gateway:$0.35 × 36 = $12.60
- CloudWatch Logs:$50 × 36 = $1,800
従量コスト(トラフィック連動):
- Lambda 実行:$6 × 36 = $216
- トラフィック成長対応(年 30% 増):
- 1 年目:$6
- 2 年目:$6 × 1.3 = $7.80
- 3 年目:$6 × 1.3^2 = $10.14
- 3 年小計:約 $24
その他サービス(S3、DynamoDB):$2.50 × 36 = $90
運用コスト:
- アプリケーション開発者対応(Kubernetes より 30% 削減):$20K × 3 = $60,000
- デバッグツール・ログ分析(学習曲線):$3,000 / 年 × 3 = $9,000
3 年間総額:$12.60 + $1,800 + $240 + $90 + $60,000 + $9,000
= 約 $71,142.60
結論:3 年間の総保有コストでは、Serverless が約 52% 安い($71K vs $146K)という試算結果が出ました。ただし、前提条件(トラフィック成長率、人件費)で結果が大きく変わります。
ハマりポイント:隠れたコスト要因
Kubernetes で気をつけるべき追加費用
- Egress トラフィック:クラスタ外へのデータ転送が高い($0.12/GB など)
- Reserved Instances の見逃し:1 年コミットで 30% 割引が可能なのに未利用
- GPU ノード:機械学習用に GPU が必要な場合、急激にコスト増加
- ディザスタリカバリ:バックアップストレージが別途費用
Serverless で気をつけるべき追加費用
- コールドスタート遅延:初回実行時 5〜10 秒かかる可能性(ユーザー体験低下)
- Duration の計上:初期化時間や待機時間も課金対象
- ベンダーロックイン:Lambda から別プロバイダへの移行が困難
- Provisioned Concurrency:コールドスタート回避のため予約が必要(追加料金)
実務では、Serverless のコールドスタートが問題となる場合、Provisioned Concurrency で回避できますが、その場合コスト優位性が失われることを認識しておく必要があります。
# Provisioned Concurrency の設定例(AWS Lambda コンソール)
# または CLI で:
aws lambda put-provisioned-concurrency-config \
--function-name my-function \
--provisioned-concurrent-executions 100 \
--qualifier LIVE
# 注記:
# - 100 並行実行の予約に月額 $34.50 程度の追加費用
# - これを有効にすれば、コールドスタートはほぼ発生しない
判断フレームワーク:どちらを選ぶべきか
以下の質問に答えることで、適切な選択肢が見えてきます。
Kubernetes を選ぶべき場合
- ✅ トラフィックが 24 時間ほぼ安定(70% 以上の時間で高負荷)
- ✅ マイクロサービスが 10 個以上で、複雑なオーケストレーションが必要
- ✅ レイテンシが critical(コールドスタート許容不可)
- ✅ 既に DevOps チームが Kubernetes スキルを保有
- ✅ オンプレミスと cloud のハイブリッド環境が必要
- ✅ 長期的に大規模なアプリケーション基盤を構築
Serverless を選ぶべき場合
- ✅ トラフィックが不規則でスパイク性(1 日の中で 10 倍変動など)
- ✅ スタートアップで DevOps リソースが限定的
- ✅ 急速なスケーリングが求められる
- ✅ イベント駆動型のワークロード(API、バッチ処理)
- ✅ 既存のマネージドサービス(DynamoDB、S3)を多用
- ✅ 月単位での利用期間が短い場合もある
よくある質問
はい、可能で、実務では推奨されます。例えば、AWS EKS 上で実行する Pod の一部を AWS Lambda に置き換えるといった運用が実際に行われています。
できます。特に Kubernetes では有効です。
大きく変わります。ベンダー間のコスト差異があるため、戦略的に選択する必要があります。
ワークロード特性により異なりますが、目安は以下の通りです。
実装例:コスト監視スクリプト
実務では、各選択肢を試してから最終判断することを推奨します。以下は、実際のコスト監視スクリプトです。
AWS Lambda のコスト監視(Python)
import boto3
import json
from datetime import datetime, timedelta
# CloudWatch Logs Insights で Lambda 実行コストを集計
logs_client = boto3.client('logs')
cloudwatch_client = boto3.client('cloudwatch')
def estimate_lambda_cost():
"""
直近 7 日間の Lambda 実行時間とメモリから
推定月額コストを計算
"""
# CloudWatch Logs Insights クエリ
query = """
fields @duration, @memoryUsed, @maxMemoryUsed
| stats sum(@duration) as total_duration,
max(@maxMemoryUsed) as max_memory by @log
"""
log_group = '/aws/lambda/my-function'
start_time = int((datetime.now() - timedelta(days=7)).timestamp())
end_time = int(datetime.now().timestamp())
response = logs_client.start_query(
logGroupName=log_group,
startTime=start_time,
endTime=end_time,
queryString=query
)
query_id = response['queryId']
# クエリ実行完了待機
while True:
result = logs_client.get_query_results(queryId=query_id)
if result['status'] == 'Complete':
break
elif result['status'] == 'Failed':
print("Query failed")
return
# 結果解析
total_duration_ms = 0
max_memory_mb = 0
for record in result['results']:
for field in record:
if field['field'] == 'total_duration':
total_duration_ms = float(field['value'])
elif field['field'] == 'max_memory':
max_memory_mb = float(field['value'])
# AWS Lambda 料金計算
# $0.0000166667 / GB-秒
memory_gb = max_memory_mb / 1024
duration_seconds = total_duration_ms / 1000
daily_cost = (duration_seconds * memory_gb) * 0.0000166667
monthly_cost = daily_cost * 30
print(f"=== AWS Lambda Cost Estimation ===")
print(f"Memory Used: {max_memory_mb} MB")
print(f"Total Duration (7 days): {duration_seconds} seconds")
print(f"Estimated Monthly Cost: ${monthly_cost:.2f}")
return monthly_cost
if __name__ == '__main__':
estimate_lambda_cost()
GKE のコスト監視(gcloud CLI)
#!/bin/bash
# GKE クラスタのリソース使用状況からコスト推定
CLUSTER_NAME="my-cluster"
ZONE="asia-northeast1-a"
PROJECT_ID="my-project"
# ノード情報取得
echo "=== GKE Cluster Resource Usage ==="
gcloud container clusters describe $CLUSTER_NAME \
--zone $ZONE \
--project $PROJECT_ID
# ノード数確認
NODE_COUNT=$(gcloud container clusters describe $CLUSTER_NAME \
--zone $ZONE \
--project $PROJECT_ID \
--format='value(nodePool[0].initialNodeCount)')
echo "Active Nodes: $NODE_COUNT"
# Pod リソース使用状況
echo "=== Pod CPU/Memory Usage ==="
kubectl top nodes
kubectl top pods --all-namespaces
# 使用率計算(ノード 3 個、e2-medium)
# 月額 = $15 × 3 + $73.80(クラスタ管理料)
echo ""
echo "=== Estimated Monthly Cost (GKE) ==="
NODE_COST=$(echo "$NODE_COUNT * 15 + 73.80" | bc)
echo "Estimated Cost: \$$NODE_COST / month"
実務の判断プロセス
コスト比較だけでなく、以下の要素も加味した判断フローを示します。
flowchart TD
Start["プロジェクト開始"]
Start --> Q1{"ワークロード特性を
分析"}
Q1 -->|24/7 安定稼働| Q2{"複雑なオーケストレーション
が必要?"}
Q1 -->|スパイク型| Q3{"レイテンシ要件
は?"}
Q2 -->|はい| R1["Kubernetes推奨
EKS/GKE検討"]
Q2 -->|いいえ| Q4{"チーム スキル
レベルは?"}
Q3 -->|< 100ms| R2["Kubernetes推奨"]
Q3 -->|> 1秒許容| Q5{"初期スケーリング
重視?"}
Q4 -->|DevOps 経験豊富| R1
Q4 -->|開発チーム中心| R3["Serverless推奨
Lambda/CloudFunctions"]
Q5 -->|重視| R3
Q5