PCDE 合格対策
DEEP DIVE

💰 FinOps とコスト最適化徹底深掘り

Spot VM / CUD / SUD / Recommender / 各ワークロード最適化を、計算式・割引率・事故ケース・実務 BP まで深掘り。FinOps の Inform → Optimize → Operate サイクルで体系化。

公式 docs 準拠 🎯 上級 PCDE §5
🔑 TL;DR — FinOps 6 つの最大コスト源
  1. 観測可能性のオーバー ingestion:log/metrics の exclusion 漏れで月数十万円が一瞬で消える
  2. Cloud Run min-instances を盲目的に >0 設定:cold start を恐れて常時課金
  3. Egress (cross-region/Internet):multi-region サービスで Premium Tier 想定外
  4. Idle resource 放置:unattached PD / static IP / 古い snapshot
  5. CUD の塩漬け:3 年 commitment 後にワークロード消失
  6. GKE Autopilot を「軽量 Pod」で多用:per-Pod 料金で Standard より割高に

1. FinOps の哲学とサイクル

FinOps は FinOps Foundation が提唱する「クラウドのコストを エンジニア・財務・経営 の三位一体で継続最適化する」運営フレームワーク。Inform → Optimize → Operate の 3 フェーズを反復する。

📖 Google 公式:Cost optimization pillar — Google Cloud Architecture Framework
FinOps Lifecycle Cycle ┌─────────────────────┐ │ INFORM │ ← 可視化・分析・配分 │ ShowBack / Tag / │ │ Billing Export → │ │ Looker Studio │ └──────────┬──────────┘ │ insight ▼ ┌─────────────────────┐ │ OPTIMIZE │ ← 改善実装 │ Recommender / │ │ CUD / Spot / RIs │ │ Right-sizing │ └──────────┬──────────┘ │ change ▼ ┌─────────────────────┐ │ OPERATE │ ← 文化・運用 │ ChargeBack / │ │ Budget Alert / │ │ Unit Economics │ └──────────┬──────────┘ │ └────────────► (back to INFORM)

1.1 ShowBack vs ChargeBack

方式説明強み弱み
ShowBack部門別にコストを表示するだけ、実際の支払いは中央集約導入が容易・チーム間摩擦が少ない削減インセンティブが弱い
ChargeBack部門予算から実費請求強い削減インセンティブ・予算規律正確なタグ付け必須・組織内政治
ハイブリッド共通基盤は ShowBack、ワークロードは ChargeBack現実解境界設計が複雑

1.2 Billing Export と Unit Economics

BigQuery Billing Export(Standard / Detailed / Pricing)を設定し、Looker Studio で可視化するのが Google 推奨パス。

-- Detailed Billing Export からチーム別コスト集計
SELECT
  invoice.month,
  labels.value AS team,
  SUM(cost) - SUM(IFNULL((SELECT SUM(amount) FROM UNNEST(credits)), 0)) AS net_cost
FROM `billing_project.billing_export.gcp_billing_export_resource_v1_XXXXXX`
CROSS JOIN UNNEST(labels) AS labels
WHERE labels.key = 'team'
  AND DATE(_PARTITIONTIME) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY 1, 2
ORDER BY 1 DESC, net_cost DESC;

Unit Economics:リクエスト 1 件あたりのコスト、ユーザ MAU あたりのコストを定義し、スケールしたときの収益性を予測。SaaS では必須指標。

1.3 GKE Cost Allocation

GKE クラスタで --enable-cost-allocation を有効化すると、Namespace / Workload 単位の CPU/Memory 使用量を Billing Export に注入してくれる。

gcloud container clusters update CLUSTER_NAME \
  --enable-cost-allocation \
  --location=REGION
📖 公式:View cluster cost allocation data — GKE Docs

1.4 Budget Alert の正しい設計

⚠️ 絶対値だけのアラートは不十分 必ず Threshold rules を複数 + Forecast を併用すること。50%/75%/90%/100% に加え 「予測で月末 100% を超える」 も追加で、実際に超える前に検知。
# Budget の threshold rules 例(gcloud or Terraform)
budget_filter:
  projects: ["projects/PROD_PROJECT"]
amount:
  specified_amount:
    currency_code: JPY
    units: 5000000  # 月 500 万円
threshold_rules:
  - threshold_percent: 0.5
  - threshold_percent: 0.75
  - threshold_percent: 0.9
  - threshold_percent: 1.0
  - threshold_percent: 1.0
    spend_basis: FORECASTED_SPEND  # 予測ベース
⚠️ 事故ケース 1-1:Budget Alert を絶対値しか設定せず月末予測 200% に気づけず Cloud Run の意図せぬ scale-out が月初に発生。50%/75% threshold は静的請求基準のため早期に発火せず、月末に予算 2 倍超過が判明。教訓:spend_basis: FORECASTED_SPEND を 1 つは必ず追加。
⚠️ 事故ケース 1-2:Billing Export を本番 project に格納して削除リスク 決算用 BigQuery dataset を本番 project に作成、project 整理で誤削除し過去 18 ヶ月の billing データ消失。教訓:Billing Export は専用 billing project を作成し、`roles/owner` を絞る。

2. Spot VM 徹底解剖

📖 公式:Spot VMs — Compute Engine Docs

2.1 Spot VM ライフサイクル

Spot VM Lifecycle ┌─────────────┐ │ Provision │ ← gcloud / API / MIG │ (Spot=true)│ provisioningModel=SPOT └──────┬──────┘ │ scheduling.instanceTerminationAction=STOP|DELETE ▼ ┌─────────────┐ │ RUNNING │ ← 通常 VM と同じく動作 │ (最大 91% │ 割引適用、SUD/CUD 不可 │ 割引) │ └──────┬──────┘ │ Compute Engine が capacity 回収を判断 │ (リージョン需給で発生) ▼ ┌─────────────┐ │ PREEMPTION │ ← ACPI G2 Soft Off 通知 │ (30 秒猶予) │ shutdown script 実行可 └──────┬──────┘ ▼ ┌─────────────┐ │ STOPPED │ (action=STOP) → 後で再開可 │ / │ action=DELETE → 完全削除 │ TERMINATED │ MIG なら自動で別 Spot 試行 └─────────────┘

2.2 Spot VM vs Preemptible(廃止予定)

項目Spot VMPreemptible VM(旧仕様、新規非推奨)
最大稼働時間制限なし24 時間で必ず終了
割引率最大 91%(変動)固定 80%
料金更新動的(リージョン需給)固定
preemption 通知30 秒前 ACPI G230 秒前 ACPI G2
Termination actionSTOP or DELETE 選択可常に DELETE
GPU/TPU対応対応
CUD/SUD 適用不可不可

新規ワークロードは Spot 一択。Preemptible はレガシー互換目的で残存。

2.3 30 秒 grace period のハンドリング

#!/bin/bash
# /etc/preempt-shutdown.sh
# Spot preemption 通知を受け取った時の優雅な停止

# 1) アプリに SIGTERM 送出(10 秒以内)
systemctl stop my-worker

# 2) 進行中バッチを cancel API で外部に通知(5 秒以内)
curl -X POST https://api.example.com/cancel \
     -H "Authorization: Bearer $TOKEN" \
     --max-time 5

# 3) ローカル WAL を GCS にアップロード(残り 10 秒)
gsutil -q cp /var/lib/myapp/wal-* gs://drain-bucket/$(hostname)/

# 4) sync して終了
sync

shutdown script は --metadata shutdown-script=... または --metadata-from-file shutdown-script=... で設定。Cloud Logging には自動転送される。

2.4 GKE Spot ノードプール

gcloud container node-pools create spot-workers \
  --cluster=my-cluster \
  --location=asia-northeast1 \
  --spot \
  --enable-autoscaling --min-nodes=0 --max-nodes=100 \
  --machine-type=n2-standard-8 \
  --node-taints=cloud.google.com/gke-spot=true:NoSchedule

Pod 側で toleration と nodeSelector を指定:

spec:
  tolerations:
    - key: cloud.google.com/gke-spot
      operator: Equal
      value: "true"
      effect: NoSchedule
  nodeSelector:
    cloud.google.com/gke-spot: "true"
  terminationGracePeriodSeconds: 25  # 30 秒以内に終了完了

2.5 ハイブリッド node pool 設計

推奨:3 層 node pool ┌─────────────────────┐ │ System Pool │ ← kube-system / DaemonSet │ On-Demand │ (e2-standard-2 × 2-3) │ 100% 安定 │ └─────────────────────┘ ┌─────────────────────┐ │ Workload Pool │ ← stateful, critical │ On-Demand + CUD │ │ 予測可能ワークロード │ └─────────────────────┘ ┌─────────────────────┐ │ Spot Pool │ ← stateless, batch, ML training │ Spot 91% off │ │ 中断許容ワークロード │ └─────────────────────┘
💡 BP:CA (Cluster Autoscaler) の Optimize-utilization profile Spot を有効活用するなら --autoscaling-profile=optimize-utilization に設定。Pod 配置を高密度に詰め、不要 node を素早く削除。デフォルトは balanced(中断耐性重視)。

2.6 Spot で動かしてよい / ダメ

カテゴリ不適
計算特性Stateless / batch / 並列可Stateful / シングルトン / 中断回復難
具体例 ✓ML training, video transcoding, CI/CD runner, web 後段の worker, Spark/Dataflow worker
具体例 ✗DB primary, Redis, queue broker (Kafka leader), gateway/edge LB

2.7 Spot 事故ケース

⚠️ 事故ケース 2-1:本番 DB を Spot で動かして 1 週間でデータロスト Cloud SQL に乗らない Postgres 互換 DB を「コスト削減のため」Spot VM 1 台で稼働。3 日目に preempt + DELETE で PD まで消失。教訓:stateful は Spot 禁止、または最低限 PD 永続 + 別ゾーン standby。
⚠️ 事故ケース 2-2:GKE Spot pool に PDB なしで一斉再起動 Pod Disruption Budget 設定漏れ。Compute Engine 側の Spot 一斉回収で全 Pod が同時 evict、サービス断 4 分。教訓:Spot Pod には必ず PDBminAvailable: 50% 等)。
⚠️ 事故ケース 2-3:terminationGracePeriodSeconds = 60 で grace 切れ強制 KILL Spot は 30 秒しか猶予がない。Pod 側で 60 秒設定しても、それ以前に SIGKILL。教訓:terminationGracePeriodSeconds25-28 秒 に。
⚠️ 事故ケース 2-4:Spot 多用でリージョン全体が capacity 枯渇 asia-northeast1 で大規模ML training を Spot で実行、Compute Engine 側の Spot capacity を圧迫し他社含めた中断頻発。教訓:複数リージョン分散 / multi-zone MIG。
⚠️ 事故ケース 2-5:shutdown script が snapshot 取り損ね 30 秒以内に gsutil で 10GB アップロード不可能。教訓:snapshot は別途定期実行(Compute Engine snapshot schedule)か、PD attached なら data はそのまま残す action=STOP を選択。
⚠️ 事故ケース 2-6:CUD 適用済リソースを Spot にリプレース CUD 1 年が残ったまま GCE → Spot に切り替え、CUD 分はそのまま supply されるが Spot 側にも課金。Spot は CUD/SUD 不可。教訓:CUD 期間中はリプレースしない、または Spot へ移行時は CUD を別ワークロードに attribute。

3. CUD(Committed Use Discounts)完全理解

📖 公式:Committed use discounts — Compute Engine Docs

3.1 CUD の 2 種類

Resource-based CUDSpend-based CUD(Flexible CUD)
対象vCPU / Memory / GPU を 個別に commit金額($/時)を commit、対象サービスを横断適用
柔軟性低(マシンファミリー固定)高(同サービス内で自由)
割引率1y: ~28-37% / 3y: ~46-66%1y: ~28% / 3y: ~46%(やや低い)
対応サービスGCE, GKE node, Cloud SQL, SpannerGCE, Cloud Run, GKE Autopilot, Cloud SQL, Spanner, AlloyDB, Dataflow, Memorystore など多数
変更可否cancel 不可cancel 不可

3.2 割引率の具体値(リージョン・マシンファミリー別)

💰 Resource-based CUD(主要マシンファミリー、us-central1)
マシンファミリー1y vCPU1y RAM3y vCPU3y RAM
N1~37%~37%~57%~57%
N2 / N2D~37%~37%~55%~55%
E2~28%~28%~46%~46%
C2 / C2D~37%~37%~55%~55%
M1 / M2 (mem-optimized)~25%~25%~52%~52%
A2 (GPU)~30-40%~30-40%~50-66%~50-66%
※ 正確な数値はリージョン・時期により変動。公式 pricing ↗ で確認。

3.3 CUD 自動適用の階層

CUD attribution 階層 Project Level CUD │ ▼ プロジェクト内で消費 │ Billing Account Level (default で全 project に shared) │ ▼ Sharing が ON ならビリングアカウント全体に分配 │ Cross-project sharing │ ▼ 余剰 CUD は同 billing account の他 project にも自動適用 ※ Sharing OFF にすると CUD は購入 project でしか使えない

3.4 CUD Recommender

Recommender API は過去 30 日の使用量を分析し、購入推奨 CUD を提示。Console から確認可能。

gcloud recommender recommendations list \
  --project=$PROJECT_ID \
  --location=global \
  --recommender=google.compute.commitment.UsageCommitmentRecommender

3.5 CUD 購入タイミング戦略

💡 BP:段階的 commitment ladder
  1. 0-3 ヶ月:観察期間。Recommender が安定する 30 日以上を待つ
  2. 3-6 ヶ月:1 年 Resource CUD を base load の 50-70% で購入(保守的)
  3. 6-12 ヶ月:使用率が安定したら追加で 80-90% まで Resource CUD
  4. 12 ヶ月以降:3 年 CUD で base の 50% を固定(割引率最大化)
  5. 残り peak は Spend-based CUD(Flexible)+ Spot で吸収

3.6 CUD 事故ケース

⚠️ 事故ケース 3-1:3 年 CUD 後にワークロードクラウド移行で塩漬け Compute Engine N1 に 3 年 CUD 100% 購入直後、別クラウドへの戦略移行が決定。CUD は cancel 不可、3 年間支払い義務。教訓:3 年 CUD は base load の 50-70% まで、Spend-based も組み合わせ。
⚠️ 事故ケース 3-2:Spend-based CUD が意図しないサービスに消費 Compute Engine 用に購入した Flexible CUD が、Cloud Run の予期せぬ scale-out に自動消費され、本来 GCE で得るはずだった割引が発生せず。教訓:Flexible CUD は柔軟だが 消費先を制御できない。Compute 単一なら Resource-based 推奨。
⚠️ 事故ケース 3-3:マシンファミリー変更で CUD 無効化 Resource-based CUD を N1 で購入後、性能改善のため N2 に migration。CUD は N1 専用のため適用されず、N2 のフル料金と N1 CUD の二重支払い。教訓:マシンファミリー変更は CUD purchase 前に固める
⚠️ 事故ケース 3-4:CUD を別 project が「食う」 Sharing 設定で同 billing account 内の他 project の overrun を吸収、本来の購入 project が CUD 消費できなくなった。教訓:CUD の attribution / sharing を Billing で必ず確認、必要なら project sharing OFF。
⚠️ 事故ケース 3-5:Spot に置き換えて CUD 余剰 バッチワークロードを Spot に積極移行、Compute Engine on-demand 使用量が激減し CUD 余剰。Spot は CUD 適用外。教訓:Spot 大量導入の前に CUD 消費影響を試算。

4. SUD(Sustained Use Discounts)詳細

📖 公式:Sustained use discounts — Compute Engine Docs

4.1 SUD の自動適用条件

SUD は 申請不要・自動適用。月間で N1/N2/N2D/E2/C2/M1 の vCPU と RAM を一定割合以上稼働した分について段階的に割引。

月稼働率適用される割引率(on-demand 価格に対し)
0% - 25%0%(フル価格)
25% - 50%20% 割引
50% - 75%40% 割引
75% - 100%60% 割引
月全体平均最大 30% 程度の実効割引(24/7 稼働の場合)

※ N1 と他の 2nd-gen 系で正確な階段の刻みが異なる。最新の数値は公式 docsで確認。

4.2 inferred instance(推論インスタンス)

SUD は個別 VM の稼働時間ではなく、同マシンタイプの合計 vCPU・メモリ時間 を合算した「推論インスタンス」単位で計算する。

💰 計算例:頻繁に作り直しても SUD は損なわれない n2-standard-4 を 1 ヶ月のうち 毎日 8 時間だけ 90 台 起動した場合:
・vCPU 時間 = 4 vCPU × 8h × 30 日 × 90 台 = 86,400 vCPU-h
・1 つの n2-standard-4 が 1 ヶ月フル稼働 = 4 × 730 = 2,920 vCPU-h
・推論インスタンス数 = 86,400 / 2,920 ≈ 29.6 台分
→ これら 29.6 台分が 24/7 稼働したものとして SUD が階段適用される。

4.3 CUD との併用ロジック

月次コスト計算の優先順位 使用量 │ ▼ ① CUD 適用(commit 分を消費) │ │ 残り ▼ ② SUD 階段適用(残り使用量に対して) │ │ 残り ▼ ③ On-demand 価格

CUD と SUD は重複ではなく順次適用。CUD を多く購入していれば SUD の効きどころは限定的。

4.4 SUD 事故ケース

⚠️ 事故ケース 4-1:VM をこまめに stop/start して SUD 取り損ね(誤解) よくある誤解:「VM を切ると SUD カウントが消える」。実際は inferred instance で合算されるため stop/start の影響は小さい。教訓:SUD のために 24/7 稼働は不要、ただしマシンタイプを統一すること(推論インスタンス計算で合算される)。
⚠️ 事故ケース 4-2:E2 と N2 を混ぜて inferred 分散 同ワークロードを E2 と N2 に分散、それぞれで SUD 階段の上位に届かず実効割引率低下。教訓:マシンファミリーを統一

5. Network Tiers と Egress コスト

📖 公式:Network Service Tiers overview

5.1 Premium Tier vs Standard Tier

項目Premium TierStandard Tier
経路Google global backbone(送信元から目的地まで Google ネットワーク内)ISP 経由(出口リージョンの ISP に渡す)
SLA99.99% global IP99.9% regional IP
LBGlobal LB / Premium GLB 利用可Regional LB のみ
Cloud CDN使える使えない
料金高い(特に大陸間 egress)安い(~40-60% 安)
推奨用途グローバル SaaS / 低レイテンシ / 重要本番region 内ユーザ / バッチ転送 / 内部システム

5.2 Egress 料金体系

💰 主要 Egress 料金(asia-northeast1 から、目安)
方向料金/GB(目安)
同ゾーン内無料
同リージョン別ゾーン$0.01
同大陸別リージョン$0.02
大陸間(asia → us)$0.08
インターネット(Premium)$0.12 - $0.23
インターネット(Standard)$0.05 - $0.09
Cloud CDN cache fill$0.01 - $0.04
※ Always Free や Cloud Skills Boost クレジット適用可。公式 pricing ↗ で最新を確認。

5.3 Cross-Cloud Interconnect

AWS / Azure / OCI / Alibaba との専用線接続。Egress は Cross-Cloud Interconnect 料金(公衆インターネット egress より安い)。

5.4 Network Tier 事故ケース

⚠️ 事故ケース 5-1:multi-region デプロイで月 100 万円のリージョン間 egress asia-northeast1 と us-central1 に同期レプリカ、双方向 1Gbps 常時転送 = 月 0.5PB ≈ $10,000 (Premium)。教訓:cross-region 同期は最小化、可能なら Spanner 等のマネージドサービスに任せる。
⚠️ 事故ケース 5-2:Cloud Storage multi-region で予期せぬダウンロード料金 `gs://my-bucket` を us multi-region に作成、asia ユーザが大量ダウンロード。Multi-region は他リージョンへの egress が課金対象。教訓:ユーザロケーションに合わせた region/dual-region を選択。
⚠️ 事故ケース 5-3:default が Premium のままで意図せぬ高額 LB / VM の network tier 指定漏れで Premium 適用、Standard で十分な内部システムに月 30 万円。教訓:Project default network tier を Standard に変更、Premium は必要な所だけ明示。
⚠️ 事故ケース 5-4:Cloud CDN なしで CDN 配信 静的アセットを GCS から直接配信。Cache 効果なく繰り返し egress 課金。教訓:静的コンテンツは Cloud CDN 必須。cache hit rate 90%+ で egress 1/10 に。

6. Recommender / Active Assist

📖 公式:Recommender overview

6.1 Active Assist 全体像

Active Assist Services Map ┌──────────────────────────────────────────────────┐ │ Active Assist (umbrella brand) │ ├──────────────────────────────────────────────────┤ │ Recommender API (改善提案、5 カテゴリ) │ │ Insights API (現状分析データ) │ │ Recommendation Hub (集約 Console) │ │ Policy Analyzer (IAM の who-can-what 分析) │ │ Policy Simulator (IAM 変更影響シミュ) │ │ Unattended Project Recommender │ └──────────────────────────────────────────────────┘

6.2 Recommender 5 カテゴリ詳細

カテゴリ主な Recommender ID提案内容
Cost google.compute.instance.MachineTypeRecommender
google.compute.instance.IdleResourceRecommender
google.compute.disk.IdleResourceRecommender
google.compute.commitment.UsageCommitmentRecommender
google.iam.policy.Recommender
VM rightsizing / Idle VM / Idle PD / CUD 購入 / IAM role 縮小
Security google.compute.firewall.Recommender
google.iam.policy.Recommender
不要な FW rule / 過剰権限 IAM 削減
Performance google.compute.instance.MachineTypeRecommender サチっている VM の machine type up
Manageability Cloud Asset / Deprecated API insight 未使用 project / 廃止予定 API 利用検知
Reliability Reliability Insights / Cloud Asset SPOF / quota 枯渇予測

6.3 Recommender 自動化(GitOps PR 生成パターン)

Recommender → IaC PR 自動化 ┌────────────┐ Pub/Sub topic ┌──────────────┐ │ Recommender│ ─────────────────▶ │ Cloud Run │ │ (cost) │ (daily push) │ Function │ └────────────┘ └──────┬───────┘ │ Terraform mod 修正 ▼ ┌──────────────┐ │ GitHub PR │ ← 人間がレビュー │ "Resize VM" │ └──────┬───────┘ │ merge ▼ ┌──────────────┐ │ Cloud Build │ │ apply │ └──────────────┘
# Recommender 取得例
gcloud recommender recommendations list \
  --project=$PROJECT_ID \
  --location=global \
  --recommender=google.compute.instance.MachineTypeRecommender \
  --format=json

6.4 Recommender 事故ケース

⚠️ 事故ケース 6-1:Idle VM recommender を信じて削除したら本番 Recommender が低 utilization と判定した VM を自動削除。実は深夜バッチ専用 VM(昼間は idle)。教訓:削除系は必ず人間レビュー、tag/label で対象除外。
⚠️ 事故ケース 6-2:Machine type rightsizing で性能劣化 Recommender 推奨に従い 4 vCPU → 2 vCPU に縮小、業務ピーク時に CPU 100% でレイテンシ悪化。教訓:観測期間 30 日以上、ピーク時間帯を必ず含む。
⚠️ 事故ケース 6-3:IAM Recommender でカスタム role 削減して権限不足 過去 90 日未使用と判定された権限を削除、月次バッチで使用していた IAM 権限で job 失敗。教訓:長周期ジョブを観測期間に含める、Policy Simulator で事前検証。

7. ワークロード別コスト最適化

7.1 GKE 最適化

項目StandardAutopilot
料金モデルnode 料金(GCE 価格 + 管理費)Pod 単位(vCPU/Memory request × 時間)
得意な workload大量・密度の高い Pod個数少 / リソース大の Pod
Spot 対応node pool として Spot 構成可Spot Pod として指定可(nodeSelector: cloud.google.com/gke-spot
運用負担node 管理ありnode 隠蔽、ほぼゼロ
💰 計算例:Autopilot vs Standard どっちが安い? ・Pod 5 つ、各 2 vCPU / 4 GiB を 24/7 稼働
・Autopilot: 10 vCPU × $0.0445/h + 20 GiB × $0.0049/h × 730h ≈ 月 $396(Pod request ベース)
・Standard: n2-standard-16(16 vCPU / 64 GiB)× 1 台 × $0.7763/h × 730h ≈ 月 $566(node 単位 + 管理費別)
軽量・少数 Pod なら Autopilot 有利。ただし bin packing で詰められるなら Standard。

Bin Packing 最適化:CA の --autoscaling-profile=optimize-utilization + Pod の reasonable な requests 設定で、node 利用率を 80%+ まで上げる。

7.2 Cloud Run 最適化

設定コスト影響推奨
min-instances0 なら scale to zero(cold start 数百ms-数秒)、>0 なら常時課金SLO 厳しいなら 1-2、それ以外は 0
cpu-always-allocated (旧 CPU always allocated)OFF なら request 処理中だけ CPU 課金、ON なら常時背景処理あり / WebSocket は ON、stateless API は OFF
concurrency1 → 80 で同 instance あたりの処理数が増え単価激減I/O bound なら 80 (max)、CPU bound なら 8-32
CPU boost起動時 CPU を倍にし cold start 短縮(Gen2)cold start 体感する全ケースで ON
memory不要に大きいと毎リクエスト課金Profiler で実測しタイト設定
💰 計算例:concurrency が 10 倍違うと月コストは? 月 1000 万リクエスト、1 req = 200ms、1 vCPU、512MB
・concurrency=1: 1000 万 × 200ms = 2,000,000 vCPU-sec ≈ 556 vCPU-h × $0.024 = $13.3(vCPU 部分のみ)
・concurrency=80: 同時 80 リクエスト処理で実 vCPU 時間 1/80 ≈ $0.17
I/O bound なら concurrency 上げる効果は 10-80 倍

7.3 Compute Engine 最適化

7.4 観測可能性自体のコスト削減

💡 BP:観測コスト最適化の優先順位
  1. Log Exclusion filter:不要な severity=INFO ログを除外(最大削減効果)
  2. Log Sampling:必要だが大量のログを 10% にサンプル
  3. Log Retention 短縮:_Default bucket を 30 日 → 7 日に
  4. Metrics ingestion 制限:高基数ラベル抑制
  5. Trace sampling rate:0.1% に下げる(1% でも大量)

7.5 ワークロード別事故ケース

⚠️ 事故ケース 7-1:Cloud Run min-instances=0 で SLO 違反 cold start に 3 秒、SLO p99 1 秒。月 0.1% のリクエストが cold start に当たり SLO ぎりぎり違反。教訓:SLO 厳しいサービスは min-instances=1 + CPU boost、cold start 完全回避不要なら sampling で対処。
⚠️ 事故ケース 7-2:GKE Autopilot で軽量 Pod が予想外コスト DaemonSet を Autopilot に多数デプロイ、Pod 数 × 単価で Standard の 1.5 倍に。教訓:DaemonSet / 大量 Pod は Standard。
⚠️ 事故ケース 7-3:PD SSD 過剰プロビジョニング DB ワークロードに 10TB SSD(実使用 500GB、IOPS は 1k 程度)。Balanced で十分。月差額 $700。教訓:実 IOPS 測定 → PD タイプ決定。
⚠️ 事故ケース 7-4:log Exclusion 設定漏れで月 50 万円 新規 microservice をデプロイ、DEBUG ログを Production で大量出力。Exclusion filter なし。教訓:サービス追加時の checklist に Exclusion filter 設計を入れる
⚠️ 事故ケース 7-5:Cloud Run concurrency=1 のままで月コスト 80 倍 gRPC stream を扱うため concurrency=1 を維持、I/O bound だが本来 80 で十分。教訓:concurrency 設定は負荷試験で実測

8. 事故ケース総集編 / 即答パターン

8.1 全事故ケース一覧(31 件)

#事故教訓・対処
1-1FinOpsBudget 絶対値のみ、予測 200% に気づけずFORECASTED_SPEND threshold 必須
1-2FinOpsBilling Export を本番 project に格納し削除専用 billing project に分離
2-1Spot本番 DB を Spot で動かしデータロストstateful は Spot 禁止
2-2SpotPDB なしで GKE Spot 一斉再起動PDB minAvailable: 50%+
2-3SpotterminationGracePeriodSeconds 60 で SIGKILL25-28 秒に設定
2-4Spotリージョン Spot capacity 枯渇multi-region/zone 分散
2-5Spotshutdown script で snapshot 取り損ねsnapshot schedule で別途実行
2-6SpotCUD リソースを Spot に置換CUD 期間中はリプレースしない
3-1CUD3 年 CUD 直後に戦略変更で塩漬け3y は base load の 50-70% まで
3-2CUDFlexible CUD が別サービスに消費Compute 単一なら Resource-based
3-3CUDN1→N2 移行で CUD 無効化CUD 購入前にファミリー固定
3-4CUD他 project が CUD を食うsharing 設定確認
3-5CUDSpot 移行で CUD 余剰Spot 導入前に試算
4-1SUDstop/start で SUD 失うと誤解inferred で合算される
4-2SUDマシンファミリー混在で SUD 分散ファミリー統一
5-1Egressmulti-region で月 100 万円 egresscross-region 同期最小化
5-2EgressGCS multi-region で予期せぬ DL 料金region/dual-region に変更
5-3Egressdefault が Premium で意図せぬ高額default を Standard に
5-4EgressCloud CDN なしで配信静的は CDN 必須
6-1RecommenderIdle VM 自動削除で本番削除削除系は人間レビュー
6-2Recommenderrightsizing で性能劣化30 日 + ピーク時間含む
6-3RecommenderIAM Recommender で月次 job 失敗長周期 job を観測対象に
7-1Cloud Runmin-instances=0 で SLO 違反SLO 厳しいなら =1 + CPU boost
7-2GKEAutopilot で DaemonSet コスト大量 Pod は Standard
7-3GCEPD SSD 過剰IOPS 実測 → Balanced 検討
7-4LoggingExclusion なしで月 50 万円新サービスは Exclusion 設計
7-5Cloud Runconcurrency=1 で 80 倍コスト負荷試験で実測

8.2 即答すべき選択肢マトリクス

用途・条件推奨コスト最適化テクニック
夜間バッチ(中断許容)Spot VM + MIG
24/7 安定 base load を 3 年保証可3 年 Resource-based CUD(最大 66% off)
複数サービス横断で柔軟に commit したい1-3 年 Spend-based CUD (Flexible CUD)
VM が CPU 余り気味Recommender (MachineTypeRecommender)
長期保管ログ(読み取り稀)Log Bucket retention 短縮 + GCS Coldline/Archive sink
cold start 許容できる APICloud Run min-instances=0
cold start 不許可 APICloud Run min-instances=1-2 + CPU boost
GKE node pool 利用率向上CA optimize-utilization profile + bin packing
軽量 Pod 数個だけGKE Autopilot or Cloud Run
大量 Pod / DaemonSetGKE Standard
内部システムで region 内のみ通信Network Tier: Standard
グローバル本番Network Tier: Premium + Cloud CDN
multi-region データ転送大量region/dual-region GCS + ユーザ近接配信
BigQuery クエリコストSlot reservations (1y/3y) + partitioning + clustering
未使用リソースの掃除Recommender + Unattended Project Recommender
コスト ChargeBackDetailed Billing Export + label/tag 必須化
突発スパイク予防Budget Alert (FORECASTED_SPEND) + Quota
観測コスト爆発防止Log Exclusion → Sampling → Retention 短縮

8.3 Carbon Footprint と Sustainability

Well-Architected の Sustainability 柱に対応。Cloud Carbon Footprint で project / region / service 別の CO₂ 排出量を可視化。

8.4 最終チェックリスト

💡 FinOps 月次運用チェックリスト(10 項目)
  1. Budget Alert(絶対値 + 予測)が全 production project で動いている
  2. Recommender 推奨を月次でレビュー、PR 化
  3. BigQuery Billing Export → Looker Studio ダッシュボードで部門別可視化
  4. label/tag 必須化(team, env, costcenter)が Org Policy で enforce
  5. CUD の購入率と消化率を四半期レビュー
  6. Idle VM / Unattached PD / 古い snapshot を月次掃除
  7. Log Exclusion filter 漏れがないか新サービス追加時にチェック
  8. Cloud Run concurrency / min-instances 設定が SLO とコストのバランスで最適か
  9. cross-region egress / Premium Tier の利用が必要最小限か
  10. Carbon Footprint レポートを年次でステークホルダーに共有
🎯 試験直前メモ
  • 「最も低コスト」「最も少ない運用負荷」要件 → Recommender / Active Assist / マネージドサービス選択
  • 「中断許容バッチ」→ Spot VM
  • 「3 年安定」→ 3 年 Resource-based CUD(最大 66% off)
  • 「複数サービス横断」→ Flexible CUD(Spend-based)
  • 「観測コスト削減」→ Exclusion → Sampling → Retention 短縮の順
  • 「内部のみ通信」→ Network Tier Standard、Cloud CDN は静的のみ
  • 「Carbon 配慮」→ 低炭素リージョン選定 + Cloud Carbon Footprint レポート

9. GKE 運用深掘り:事故・コスト・肥大化対策

Section 2 / 7 では Spot や Autopilot vs Standard の入口を扱いましたが、本章では「現場で実際に燃えた事故」「請求書がなぜ跳ねたか」「どう抑え込んだか」に絞り、より実務寄りで深掘りします。事故ケースは Section 2.7 / 7.5 との重複を避け、Control Plane / Autoscaling / Workload Identity / Ingress / Logging など運用層の罠を集めています。

「Autopilot is a mode of operation in GKE in which Google manages your cluster configuration, including your nodes, scaling, security, and other preconfigured settings.」 — GKE Autopilot overview

9.1 重大事故ケース 10 件(実務深掘り版)

各ケースは 症状 / 原因 / 処置 / 教訓 / 検知 metric の 5 行で構成。Section 2 / 7 と重複しないように、Autopilot 制約・Cluster Autoscaler 挙動・Control Plane upgrade・Workload Identity・Ingress Health Check・Logging quota を中心に選定しています。

⚠️ 9.1.1 Autopilot で DaemonSet が rejected、システム pod が作れず
症状監視 agent(Datadog DaemonSet)を Autopilot にデプロイ。Pod ... was rejected by admission webhook: DaemonSet using hostPath is not allowed で全 node に展開されず、host metric が一切収集されない。
原因Autopilot はセキュリティ強化のためのデフォルト制約として、hostPathhostNetworkhostPID、特権コンテナ等を禁止。DaemonSet 自体は許可されているが、host リソースへのアクセスを要する DaemonSet は webhook で reject される。
処置① まず Datadog 等の公式 chart が Autopilot 対応版を提供していないか確認(Datadog は GKE Autopilot 専用 chart あり) → ② 公式対応がない場合、Cloud Operations for GKE(Managed Service for Prometheus、Cloud Logging)に切替 → ③ どうしても hostPath が必要ならStandard 移行を検討。kubectl get pods -n datadog -o yaml | grep "rejected" で原因確認。
教訓Autopilot 採用前に「どんな DaemonSet を使うか」を洗い出し、Autopilot の制約 (許可されないワークロード一覧 ↗) と突き合わせる。セキュリティ・監視・CNI 系の DaemonSet は Autopilot で動かない可能性が高い
検知Cloud Logging で resource.type="k8s_cluster" + protoPayload.response.reason="Forbidden" + protoPayload.response.message=~"admission webhook" を alert。
💰 9.1.2 Standard cluster の node-auto-provisioning で過大マシン作成、コスト 5 倍
症状NAP(Node Auto-Provisioning)を有効化した翌週、請求書の GKE Compute が前月比 +400%。Cloud Logging で n2-highmem-96(96 vCPU / 768 GiB)が 6 台起動していた。
原因ある CronJob の Pod が resources.requests: {cpu: 80, memory: 600Gi}誤って書かれていた(本来 80m / 600Mi)。NAP は「この Pod を schedule できる最小 node」として n2-highmem-96 を新規作成、Pod 終了後もscaleDown delay 10 分の間は課金。
処置① 即時に gcloud container clusters update CLUSTER --autoprovisioning-max-cpu=32 --autoprovisioning-max-memory=128NAP 上限を設定 → ② resources.requests の誤りを修正 → ③ OPA Gatekeeper / Policy Controller で「requests.cpu > 16 または requests.memory > 64Gi の Pod は拒否」する Constraint を追加 → ④ LimitRange を全 namespace にデフォルト適用。
教訓NAP は強力だが「Pod request が malformed なら巨大 node が走る」。autoprovisioning-max-* の上限設定と、Admission Controller での request 制約が必須。NAP は profile + 上限を必ずペアで設定
検知Monitoring の kubernetes.io/container/cpu/request_coresrequest_cores > 16 の Pod 件数を alert。Billing の GKE Compute 日次変動 +30% で warn。
⚠️ 9.1.3 HPA + VPA 同時適用で Pod が再起動連発、SLO 違反
症状Pod が 5 分おきに OOMKilled / Evicted を繰り返し、HTTP 5xx 率 8%、SLO(99.9%)一発で違反。CPU 使用率は 30% 程度で余裕あり。
原因HPA を CPU メトリクスで設定(targetCPUUtilization: 70)+ 同じ Deployment に VPA をAuto モードで適用。VPA が requests を変更するたびに Pod が evict され、HPA は CPU 比率が変動するので scale 判断が安定しない。
処置① VPA を Off / Initial / Recreate モードへ変更(Auto モードは HPA と併用不可と公式に明記)→ ② HPA は CPU でなくカスタム metric(requests/s, queue depth)で動かす → ③ VPA はRecommendation modeで値だけ取得し、人間が PR でレビューして反映。
教訓HPA(CPU/Memory)+ VPA Auto は同じ Deployment で禁忌。Multi-dimensional Pod Autoscaler(MPA)か、HPA をカスタム metric で、VPA は Recommendation のみに分離する。
検知kubernetes.io/container/restart_count の delta > 3 を 10 分窓で alert。kube_pod_status_reason{reason="Evicted"} も併用。
⚠️ 9.1.4 Cluster Autoscaler の scaleDown timeout 短すぎで Pod 強制退去 → リクエスト drop
症状夜間バッチ完了後の scale-in 時、HTTP API Pod が予告なく drain され、進行中リクエストが 502 に。月数千件の SLO 違反。
原因CA の --scale-down-unneeded-time がデフォルト 10 分のまま、かつ Pod 側の terminationGracePeriodSeconds: 30 + preStop hook なし。CA は node 上の Pod に SIGTERM を送り 30 秒後に SIGKILL。in-flight リクエストは中断。
処置① Pod 側に preStop sleep 15s(LB が unhealthy 判定する時間を稼ぐ)+ terminationGracePeriodSeconds: 60 を設定 → ② PodDisruptionBudgetminAvailable: 80%)で同時 drain 数を制限 → ③ node lifecycle annotation cluster-autoscaler.kubernetes.io/safe-to-evict: "true" を batch Pod のみに付与し、API Pod は false に。
教訓CA の scaleDown は「node を消す = その node 上の全 Pod を evict」。preStop / GracePeriod / PDB の 3 点セットが必須。「Pod を安全に止める設計」と「node を畳む設計」は別物
検知HTTP LB の backend latency p99 と kube_node_status_condition{condition="Ready",status="false"} の相関で検知。
⚠️ 9.1.5 PodDisruptionBudget 設定漏れで node drain 中にサービス停止
症状Control Plane upgrade に伴う surge upgrade で、ある node pool の 5 node が並列で drain。3 replica の Deployment が全 Pod 同時 evictされ、サービス 4 分完全停止。
原因PDB が一切設定されておらず、node drain は全 Pod を即時 evict。3 replica が同一 zone の同一 node pool に偏って配置されていた(pod topology spread なし)。
処置PodDisruptionBudget を全 critical Deployment に作成(minAvailable: 50% または maxUnavailable: 1) → ② topologySpreadConstraints で zone / node pool 分散を強制 → ③ surge upgrade パラメータ --max-surge-upgrade=1 --max-unavailable-upgrade=0 に変更し同時 drain を 1 node に制限
教訓PDB なし = node maintenance / upgrade 時にサービス無防備。Production の全 Deployment に PDB を Org Policy / Policy Controller で必須化する。「PDB 無しは production deployment ではない」と覚える。
検知Policy Controller / OPA で「kind: Deployment に対応する PDB が無ければ alert」。kubectl get pdb -A を定期 audit。
⚠️ 9.1.6 Workload Identity 設定漏れで GCS 経由の ETL が全失敗
症状夜間 ETL Pod が 403 Permission deniedgcloud auth list は KSA を表示するが、実際の token request がGCE metadata server の default SA tokenを返している。
原因Workload Identity はcluster level + node pool level の両方で有効化が必要。新規追加した node pool に --workload-metadata=GKE_METADATA を指定し忘れ、その node 上の Pod だけが旧 metadata server を使い node SA で動作。
処置gcloud container node-pools update POOL --workload-metadata=GKE_METADATA → ② KSA と GSA の binding 確認:gcloud iam service-accounts get-iam-policy GSAserviceAccount:PROJECT.svc.id.goog[NS/KSA] が含まれるか → ③ Org Policyiam.disableServiceAccountKeyCreation + compute.requireOsLogin を有効化し、node SA で動作する経路を塞ぐ。
教訓Workload Identity はcluster ⇔ node pool ⇔ KSA ⇔ GSA の 4 段リンク。1 つでも欠けるとsilent に node SA fallbackする(最も気付きにくい)。node pool 作成時の terraform module に必須化
検知Cloud Audit Logs で protoPayload.authenticationInfo.principalEmail が node SA(...-compute@developer.gserviceaccount.com)の API call を alert。
⚠️ 9.1.7 Zonal cluster で control plane upgrade 中に kube-apiserver 10 分 downtime
症状火曜 02:00 JST、自動 upgrade window 中に kubectl get pods が timeout。Argo CD の自動 sync が全 fail、デプロイパイプライン死亡。10 分後に復旧。
原因本番 cluster がZonal cluster。Zonal cluster はcontrol plane が 1 zone のみで冗長化されないため、upgrade 中は API server が完全停止。Regional cluster は 3 zone に control plane を分散しローリング upgrade で zero downtime
処置① 既存 Zonal を Regional に変換するには新 cluster を Regional で作って migrate(in-place 変換不可)→ ② migration は ASM / Multi-cluster Ingress で blue-green → ③ 暫定対応としてmaintenance window を業務影響最小の時間帯に限定 + maintenance exclusion で繁忙期は upgrade 禁止。
教訓Production は必ず Regional cluster。月コスト差は cluster 管理料 $73 → $219(3 倍)だが、kube-apiserver 可用性は段違い。「Zonal は dev / 学習用、Production は Regional」を Org Policy で強制可。
検知Monitoring の kubernetes.io/cluster/api_server/request_count が 1 分以上 0 で alert。Argo CD の sync failure rate を SLI 化。
⚠️ 9.1.8 Spot node pool の Pod が一斉退去、CA が補充できず capacity 不足
症状Spot node pool 上の 30 Pod が同時 preempt。CA は補充を試みるが code=ZONE_RESOURCE_POOL_EXHAUSTED30 分間 capacity が確保できず、SLO 違反。
原因① Spot 単独の node pool を 1 zone のみで構成 → ② capacity 枯渇時の fallback 設計なし → ③ backup-on-demand 的な on-demand node pool が無く、CA は Spot のみで補充を試行し続けた。
処置multi-zone Spot node pool(3 zone 分散) → ② on-demand fallback node pool を taint 付きで用意し、preferred-during-scheduling で Spot を優先、Spot 枯渇時のみ on-demand へスケジュール → ③ CA に --expander=priority を設定し、Spot pool を高優先度に → ④ Compute Engine Reservation(オンデマンド予約)で重要 workload の予約 capacity を確保。
教訓Spot は常に「容量無保証」。Multi-zone + on-demand fallback + Reservation の 3 段防御が production の最低ライン。「Spot だけの node pool」は SLO サービスには使わない
検知CA の event log で NoScaleUp + no.scale.up.spot.capacity を alert。kube_pod_status_phase{phase="Pending"} 滞留時間。
⚠️ 9.1.9 Ingress の Backend Service Health Check 設定ミスで 502 連発
症状新規 Ingress(GCLB)経由のリクエストが間欠的に 502。Pod は Ready、Service の Endpoints も正常。GFE の access log に backend_connection_closed_before_data_sent_to_client
原因BackendConfig(GKE Ingress 専用 CRD)で health check path を指定せず、GCLB はデフォルトで / へ GET。アプリの / は 200 を返すが応答時間 4 秒で、GCLB のデフォルト timeoutSec: 5 を時折超え unhealthy 判定。
処置BackendConfighealthCheck: { type: HTTP, requestPath: /healthz, timeoutSec: 1, checkIntervalSec: 5, healthyThreshold: 1, unhealthyThreshold: 3 } を明示 → ② アプリに /healthz(DB connection 等の外部依存は含めず in-memory のみ確認)を実装 → ③ readinessProbeBackendConfig health check を一致させる(path / port / timeout)。
教訓GKE Ingress の health check はBackendConfig で明示しない限り / がデフォルト。readinessProbe と独立に動作するので、両方を同じ条件で設計。healthz は外部依存を含めないのが鉄則。
検知LB の loadbalancing.googleapis.com/https/backend_latencies p99 と backend_status_code="5xx" 比率。
💰 9.1.10 Cloud Logging quota 超過で重要 audit log が drop
症状監査チームから「先週 木曜 14:00〜18:00 の admin activity log が欠落」と指摘。SOC2 audit で「ログの完全性」要件違反のリスク。
原因GKE cluster の workload log が DEBUG 出力 + 大量 stack trace で1 分あたり 10 GBを超過し、Cloud Logging API write quota(プロジェクト毎の WriteRequestsPerMinutePerProject 等)を消費。Logging Agent の queue 溢れでaudit log も巻き添えで drop
処置Log Router の Exclusion filter で workload の DEBUG ログを除外(severity < INFO) → ② audit log は専用 sink で別 project の独立 bucketへ → ③ 重要 log は Required log buckets(_Required は exclusion 不可)またはBigQuery sink + Cloud Storage sink で二重冗長化 → ④ Quota 上限引き上げ申請。
教訓Cloud Logging は「無限に飲み込んでくれる」訳ではない。quota / agent buffer / sink 経路の 3 つに上限がある。audit log と workload log は経路分離が原則。
検知logging.googleapis.com/byte_countlogging.googleapis.com/dropped_log_entry_count を monitoring。Quota usage は serviceruntime.googleapis.com/quota/exceeded で alert。

9.2 GKE コスト構造の解剖(Standard vs Autopilot)

GKE の請求書は「cluster 管理料 + compute 料 + storage 料 + network 料」の 4 階層で構成されます。Standard と Autopilot でcompute 課金単位が決定的に異なるため、ワークロード特性により最適解が変わります。

9.2.1 主要コンポーネント別の課金(2026 年時点)

コンポーネントStandardAutopilot備考
Cluster 管理料$0.10 / hour(≒ 月 $73)$0.10 / hour(≒ 月 $73)無料枠:billing account ごとに 1 zonal cluster 無料
Compute(Pod / Node)node の VM 料金(GCE 価格)Pod の vCPU + Memory request(per-Pod 課金)後述の単価表参照
Regional cluster 追加料同じ $0.10/h(control plane 冗長分は無料)同じ $0.10/h2024 以降は zonal と同額に統一
Persistent DiskStandard PD $0.04/GB-month、SSD PD $0.17/GB-month同じscale 後に attach されたまま残ると累積
Load Balancer$18-25 / 月 / forwarding rule + データ処理料同じIngress 1 つあたり管理コスト固定
Egress(cross-region / Internet)$0.01〜0.12 / GB同じmulti-region cluster で要注意
Logging / Monitoring$0.50 / GB ingested(_Default は 50 GB / 月無料)同じworkload log が支配的になりやすい
「Autopilot mode bills you for the CPU, memory, and ephemeral storage that your Pods request while they are running.」 — GKE pricing — Autopilot mode

9.2.2 Autopilot の Pod 単価(General-purpose, us-central1)

リソース単価備考
vCPU$0.0445 / vCPU-hourPod の resources.requests.cpu 合計で課金
Memory$0.0049 / GiB-hourPod の resources.requests.memory 合計で課金
Ephemeral storage$0.0000548 / GiB-hour1 GiB がデフォルト、明示指定可
Spot Pod上記から最大 60-91% 割引Pod spec に spot: true 指定
Balanced / Scale-Out / Acceleratorcompute class により別単価GPU / Arm 等は加算あり

9.2.3 Standard の Node 単価(参考、n2-standard-4 = 4 vCPU/16 GiB, us-central1)

machine typevCPUmemory単価 / hour(on-demand)Spot 単価(≒ 60-91% off)
e2-medium14 GiB$0.033$0.010
e2-standard-4416 GiB$0.134$0.040
n2-standard-4416 GiB$0.194$0.058
n2-standard-161664 GiB$0.7763$0.233
n2-highmem-8864 GiB$0.524$0.157
c2-standard-16(compute-optimized)1664 GiB$0.836$0.251

9.2.4 Autopilot vs Standard 単価の損益分岐点

💰 計算例:bin packing 効率と損益分岐 条件:Pod 5 個、各 2 vCPU / 4 GiB、24/7 稼働。
Autopilot:10 vCPU × $0.0445 × 730h + 20 GiB × $0.0049 × 730h = $325 + $72 ≒ 月 $397 + $73(管理料)= $470
Standard(n2-standard-16 × 1 = 16 vCPU/64 GiB に詰める):$0.7763 × 730h + $73 = $567 + $73 = $640(node 利用率 62.5%)
5 Pod 程度なら Autopilot が約 27% 安い

逆の条件:Pod 50 個、各 2 vCPU / 4 GiB(合計 100 vCPU / 200 GiB)
Autopilot:100 vCPU × $0.0445 × 730h + 200 GiB × $0.0049 × 730h = $3,249 + $716 = $3,965 + $73 = $4,038
Standard(n2-standard-16 × 7 で 112 vCPU 詰める):$0.7763 × 730h × 7 + $73 = $3,968 + $73 = $4,041(node 利用率 89%)
50 Pod 規模で Standard と Autopilot は同等。bin packing 効率が 89% を超えるなら Standard 有利、それ未満なら Autopilot 有利。

Spot 混在の条件:上記 50 Pod のうち 30 Pod を Spot に → Standard の方が Spot 適用範囲が広く(node 全体)、約 35-50% 削減可能。

9.3 コスト肥大化の典型パターン 6 件

💰 パターン A — Standard で over-provisioned node、bin packing 失敗

症状:node 利用率 30% で月 $5,000、Pod 数は 100 程度。Cloud Monitoring の node_cpu_allocatable_utilization も 30%。

原因:開発者が「念のため」requests.cpu を実使用の 5 倍に設定。schedule 時に node を埋められず、CA が常に新 node を起動。

▼ コスト試算(月) before: n2-standard-16 × 10 台 × $0.7763 × 730h = $5,667 after : 同じ Pod を request 適正化、bin packing で 4 台に集約 = n2-standard-16 × 4 台 × $0.7763 × 730h = $2,267 → -$3,400 / 月(-60%)

対処:① VPA Recommendation mode で過去 30 日の actual usage から推奨 request を取得 → ② requests = p95(actual) × 1.2 を目安に PR → ③ CA を --autoscaling-profile=optimize-utilization に変更しbin packing 優先

💰 パターン B — Autopilot で軽量 Pod 大量、per-Pod 料金が積み上がる

症状:Pod 数 500(各 0.25 vCPU / 256 MiB の microservice)。Autopilot で月 $4,000、同じ Pod を Standard に置けば $1,500 程度。

原因:Autopilot はPod 数に比例して minimum overheadがある(各 Pod に kube-system overhead を加算)。さらに 最小 request(0.25 vCPU、0.5 GiB)に丸められるため、それ以下の小さな Pod でも 0.25 vCPU 分課金される。

▼ Autopilot の minimum request roundup Pod spec: requests.cpu = 50m, memory = 128Mi Autopilot 実課金: cpu = 250m, memory = 512Mi ← roundup 500 Pod × 0.25 vCPU = 125 vCPU × $0.0445 × 730h = $4,060 / 月 Standard(n2-standard-16 × 2 で詰める): 32 vCPU × $0.7763 × 730h = $1,815 / 月 → -$2,245 / 月

対処:① 軽量 Pod 大量ならStandard + bin packingに移行 → ② どうしても Autopilot を使うなら同 namespace 内で複数 Pod を 1 つに統合(sidecar 削減等) → ③ Autopilot 公式の最小リソース仕様を採用前に確認。

💰 パターン C — node pool の machine type 過剰(メモリ余り)

症状:API サーバ用 node pool に n2-highmem-16(16 vCPU / 128 GiB)を採用。CPU 使用率 70%、メモリ使用率 15%。

対処workload の CPU:Memory 比率を測定し、最適 machine family を選定。
・CPU bound(比率 1:2 未満)→ n2-highcpu 系(vCPU:RAM = 1:1)
・汎用(比率 1:4 程度)→ n2-standard 系(1:4)
・Memory bound(比率 1:8 以上)→ n2-highmem 系(1:8)
・特殊比率 → Custom machine type(N1/N2 のみ可)で 1:3 等を指定。

💰 パターン D — taint / nodeSelector 制約で利用率 30%

症状:node pool A は GPU 専用、B は memory-heavy、C は default。各 pool の利用率がそれぞれ 20-40%。

対処:① node pool 統合(GPU 以外は default に統合)→ ② nodeAffinitypreferredDuringScheduling に緩和し、必要なら他 pool にも落ちる設計 → ③ Compute Class(Autopilot)で workload class を分離。

💰 パターン E — Filestore / PD over-provisioning

症状:StorageClass で 100 GiB SSD PD を Default 設定。dev 環境の Pod が PVC 100 個 = 10 TB、実使用 500 GB。月 $1,700 → $85 の浪費。

対処:① StorageClassallowVolumeExpansion: true + 初期 10 GiB → ② Filestore は最小 1 TiB からなので、共有不要なら GCSFuse / PD で代替 → ③ PV reclaim policyDelete に(Retain だと Pod 削除後も残る) → ④ Snapshot 数とサイズを定期 audit。

💰 パターン F — 環境別 / team 別に cluster を量産(50 cluster 問題)

症状:env × team × region で cluster が 50 個、各 $73 × 50 = 月 $3,650 が cluster 管理料だけで消失。各 cluster の node 利用率も 20% 以下。

対処:① multi-tenant cluster(namespace 分離 + ResourceQuota + NetworkPolicy) → ② team 分離は fleet(Anthos / GKE Enterprise)で論理境界 → ③ env 分離は最低限(dev / stg / prd の 3 cluster × region)に圧縮 → ④ shared services cluster(CI/CD agent、Prometheus 等)を 1 つに集約。

9.4 最適化テクニック 10 個

  1. Autopilot vs Standard の判断軸
    ・Autopilot 有利:小規模(< 30 Pod)、運用工数最小化、SRE 不在、初学者
    ・Standard 有利:大量 Pod(> 50)、特殊 DaemonSet、bin packing 80%+、GPU、特殊 networking
  2. Cluster Autoscaler の optimize-utilization profile--autoscaling-profile=optimize-utilizationscaleDown を積極化、node 利用率 80%+ を目指す。デフォルト balanced は availability 優先。
  3. Bin packing 最適化(適切な resources.requests):VPA Recommendation mode で過去 30 日の実測 → requests = p95 × 1.2 を PR 化。requests 適正化が単一最大のコスト削減手段
  4. Spot node pool の活用:stateless / バッチ / dev は Spot で 60-91% 削減。production はmulti-zone Spot + on-demand fallback + PDB + preStop の 4 点セット。
  5. Node Auto-Provisioning(NAP)+ 上限設定:NAP は新規 machine type を自動選定し bin packing 効率化。必ず --autoprovisioning-max-cpu / --max-memory で上限を設定。
  6. Vertical Pod Autoscaler in Recommendation mode:Auto モードは HPA 競合・restart 多発のため本番禁止。Recommendation mode で値だけ取得し人間レビュー。
  7. GKE Cost Allocation + Cost Insight:cluster 単位で billing-export を namespace / label 別に按分可能。BigQuery + Looker Studio で部門別 dashboard。
  8. Multi-tenant cluster(namespace 分離):cluster 数を圧縮し管理料・base capacity を節約。ResourceQuota + LimitRange + NetworkPolicy + Hierarchical Namespaces (HNS) でテナント分離。
  9. Pod Disruption Budget の適切な設定:production は必ず PDBminAvailable: 50% 推奨。Org Policy / Policy Controller で必須化。
  10. Regional vs Zonal の trade-off
    ・Regional:control plane 冗長、upgrade zero downtime、node も multi-zone で配置可、cluster 管理料は zonal と同額(2024 以降)
    ・Zonal:単一 zone のみ、upgrade 中 API 停止、dev / 学習用
    production は Regional 一択
💡 BP:GKE Production cluster の「最適化済みテンプレ」(gcloud)
gcloud container clusters create prod-cluster \ --region=us-central1 \ # Regional cluster --release-channel=regular \ # 安定 upgrade --enable-autoscaling --min-nodes=1 --max-nodes=10 \ --autoscaling-profile=optimize-utilization \ # bin packing 優先 --enable-autoprovisioning \ --autoprovisioning-max-cpu=64 \ # NAP 上限 --autoprovisioning-max-memory=256 \ --workload-pool=PROJECT.svc.id.goog \ # Workload Identity --enable-shielded-nodes \ --enable-private-nodes \ # Private nodes --master-ipv4-cidr=172.16.0.0/28 \ --enable-network-policy \ --enable-dataplane-v2 \ # Cilium ベース --logging=SYSTEM,WORKLOAD \ # Logging 範囲 --monitoring=SYSTEM \ --maintenance-window-start=2024-01-01T18:00:00Z \ --maintenance-window-end=2024-01-01T22:00:00Z \ --maintenance-window-recurrence='FREQ=WEEKLY;BYDAY=SA,SU' # node pool 作成(Spot + on-demand fallback の 2 pool) gcloud container node-pools create spot-pool \ --cluster=prod-cluster --region=us-central1 \ --spot --machine-type=n2-standard-4 \ --enable-autoscaling --min-nodes=0 --max-nodes=20 \ --workload-metadata=GKE_METADATA # WI 必須 gcloud container node-pools create on-demand-pool \ --cluster=prod-cluster --region=us-central1 \ --machine-type=n2-standard-4 \ --enable-autoscaling --min-nodes=1 --max-nodes=5 \ --node-taints=fallback=true:PreferNoSchedule \ --workload-metadata=GKE_METADATA

9.5 監視・アラート設計(GKE 特有)

9.5.1 監視すべき主要 metric

metric説明SLI / alert 例
kubernetes.io/container/cpu/request_utilizationrequest 比率の actual usage1 週間平均 < 30% で over-provision 候補
kubernetes.io/container/memory/request_utilizationmemory request 比率同上
kubernetes.io/container/restart_countcontainer 再起動回数delta > 3 / 10min で alert
kubernetes.io/node/cpu/allocatable_utilizationnode 全体の利用率node pool 平均 < 50% で集約検討
kubernetes.io/autoscaler/cluster_autoscaler/unschedulable_pods_countschedule 不能 Pod 数5 分以上滞留で alert
kubernetes.io/cluster/api_server/request_countkube-apiserver 受信数1 分間 0 なら apiserver down
logging.googleapis.com/dropped_log_entry_countlog drop 数1 件でも warn
Pod eviction eventCloud Logging で jsonPayload.reason="Evicted"1 件で warn、memory pressure 検知

9.5.2 GKE 特有の SLO 設計

Cluster availability SLO
kube-apiserver の応答率 ≥ 99.95%(Regional)/ 99.5%(Zonal)
Workload SLO
Pod の readiness 比率 ≥ 99.9%、HTTP 5xx 率 < 0.1%
Autoscale latency SLO
unschedulable Pod 検知から node 追加完了まで < 90 秒(Spot 含む)
Cost SLO
node pool 利用率 ≥ 60%、month-over-month コスト変動 < 20%

9.5.3 コスト・容量アラート

Budget alert
Cloud Billing で「Kubernetes Engine」のサブ予算、月予算 50/80/100/120% で通知。Forecasted spend(予測) alert で月途中の異常検知
Quota alert
region quota(CPUS, IN_USE_ADDRESSES, SSD_TOTAL_GB)を 80% で warn。Spot capacity に依存するならpreemptible quota も別途
Idle node alert
node 利用率 < 30% が 24h 継続したら集約検討
Cost spike alert
GKE Compute の日次コスト前日比 +30% で SRE 通知

9.6 試験ポイント(Section 9 要点)

🔑 GKE 試験ポイント
  • Autopilot の制約:hostPath / hostNetwork / 特権コンテナ禁止。セキュリティ / 監視 DaemonSet は動かない可能性
  • Production cluster は Regional。Zonal は upgrade 中 control plane 停止
  • Workload Identity は cluster + node pool + KSA + GSA の 4 段。1 つでも欠けると node SA に silent fallback
  • PDB なし = production 失格。node drain / upgrade 時のサービス停止リスク
  • HPA + VPA Auto は禁忌。VPA は Recommendation mode で人間レビュー
  • NAP は上限設定必須。malformed request で巨大 node が走るリスク
  • cluster 管理料は $0.10/h(≒ $73/月)、billing account ごとに zonal 1 つ無料
  • Autopilot 単価:$0.0445/vCPU-h + $0.0049/GiB-h(Pod request ベース)
  • 「軽量 Pod 大量」は Standard 有利、「数 Pod だけ」は Autopilot 有利。bin packing 効率 89% がおおむね損益分岐
  • Spot は multi-zone + on-demand fallback + PDB + preStop の 4 点セットで初めて production grade
  • Cluster Autoscaler profilebalanced(デフォルト・可用性優先) vs optimize-utilization(コスト優先)

10. Cloud Run 運用深掘り:事故・コスト・肥大化対策

Cloud Run は「リクエストベースの完全サーバレス compute」として運用工数最小ですが、concurrency / cpu-allocation / min-instances の 3 つの設定を理解しないと、請求書が想定の数十倍になることがあります。本章では Section 2.7 / 7.5 の Cloud Run 事故を発展させ、Worker Pool・Cloud Run Jobs・gen1↔gen2・VPC Connector・Secret 連携などの深部を扱います。

「By default, a container instance is allocated CPU only during request processing. You can configure your service to always allocate CPU to container instances.」 — Cloud Run CPU allocation

10.1 重大事故ケース 10 件(実務深掘り版)

各ケースは 症状 / 原因 / 処置 / 教訓 / 検知 metric の 5 行で構成。Section 7.5 の事故と重複しないように、Worker Pool・Jobs・Secret・gen 切替・size limit・VPC Connector・Cloud Run Functions 等の深部を扱います。

⚠️ 10.1.1 min-instances=0 + cold start 3 秒で SLO 違反
症状API 全体の SLO(p99 < 1 秒)に対し、p99 = 3.2 秒。0.5% のリクエストが cold start に当たり、Java Spring Boot の起動 + JIT で 3 秒。エンドユーザーから「時々遅い」苦情。
原因min-instances=0 でアイドル中はスケールゼロ。新規リクエスト時に container start + アプリ起動が必要。Java / .NET 系は cold start 2-5 秒が一般的
処置min-instances=1 設定 + CPU boost 有効化(gen2 で startup 時 CPU 倍増) → ② アプリ側でAOT compilation(Spring Boot → GraalVM Native Image)で起動 100ms へ短縮 → ③ それでも厳しければCloud Run 不向き、GKE で常時 Pod 化を検討。
教訓cold start は言語ランタイム選定に大きく依存。Java / .NET = 数秒、Go / Rust / Node = 数百ms、Python = 数百ms-1秒。SLO 厳しいならmin-instances ≥ 1 + CPU boost を基本とし、コストとのトレードオフを設計時に決める。
検知run.googleapis.com/container/startup_latencies p95、および run.googleapis.com/container/instance_count の min を監視。
💰 10.1.2 concurrency=1 のまま Worker Pool 化、月コスト 80 倍
症状Pub/Sub push 経由の I/O bound worker(DB 待ち中心)を Cloud Run で実装。concurrency: 1 のまま運用、月 $8,000。同じワークロードを GKE Deployment 化で月 $100 程度の見積もり。
原因Pub/Sub push は 1 message = 1 リクエストだから concurrency=1 で良い」という誤解。I/O 待ち時間中に同 instance で他の message も処理できる。
処置① concurrency=80(max)に変更し負荷試験 → ② Pub/Sub の maxOutstandingMessages / maxConcurrentDispatch を調整 → ③ 長時間ジョブは Cloud Run Jobs に分離(Cloud Run service の max request timeout は 60 分) → ④ Worker Pool(Cloud Run の新機能、リクエストなしの常時実行)を検討。
教訓concurrency=1 は「state shared / thread unsafe / heavy computation」のみ。I/O bound なら 80(max)。負荷試験でレイテンシが許容範囲内に収まる最大 concurrency を見つけ設定。
検知run.googleapis.com/container/instance_count の積分 × 単価 を予測し、month-over-month で警戒。
💰 10.1.3 CPU always allocated を意図せず ON で常時課金
症状月数千リクエストの社内ツール(ほぼアイドル)に月 $200。gcloud run services describecpuAllocation: ALWAYS が判明。
原因WebSocket 機能を「将来追加する予定」で CPU always allocated を ON にし、結局 WebSocket は未実装のまま。request 処理外でも CPU + Memory が常時課金される(min-instances=1 の場合)。
処置CPU allocation--no-cpu-throttling から外す(デフォルト:request 中のみ CPU 割当) → ② WebSocket / streaming / バックグラウンド処理が実際に必要かを設計時に判定 → ③ 不要ならrequest-based billing(デフォルト)で大幅削減。
教訓CPU always allocated はWebSocket / SSE / 長時間 streaming / 背景処理4 ユースケース限定。それ以外は request-based。公式 CPU allocation guide ↗ を必ず一読。
検知Cloud Asset Inventory で resource.type="run.googleapis.com/Service" + spec.template.spec.containers[].resources.cpuIdle=false の service を日次 audit。
⚠️ 10.1.4 Secret 環境変数の version 指定ミスで Revision deploy が即時失敗
症状新 revision を deploy するたび ContainerHealthCheckFailed: container failed to start。前 revision に rollback で動く。
原因Secret Manager 連携で --update-secrets=API_KEY=my-secret:latest と指定していた。Secret が rotation され latest が新 version になったが、新 version が disabled 状態。Cloud Run は revision 起動時に Secret を pull し、disabled だと取得失敗。
処置Secret は version pinmy-secret:7)を原則化 → ② rotation 時は新 version を enabled で作成 → Cloud Run revision 再 deploy → 旧 version disable の順序 → ③ Cloud Run のSecret access service accountroles/secretmanager.secretAccessor)が runtime SA に付与されているか確認。
教訓Cloud Run の Secret は「mount 時に取得」型(一部)と「環境変数として展開」型がある。latest は production で使わず、必ず version pin。rotation は両 version を一時的に enabled に。
検知Cloud Logging で resource.type="cloud_run_revision" + severity=ERROR + jsonPayload.message=~"secret" を alert。
⚠️ 10.1.5 HTTPS request size 32 MB 制限で 413 連発(gen1)
症状画像アップロード API(10-50 MB の画像)が 413 Request Entity Too Largeapplication/json body 32 MB を超えるリクエストも同様。
原因Cloud Run gen1 のHTTPS request payload size limit は 32 MB(hard limit)。streaming も非対応。
処置gen2 (Cloud Run Execution environment second generation) に切替:gen2 はrequest streaming + 大容量 body 対応(理論上 size 制限緩和)→ ② アプリ設計を変えdirect upload to GCS(signed URL 経由)+ Cloud Run は metadata のみ受信 → ③ どうしても受信するならchunked upload(multipart)。
教訓gen1 / gen2 の制約は意外と異なるExecution environments 公式 ↗ を読み、機能要件と照合してから採用。大容量 upload は GCS signed URL で OS-bypass が定番
検知HTTP LB の backend_status_code="413" 比率を monitoring。
⚠️ 10.1.6 Cloud Run Jobs の max execution timeout 24h 超過で deploy 失敗
症状週次 ETL(30 時間ジョブ)を Cloud Run Jobs で実装。--task-timeout=86400(24h)以上を指定すると INVALID_ARGUMENT
原因Cloud Run Jobs のtask timeout 上限は 24 時間(hard limit)。Cloud Run service の request timeout も 60 分が上限。
処置① ETL を複数 task に分割--tasks=N --parallelism=K)し各 task < 24h に → ② 長時間ジョブはGKE CronJob または Compute Engine + Cloud Scheduler へ → ③ Spark / BigQuery 系の workload ならDataflow / BigQuery scheduled query へ。
教訓Cloud Run は「短時間 stateless workload」用。長時間バッチは分割 or 他サービス。サービス選定時にSLA / timeout / size 制約を一覧で確認。
検知Cloud Run Jobs の execution_count{status="cancelled_timeout"}
💰 10.1.7 VPC Connector 過剰追加で egress 帯域 + idle コスト爆発
症状Cloud Run service 20 個、それぞれ専用 Serverless VPC Connector を作成。e2-micro × 2 instance × 20 connector × 24h × 30d = 月 $144 が idle で消える + データ処理料も別途。
原因「サービスごとに分離した方がきれい」と思い1 service = 1 connectorで運用。Connector はmin_instances=2 で常時課金(e2-micro 単位)。さらに connector 経由 egress は追加データ処理料
処置Direct VPC egress(gen2 専用)に移行:Connector 不要、direct に VPC へ → ② Connector を共用する場合はregion 単位で 1 つ、複数 service で share → ③ VPC 内通信不要ならconnector を外す(Cloud Run はデフォルト public internet 経由)。
教訓Serverless VPC Connector はidle でも常時課金(min instance 2 が必須)。gen2 + Direct VPC egress が新規 production の第一選択。Direct VPC egress 公式 ↗
検知Cloud Asset Inventory で project 内の Connector 数を月次 audit。同 region 内 Connector の重複を検知。
⚠️ 10.1.8 gen1 → gen2 切替で startup probe 動作差で全 revision 起動失敗
症状gen1 で動いていた service を --execution-environment=gen2 に変更したら全 revision が起動失敗ContainerHealthCheckFailed
原因gen1 と gen2 でfilesystem / network namespace 等の挙動差異がある。アプリは /tmptmpfs 前提で使っており、gen2 では実 disk based に変わったため I/O latency が増え startup probe が間に合わなかった(gen1 vs gen2 の挙動差は時期により変動する)。さらに gen1 で sandbox API(一部 syscall)を使っていた箇所が gen2 では別挙動。
処置新 revision に traffic 0% で deploy(traffic splitting)→ ② 動作確認後に段階的に traffic 移動 → ③ アプリのfilesystem 前提 / syscall 依存箇所を gen2 互換に修正 → ④ startupProbe.initialDelaySeconds / periodSeconds / failureThreshold を調整。
教訓gen 切替は「同じ container でも挙動が違う」と覚悟する。traffic 0% deploy → 段階移行を rule に。Execution environments 比較 ↗
検知Cloud Logging で revision deploy 時の ContainerHealthCheckFailed を即時 alert。
⚠️ 10.1.9 Cloud Run Functions(旧 gen2 Cloud Functions)の cold start で SLO 違反
症状Pub/Sub trigger の Cloud Run Functions(Python 3.11、Flask wrapping)。p99 invocation latency が 2.5 秒、許容 500ms を大幅超過。
原因Cloud Run Functions はCloud Run の上に Functions Framework が乗った構造。Python の場合、import の重い library(pandas、tensorflow 等)が cold start に直撃。さらに Pub/Sub trigger はmin-instances を上げづらい(リクエスト ≒ message のため、ピーク予測しづらい)。
処置min-instances=1 + CPU boost → ② 重い import を遅延読み込み(関数内で import)→ ③ Cloud Run Functions ではなくCloud Run service として書き換え(より細かい設定が可能)→ ④ どうしても cold start を許容できないなら GKE Deployment へ。
教訓Cloud Run Functions = Cloud Run service の「より簡単版」であり、内部は同じ。SLO 厳しいならCloud Run service として明示的に管理した方が制御性が高い。Functions Framework のオーバーヘッドも考慮。
検知cloudfunctions.googleapis.com/function/execution_times p99 と cloud_function_execution_count{status="ok"}
💰 10.1.10 Cloud Run Jobs の retry 設定で同 task が重複実行 → DB 二重書き込み
症状夜間 ETL Job が transient error で 1 task fail → --max-retries=3 設定で 3 回再実行 → DB に同じレコードが 4 行登録。アプリは冪等性なし
原因Cloud Run Jobs はtask 単位での自動 retryを提供(--max-retries)。同じ CLOUD_RUN_TASK_INDEX で再実行されるが、アプリ側で冪等性を保証しないと重複書き込みになる。
処置① アプリ側で冪等性を担保(INSERT ... ON CONFLICT DO NOTHING、UUID 主キー等)→ ② retry が必要ならidempotency keyCLOUD_RUN_TASK_INDEX + CLOUD_RUN_TASK_ATTEMPT で生成 → ③ 並列実行を考慮:--parallelism=N で N task 同時実行、それぞれが完了するまで Job は終わらない。
教訓「retry」と「冪等性」は必ずセット。retry を有効にする時点で、アプリ側で「同じ task が複数回走っても安全」を担保する必要がある。分散システムの大原則
検知DB 側で unique constraint violation count を monitoring。task の CLOUD_RUN_TASK_ATTEMPT > 0 件数を週次 review。

10.2 Cloud Run コスト構造の解剖

Cloud Run の請求は「vCPU 秒 + Memory 秒 + Request 数 + Network egress」の 4 軸で構成され、さらに「CPU allocation モード」「min-instances」で課金挙動が大きく変わります。理解の鍵は「いつ vCPU/Memory が課金されるか」です。

10.2.1 主要コンポーネント別の課金(2026 年時点、Tier 1 region)

コンポーネント単価備考
vCPU 秒(request-based, throttled)$0.000024 / vCPU-secrequest 処理中のみ課金(デフォルト)
Memory 秒(request-based)$0.0000025 / GiB-sec同上
vCPU 秒(always allocated)$0.000018 / vCPU-sec常時課金だが単価は安い(throttled の 75%)
Memory 秒(always allocated)$0.000002 / GiB-sec同上
Request 数$0.40 / 100 万 requests無料枠:月 200 万 requests
Network egressGCE 通常 egress 料金同 region 内 0、Internet $0.12/GB 等
min-instances(idle 状態)always allocated 単価で常時課金min=1 で常時 1 instance 分の vCPU + Memory
Cloud Run Jobs(vCPU/Memory)always allocated と同単価task の execution 時間で課金
「With CPU always allocated, your container instances always have CPU allocated. This is useful for background tasks or for services that have an active connection to a client.」 — Cloud Run CPU allocation

10.2.2 CPU allocation モードの違い(最重要)

項目CPU only during request processing(throttled, default)CPU always allocated
課金タイミングrequest 処理中のみ vCPU + Memory 課金instance 起動中ずっと vCPU + Memory 課金
vCPU 単価$0.000024 / vCPU-sec$0.000018 / vCPU-sec(25% 安い)
Memory 単価$0.0000025 / GiB-sec$0.000002 / GiB-sec(20% 安い)
Request 課金$0.40 / 100 万 requests無料
背景処理request 終了後 CPU が throttle、async/background 動作不可常時 CPU 利用可、background 処理 OK
WebSocket / SSE非推奨(connection 維持中も CPU throttle)必須
適用ケースstateless API、ほぼ request-response 完結WebSocket、SSE、background task、長時間処理

10.2.3 Free tier の正確な仕様

vCPU 秒
月 180,000 vCPU-秒(≒ 50 vCPU-hours)
Memory 秒
月 360,000 GiB-秒(≒ 100 GiB-hours)
Requests
月 200 万 requests
適用範囲
request-based billing(CPU throttled)のみ。always allocated は free tier 対象外
リセット
暦月の 1 日にリセット、繰越なし

10.2.4 試算例:3 つの典型ワークロード

💰 計算例:min-instances / concurrency / CPU allocation の組み合わせ 条件:月 1000 万 requests、各 200ms、1 vCPU、512 MiB Memory

① 標準 stateless API(CPU throttled, min-instances=0, concurrency=80)
・実 vCPU-秒 = (1000 万 × 0.2s) / 80 = 25,000 vCPU-sec → $0.60
・実 Memory-秒 = (1000 万 × 0.2s × 0.5) / 80 = 12,500 GiB-sec → $0.03
・Request = 1000 万 / 100 万 × $0.40 = $4.00
合計約 $4.63 / 月(free tier 適用後はほぼ無料)

② cold start NG API(min-instances=1, CPU throttled)
・min-instances=1 の idle はalways allocated 単価で課金
・idle 時間 ≒ 月 730h(リクエスト処理時間は微小)= 730 × 3600 = 2,628,000 sec
・vCPU 課金 = 2,628,000 × $0.000018 = $47.30
・Memory 課金 = 2,628,000 × 0.5 GiB × $0.000002 = $2.63
・Request 課金 = $4.00
合計約 $54 / 月(min-instances 効果で +$50)

③ WebSocket / 背景処理(min-instances=2, CPU always allocated, concurrency=80)
・常時 2 instance × 730h × 3600s = 5,256,000 sec
・vCPU 課金 = 5,256,000 × $0.000018 = $94.60
・Memory 課金 = 5,256,000 × 0.5 GiB × $0.000002 = $5.26
・Request 課金 = 0(always allocated は無料)
合計約 $100 / 月

10.3 コスト肥大化の典型パターン 6 件

💰 パターン A — min-instances を盲目的に >0

症状:開発者全員が「cold start = 悪」と思い、全 service で min-instances=2 設定。月数千リクエストの社内ツール 30 個 × $50/月 = 月 $1,500 が idle で消失

対処:① SLO 不要ならmin-instances=0(cold start 体感は気にしない) → ② 業務時間のみ事前 warm-up が必要なら Cloud Scheduler + curl で平日朝のみ warm 化 → ③ 真に必要なサービスにのみ min-instances を限定。「default は min=0、例外的に min>0」の運用方針を明文化。

💰 パターン B — CPU always allocated を意図せず ON で月数百ドル損失

症状:チームの 50 service のうち 12 service が CPU always allocated 設定。WebSocket は実装されていないにも関わらず常時課金。

対処:① Cloud Asset Inventory で cpuIdle 設定を audit → ② WebSocket / SSE / 背景処理が無いサービスは throttled に変更 → ③ Org Policy / Terraform module で「明示的なフラグなしには always allocated を ON にできない」ルール。

💰 パターン C — concurrency=1 のまま I/O bound workload

症状:DB 待ちが 90% を占める API で concurrency=1。各 request 200ms のうち 180ms が DB 待ち。本来 concurrency=80 で同 instance が 80 リクエスト並列処理できるはず。

▼ コスト比較(月 1000 万 requests、各 200ms、I/O 90%) concurrency=1 : 25 万 vCPU-h × $0.0864/h ≒ $21,600 / 月(理論最大) concurrency=80: 3,125 vCPU-h × $0.0864/h ≒ $270 / 月 → 80 倍コスト差

対処:① 必ず負荷試験を行い concurrency × throughput のスイートスポットを発見 → ② 一般則:I/O bound は 80(max)、CPU bound は 8-16、メモリ heavy なら 1-4 → ③ --cpu-throttling--concurrency はセットで設計。

💰 パターン D — VPC Connector の不要な追加

症状:「VPC 内のサービスにアクセスする予定」で 20 service すべてに Serverless VPC Connector を割当。実際に VPC 内アクセスするのは 3 service のみ。残り 17 service は connector idle で月 $5 × 17 = $85 浪費

対処:① VPC 内通信が本当に必要かを再評価(多くの GCP サービスは Public エンドポイント + IAM で十分) → ② 必要ならDirect VPC egress(gen2)に移行(Connector 不要) → ③ Connector を残す場合はregion 単位で 1 つを共用

💰 パターン E — Cloud Run Jobs の retry 設定で重複実行 → 課金 + DB 不整合

症状:100 task の Job で 10 task が flaky で retry 3 回。task 数 100 → 130 task 実行、課金 30% 増。さらに冪等性なしで DB に重複行。

対処:① flaky の根本原因を fix(network retry、timeout 拡張等) → ② 冪等性を必ず実装 → ③ retry は3 回までに制限、それ以上は dead letter queue(GCS / Pub/Sub)へ転送 → ④ Job 全体の cost を CLOUD_RUN_TASK_ATTEMPT ごとに分析。

💰 パターン F — gen2 で startup boost / CPU boost を未活用

症状:min-instances=1 で常時課金しているのに cold start も 2 秒あり、コスト・性能とも悪化。

対処:① gen2 + CPU boost--cpu-boost)を有効化、startup 時のみ CPU 倍増 → ② startup probe を適切に設定(cold start を待ってから healthcheck) → ③ 軽量ランタイム(Go / Rust / Node + minimal image)に変更し cold start を 100-300ms に圧縮 → ④ min-instances=0 + CPU boost で「ほぼ cold start 体感ゼロ」を狙う。

10.4 最適化テクニック 10 個

  1. concurrency 設定の負荷試験:1 / 8 / 32 / 80 で実機計測。レイテンシ劣化が許容範囲内の最大値を採用。I/O bound = 80、CPU bound = 8-16。
  2. CPU always allocated は必要時のみ:WebSocket / SSE / 背景処理 / 長時間 streaming の4 ユースケース限定。それ以外は throttled(デフォルト)。
  3. min-instances は SLO 要件 vs cold start トレードオフで決定:SLO 厳しい (p99 < 1s) なら 1-2、それ以外は 0。「全 service で min=2」は禁忌
  4. CPU boost で cold start 短縮(gen2)--cpu-boost で起動時 CPU 倍増、cold start 50% 短縮。コスト影響は startup 数秒のみ。
  5. Direct VPC egress(gen2)で Connector コスト削減:Serverless VPC Connector の min instance 2 + データ処理料を回避。公式 ↗
  6. Cloud Run Functions vs service の使い分け
    ・Functions:Pub/Sub trigger、Storage trigger、HTTP の短時間関数、簡易デプロイ
    ・service:細かい設定が必要、複雑なルーティング、長時間処理、自前 Dockerfile
  7. Always-on CPU vs request-based の判断軸
    ・request-based:stateless API、サンプル数 90% 以上のユースケース
    ・always-on:WebSocket / SSE / background processing(明確な要件があるときのみ)
  8. revision tag で blue-green deploygcloud run deploy --tag=blue --no-traffic で新 revision を tag 経由でテスト可、本番 traffic は 0% のまま検証。
  9. traffic splitting で canary release--to-revisions=blue=10,green=90 で段階的に traffic 移行。エラー率を見ながら 10 → 50 → 100%。
  10. Cloud Run Jobs のリソース最適化
    --cpu / --memory を実測ベースで設定(過剰スペック禁止)
    --parallelism で並列度調整(高すぎると DB 負荷、低すぎると総時間長期化)
    ・冪等性 + --max-retries=3 で flaky 対策
    --task-timeout を p99 × 1.5 で設定
💡 BP:Cloud Run service の「最適化済みテンプレ」(gcloud)
gcloud run deploy my-api \ --image=us-docker.pkg.dev/$PROJ/app/api:$SHA \ --region=us-central1 \ --execution-environment=gen2 \ # gen2 必須 --cpu=1 --memory=512Mi \ # 実測ベース --concurrency=80 \ # I/O bound のデフォルト --min-instances=0 \ # cold start 許容 --max-instances=100 \ # 過剰 scale-out 防止 --cpu-boost \ # cold start 短縮 --no-cpu-throttling=false \ # request-based billing --timeout=60s \ # request timeout --service-account=runtime-sa@$PROJ.iam.gserviceaccount.com \ --update-secrets=DB_PASS=db-pass:7 \ # version pin(latest 禁止) --vpc-egress=private-ranges-only \ # 必要な egress のみ --network=projects/$PROJ/global/networks/main \ --subnet=projects/$PROJ/regions/us-central1/subnetworks/main \ --ingress=internal-and-cloud-load-balancing \ --no-allow-unauthenticated \ # IAM 認証必須 --labels=team=backend,env=prod,costcenter=cc100 # canary deploy gcloud run deploy my-api --image=...:$NEW_SHA --tag=green --no-traffic gcloud run services update-traffic my-api --to-revisions=green=10 # ... 監視で OK なら段階的に gcloud run services update-traffic my-api --to-revisions=green=100

10.5 監視・アラート設計(Cloud Run 特有)

10.5.1 監視すべき主要 metric

metric説明SLI / alert 例
run.googleapis.com/request_countrequest 数(status code 別)5xx 率 > 1% で alert
run.googleapis.com/request_latenciesrequest latency 分布p99 > SLO で alert
run.googleapis.com/container/startup_latenciescold start 時間p95 > 2s で warn
run.googleapis.com/container/instance_countinstance 数min との乖離、max への張り付き
run.googleapis.com/container/cpu/utilizationsCPU 使用率常時 < 30% で over-provision 候補
run.googleapis.com/container/memory/utilizationsMemory 使用率> 90% で OOM リスク
run.googleapis.com/container/billable_instance_time課金対象 instance 時間コスト試算の基礎
run.googleapis.com/container/max_request_concurrencies同時 request 上限到達回数frequent なら concurrency 引き上げ検討

10.5.2 Cloud Run 特有の SLO 設計

Availability SLO
5xx 率 < 0.1%(99.9%)/ < 0.01%(99.99%)
Latency SLO
p99 request latency < 1s(含 cold start)/ < 500ms(cold start 除外)
Cold start SLO
cold start 比率 < 1% の週で 99% 達成
Cost SLO
idle instance time / total billable time < 30%(min-instances 効率)

10.5.3 コスト・容量アラート

Budget alert
Cloud Billing で「Cloud Run」サブ予算。月予算 50/80/100/120% で通知。Forecasted spend alert で月途中の異常検知
min-instances 異常 alert
Cloud Asset Inventory で全 service の minScale を週次 audit、minScale > 0 の service リストを Slack 通知
CPU always allocated audit
Asset Inventory で cpuIdle = false の service を日次レポート(WebSocket 等の正当理由がない service を検出)
instance max 張り付き alert
instance_count == max-instances が 5 分以上続いたら scale-out 上限引き上げ検討
VPC Connector idle audit
Connector 一覧と関連付け service を月次 audit、不要 Connector を削除

10.6 試験ポイント(Section 10 要点)

🔑 Cloud Run 試験ポイント
  • CPU allocation の 2 モードthrottled(request-based, デフォルト) vs always allocated(常時課金、WebSocket / 背景処理用)
  • concurrency は I/O bound = 80(max)、CPU bound = 8-16。1 のままだと最大 80 倍のコスト
  • min-instances=0 がデフォルト・推奨。SLO 厳しいときのみ 1-2、全 service で >0 は禁忌
  • CPU boost は gen2 のみ、cold start 50% 短縮、コスト影響は startup 数秒のみ
  • Free tier:月 180,000 vCPU-秒 + 360,000 GiB-秒 + 200 万 requests(request-based のみ対象)
  • VPC アクセスは gen2 + Direct VPC egress 推奨、Serverless VPC Connector は idle でも min 2 instance 課金
  • Secret は version pin(latest 禁止)、rotation 時は両 version enable
  • Cloud Run service の request timeout は最大 60 分、Cloud Run Jobs の task timeout は最大 24 時間
  • gen1 vs gen2 の挙動差異(filesystem、syscall、size limit、streaming)を採用前に確認
  • retry と冪等性は必ずセット、Cloud Run Jobs の --max-retries は冪等性前提で有効化
  • blue-green / canary は revision tag + traffic splitting で簡単実現
  • HPA に相当する scale は自動、request rate ベース。手動制御は --max-instances のみ