Kubernetesコスト最適化の実務:FinOps視点で無駄を可視化し、性能を落とさず削減する方法

Kubernetes を導入した直後は「自動で効率化される」と期待されがちですが、実際には逆です。適切な運用ルールがないと、クラウド請求は静かに膨らみ続けます。

典型例は次の通りです。

  • リクエスト/リミットが過大でノードが常時スカスカ
  • 夜間トラフィック減少時も同じ台数を維持
  • 開発環境が週末ずっと起動
  • HPA が CPU しか見ておらず、キュー滞留を無視
  • 過剰なストレージクラス(IOPS課金)を全環境で使用

本記事では、FinOps の考え方を用いて、Kubernetesコストを「見える化→改善→定着」の順に進める方法を解説します。

コスト削減の前に定義すべき指標

削減施策が失敗する理由は、目標が「安くする」しかないからです。最低でも次の 4 指標を定義します。

  1. Unit Cost: 1リクエストあたりコスト / 1ジョブあたりコスト
  2. Utilization: CPU・Memoryの実効使用率
  3. Reliability: SLO 達成率(削減で品質を落とさない)
  4. Waste Ratio: 予約/実使用の差分率

この4つを同時に追うと、単なるコストカットでなく「健全な最適化」になります。

ステップ1:可視化基盤を整える

1-1. Kubecost または OpenCost の導入

EKS/GKE/AKS いずれでも、namespace / deployment / label 単位で費用を把握できる状態にします。重要なのは team, service, env ラベルを強制することです。

推奨ラベル:

  • cost-center
  • owner
  • environment(prod/stg/dev)
  • criticality

ラベルがないと請求分析ができず、改善責任が曖昧になります。

1-2. 観測ダッシュボード

最初のダッシュボードは次を必須にします。

  • Namespace別コスト(当日/前日比)
  • Pod別 request/usage ギャップ
  • ノード空き率(CPU、Memory)
  • 時間帯別トラフィックとレプリカ数

ここまでで「どこが高いか」は見えます。次は「なぜ高いか」を潰します。

ステップ2:最も効果が高い改善施策

2-1. Right Sizing(最優先)

多くの環境で最大効果が出るのは request/limit の見直しです。VPA recommendation を参考に、まずは read-only で 2 週間観測します。

例:

  • 現在: requests.cpu=1000m, 実使用 P95 が 220m
  • 改善後: requests.cpu=300m

この1変更だけでノード数が 20〜35% 下がるケースがあります。

2-2. Cluster Autoscaler / Karpenter 最適化

オートスケーラーを入れていても、設定不備で縮退しないことが多いです。次をチェックします。

  • scale down unneeded time が長すぎないか
  • pod disruption budget が硬すぎないか
  • daemonset が過剰にリソースを固定していないか

Karpenter なら Spot + On-Demand の比率制御を導入し、重要ワークロードのみ On-Demand 固定にします。

2-3. ワークロードの時間制御

開発・検証環境はスケジュール停止が有効です。平日 9:00-20:00 だけ稼働し、夜間/休日は scale to zero。

1
2
# 例: CronJobで夜間停止
kubectl scale deployment api-staging --replicas=0 -n staging

単純ですが、月額で大きく効きます。

2-4. HPA指標の改善

CPU のみでスケールすると、I/O 待ちやキュー詰まりを見逃します。Prometheus Adapter を使い、次の指標を追加します。

  • queue length
  • request latency P95
  • in-flight request

結果として「必要な時だけ増やす」が実現し、過剰常時稼働を減らせます。

ステップ3:ストレージ/ネットワークの見直し

ストレージ

高IOPSディスクを全環境に使うのは典型的な浪費です。ワークロード特性でクラス分離します。

  • DB本番: 高IOPS
  • バッチ/開発: 標準クラス

スナップショット保持期間も要確認です。無制限保持は請求を圧迫します。

ネットワーク

クロスAZ通信量は見落とされがちです。チャットAPIや内部gRPCが高頻度だと、トラフィック課金が無視できません。依存サービスを同一AZに寄せる設計を検討します。

ガードレールを仕組み化する

最適化は一度で終わりません。再び膨らむので、CI/CD に制約を組み込みます。

  • OPA/Gatekeeper で「requests未設定」を拒否
  • ラベル欠落 (owner, cost-center) の manifest を reject
  • 予算超過 namespace の新規デプロイを警告

さらに、週次で「Top Waste 10」を自動配信し、チームごとに改善オーナーを固定します。

実例:3か月で 32% 削減した手順

ある SaaS 環境(5クラスタ)で実施した順序は次の通りです。

  1. 2週間の使用実績を収集
  2. 上位20 deployment の rightsizing
  3. staging/dev の時間停止
  4. Spot 比率を 15% → 45% へ引き上げ
  5. 高コストPVの棚卸し

結果:

  • 月次コスト: -32%
  • P95 レイテンシ: ほぼ維持
  • インシデント増加: なし

ポイントは、SLO を維持しながら段階実施したことです。

よくある反論への回答

Q. 削減すると障害が増えるのでは? A. いきなり下げると危険です。P95実績を基準に 10〜15% ずつ下げ、SLO と同時監視すれば安全に進められます。

Q. チームが協力しない A. コストを「共通責任」にすると進みません。namespaceごとに owner を明示し、改善期限を決めると動きます。

Q. どこから始めるべき? A. Right Sizing と夜間停止です。最短で効果が出ます。

まとめ

Kubernetes コスト最適化は、節約テクニックの寄せ集めではありません。計測、改善、運用ガードレールをセットで回す FinOps プロセスです。

まずは「誰の、どのワークロードが、なぜ高いか」を可視化し、Right Sizing から着手してください。性能を落とさずにコストを下げる道筋は、思っているより現実的です。

実装テンプレート:無駄を自動検出する

可視化だけだと改善は進みません。週次で自動的に「無駄候補」を抽出してチームへ配信する仕組みを入れると、改善が継続します。

抽出ルール例:

  • 7日平均で CPU 使用率 < 15% かつ request > 500m
  • 夜間(0:00-6:00)にトラフィックほぼゼロなのに replicas > 1
  • メモリ使用率 P95 < 40% が 14 日継続

このルールで候補を Slack/Discord に自動投稿し、オーナーと期限を付けるだけで改善率が上がります。

具体的なYAML見直し例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
resources:
  requests:
    cpu: "250m"
    memory: "512Mi"
  limits:
    cpu: "500m"
    memory: "1Gi"

autoscaling:
  minReplicas: 1
  maxReplicas: 8
  targetCPUUtilizationPercentage: 65

ポイントは「requests を現実に寄せる」「limits を安全マージンに置く」「HPA で不足分だけ増やす」の3点です。

ガバナンス:コストを技術負債化させない

削減施策は放置すると必ず戻ります。そこで、リリースゲートに FinOps 観点を追加します。

  • 新規サービスは cost label 必須
  • request 未設定の Pod はデプロイ拒否
  • 予算超過時は自動で注意喚起

さらに月次レビューで「削減額」だけでなく「SLO維持率」も一緒に報告することで、コスト最適化が品質改善と対立しない文化を作れます。

まとめ(実行順の再確認)

  1. まず可視化(誰が何にいくら使っているか)
  2. 次に Right Sizing と時間停止
  3. 最後にガードレールをCI/CDに組み込む

この順番を守れば、短期の削減成果と中長期の運用安定を両立できます。