2026年7月29日

2026年7月29日

Kubernetesのコスト最適化のベストプラクティス|可視化・requestsの適正化・ノードの自動調整・見落としがちな費用

Kubernetesの費用を下げる近道は、ノードの台数を決めているのがPodの resources.requests だと理解し、実際の使用量に合わせて見直すことです。requests が過大なままでは、オートスケーラーを入れても空きの多いノードが増えるだけです。この記事では、費用を見える化する方法、requests の適正化、Podとノードの自動調整、スポットインスタンスの使い方、ストレージ・ネットワーク・ログのように見落としがちな費用、検証環境の止め方を、取り組む順番に沿って説明します。

具体的な料金はクラウドとリージョン、契約で変わるため、ここでは金額ではなく考え方と確認方法を扱います。ツールの機能や名称は執筆時点(2026年10月現在)の情報をもとにしているので、導入時は各公式ドキュメントで確認してください。

1. まず費用を見える化する

何にいくらかかっているかが分からないまま設定を変えると、効果を測れません。最初に、次の2つを分けて把握します。

  • クラスターの外の請求:ノードのインスタンス、コントロールプレーンの料金、ロードバランサー、ディスク、データ転送、NATゲートウェイなど。クラウドの請求画面とコスト分析の機能で、タグごとに集計します。
  • クラスターの中の内訳:どの名前空間・アプリがノードの容量をどれだけ使っているか。OpenCost(CNCFのプロジェクト)のようなツールで、Podの requests と実際の使用量をもとに費用を配分できます。

内訳を出すには、Podや名前空間に team や app のようなラベルをそろえて付けておく必要があります。ラベルが無いリソースは「誰のものか分からない費用」になり、削ってよいかの判断ができません。

実際の使用量は、metrics-server を入れていれば次のコマンドで確認できます。

kubectl top nodes
kubectl top pods -A --sort-by=memory

kubectl top はその瞬間の値です。requests を決めるには、Prometheusなどで数日から数週間の推移を見て、ピーク時の値も確認します。

2. requests を実際の使用量に合わせる

スケジューラーは、Podの requests の合計がノードの容量に収まるように配置します。実際の使用量が少なくても、requests が大きければノードは「満杯」と判断され、新しいノードが追加されます。費用の無駄が最も出やすいのがこの部分です。

見直しの目安は次のとおりです。

  • CPUの requests:普段の使用量より少し上に置く。CPUは足りなくなっても遅くなるだけで、Podは止まりません。
  • メモリの requests と limits:ピーク時の使用量に余裕を持たせる。メモリは limits を超えるとPodが強制終了(OOMKilled)されるため、削りすぎは障害につながります。
  • CPUの limits:付けると、余っているCPUがあっても使えず、応答が遅くなることがあります。付けるかどうかは、ほかのPodへの影響と遅延のどちらを重く見るかで決めます。

適正な値の見当をつけるには、Vertical Pod Autoscaler(VPA)を推奨値を出すだけのモードで動かす方法があります。

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: wordpress-vpa
  namespace: wordpress
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: wordpress
  updatePolicy:
    updateMode: "Off"   # 推奨値の算出のみ。Podは書き換えない

kubectl describe vpa wordpress-vpa -n wordpress で推奨値を確認し、マニフェストに反映します。VPAとHorizontal Pod Autoscaler(HPA)を同じCPUの指標で同時に動かすと、互いの調整がぶつかるため避けます。

名前空間ごとに上限を決めるには ResourceQuota、requests を書き忘れたPodに既定値を入れるには LimitRange を使います。チームごとに使える量の枠を決めておくと、費用の増え方が予測しやすくなります。

3. Podの台数を負荷に合わせる

アクセスに波があるアプリは、HPAで台数を増減させます。

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: wordpress
  namespace: wordpress
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: wordpress
  minReplicas: 2
  maxReplicas: 8
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

HPAのCPU使用率は requests に対する割合で計算されます。requests を見直した後でHPAの目標値も調整しないと、増減のタイミングがずれます。キューの長さなどで台数を決めたい場合や、夜間に0台まで減らしたい場合は、KEDAのようなイベント駆動のオートスケーラーが使えます。

WordPressの場合は、ページキャッシュやオブジェクトキャッシュを整えるとPodあたりのCPU使用量が減り、必要な台数そのものが下がります。インフラの設定より先に、アプリ側で処理を減らす余地がないかも確認してください。

4. ノードを自動で増減・詰め替える

Podの台数が減っても、ノードが減らなければ費用は下がりません。ノードの自動調整には、Cluster Autoscaler か、AWSなどで使われている Karpenter を使います。

  • Cluster Autoscaler:決めておいたノードグループの中で、置けないPodがあれば増やし、空いたノードを減らす。
  • Karpenter:待っているPodの requests に合わせて、インスタンスの種類を選んでノードを作る。使用率の低いノードのPodを寄せて、ノードを減らす(統合する)機能もある。

ノードが減らないときは、退避できないPodが残っていることが多いです。レプリカが1つでPodDisruptionBudgetが厳しいもの、ローカルストレージを使うもの、退避を禁止するアノテーションが付いたものがないかを確認します。

5. スポットインスタンスと購入オプション

スポットインスタンス(GCPではSpot VM)は、クラウドの余っている容量を安く使える代わりに、短い予告で回収されることがあります。止まっても作り直せば済むステートレスなアプリやバッチ処理に向いています。使うときの要点は次のとおりです。

  • 複数のインスタンスタイプとアベイラビリティーゾーンを候補にして、一度に回収されるのを避ける。
  • データベースのような状態を持つPodは、通常のノードに置く。taint と toleration、ノードのラベルで置き場所を分けます。
  • 回収の予告を受けて、Podを正しく退避させる仕組み(KarpenterやAWS Node Termination Handlerなど)を入れる。

常に動いている最低限の台数には、Savings Plans や予約インスタンス、確約利用割引のような長期の購入オプションが使えます。条件と割引の仕組みは各クラウドの説明を確認してください。ARM系のインスタンス(AWSのGravitonなど)が使えるなら、コンテナイメージをマルチアーキテクチャでビルドしておくと選択肢が広がります。

6. 見落としがちな費用

  • 使われていないディスク:PersistentVolumeClaim を消しても、回収ポリシーが Retain だとディスクは残ります。kubectl get pv で Released のものを確認し、不要ならバックアップを取ってから削除します。AWSのEBSなら、gp2より gp3 のほうが同じ性能を安く確保できる場合があります。
  • Serviceごとのロードバランサー:type: LoadBalancer のServiceを増やすと、その数だけロードバランサーが作られます。HTTPのアプリはIngressにまとめて1つのロードバランサーで受けます。
  • ゾーンをまたぐ通信とNAT:クラウドによっては、アベイラビリティーゾーン間の通信やNATゲートウェイを通る通信に料金がかかります。イメージの取得やクラウドのAPIへのアクセスがNAT経由になっていないかも確認します。
  • ログとメトリクス:ログの出しすぎや、ラベルの組み合わせが膨大なメトリクスは、監視サービスの費用を押し上げます。デバッグ用のログレベルのまま本番で動かしていないか確認します。

7. 使わない時間は止める

開発や検証のクラスターは、夜間や休日に台数を0にするだけで費用が下がります。CronJobで kubectl scale を実行する方法や、KEDAの時刻指定のスケーラーで台数を減らす方法があります。ノードのオートスケーラーと組み合わせれば、Podが減った分のノードも減ります。本番と同じ規模の検証環境が常に必要か、作業のときだけ作れば足りるかも見直す価値があります。

まとめ

  • 費用はクラスターの外(請求)と中(名前空間・アプリ)に分けて見える化し、ラベルをそろえる。
  • ノードの台数を決めるのは requests。VPAの推奨値と使用量の推移で見直し、メモリは削りすぎない。
  • HPAでPodを、Cluster AutoscalerやKarpenterでノードを増減させる。ノードが減らないときは退避できないPodを探す。
  • スポットはステートレスなアプリに限り、複数のタイプとゾーンに分散する。常時分は長期の購入オプションを検討する。
  • 残ったディスク、ロードバランサーの数、NATとゾーン間通信、ログの量を定期的に確認し、検証環境は使わない時間に止める。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲