第3回でクラスタの形が決まりました。次に決めるのは、そのクラスタに何台のノードをどう供給するか、そしてそのコストを誰にどう帰属させるかです。
コスト最適化には複数の手段がありますが、どれも無料ではありません。Spot VMは安い代わりに中断されます。確約利用割引は安い代わりに期間を縛られます。ResourceQuotaは事故を防ぐ代わりに、厳しすぎれば開発を止めます。本記事では、どの手段がいくら効き、その代償として何を失うかを数値で対比します。
本記事も第1回以降と同様、Google Cloud(GKE)を前提に数値と製品名を記載します。
目次
第3回で決めた上限が、この設計の入力になる
オートスケーリングの設計は、IPアドレスの上限を確認するところから始めます。ここを飛ばすと、設定した最大ノード数が机上の数字で終わります。
第3回で決めた2つの値を、まず手元に出してください。
- max Pods per node(クラスタまたはノードプールの作成後は変更できない値)
- Podセカンダリ範囲のサイズから導かれる最大ノード数
オートスケーラーに設定する最大ノード数が、この上限を超えていないかを確認します。超えている場合、その設定は実行されません。
事故の現れ方は分かりにくい形を取ります。オートスケーラーがノードを増やそうとしても増えず、PodはPendingのまま残ります。マシンタイプにもクォータにも余裕があるため、原因の特定に時間がかかります。そしてこれは負荷が高まった日、つまり最もスケールしてほしい日に起きます。
上限を超えていた場合の対処は、Podセカンダリ範囲を広げるか、max Pods per nodeを下げるかのどちらかです。後者はクラスタまたはノードプールの作り直しを意味します。つまりこれは第4回で解決できる問題ではなく、第3回に戻る話になります。だからこそ最初に確認します。
Spot VM を本番で使えるかは「15秒」で決まる
Spot VMは本番環境でも使えます。ただし、乗せてよいワークロードを正しく仕分けた場合に限ります。仕分けの基準は割引率ではなく、猶予時間です。
割引率は確かに大きい
Spotの料金は動的で最大30日に1回変化しますが、CPU・メモリ・GPUについて通常価格に対して常に60〜91%の割引が提供されます。下限が60%として保証されているため、価格が動いても見積もりの前提は崩れません。
Autopilotの汎用ワークロードを例に取ると、以下の単価になります。
| 項目 | 通常 | Spot | 割引率 |
|---|---|---|---|
| vCPU(1時間あたり) | $0.0445 | $0.0133 | 約70% |
| メモリ(1GiB・1時間あたり) | $0.0049225 | $0.0014767 | 約70% |
単純計算で、Spotに載せられた分のコンピューティング費用は3分の1以下になります。第1回で試算したK8s税のうち、変動費であるノード費用に直接効きます。
しかしアプリケーションPodに与えられる猶予は15秒
ここが本記事で最も重要な数値です。
GKEクラスタのデフォルトでは、プリエンプション通知からPodのシャットダウンまでの正常終了期間は30秒です。ただし、この30秒は分割されています。
- 通常のPodのシャットダウンに15秒
- その後、システムPod(
priorityClassがsystem-cluster-criticalまたはsystem-node-criticalのもの)のシャットダウンに15秒
アプリケーションのPodに実際に与えられるのは15秒です。「Spot VMの猶予は30秒」という理解で設計すると、想定の半分の時間で切られます。
第1回の条件2で述べたとおり、terminationGracePeriodSecondsをどれだけ延ばしてもこの猶予は超えられません。Kubernetesの設定はゲストOSの中の話であり、その外側で電源が落ちるためです。
正常終了期間を120秒へ延長する構成もありますが、制約が3つ重なります。
- 執筆時点でプレビュー版です
- コントロールプレーンが一定バージョン以上(GKE 1.35.0-gke.1171000以降)である必要があります
- Standardモードでのみサポートされます。ノードシステム構成をカスタマイズして特定のノードプールに設定する形のため、Autopilotでは選択できません
Autopilotを選んでいる組織は、この延長を使えません。15秒が動かせない前提として設計に入ります。
15秒で仕分けるワークロード3分類
設計の順序を間違えないでください。「Spot比率を何%にするか」から入ってはいけません。まずワークロードを以下の3分類に仕分け、乗せてよいものの合計が結果として比率になる、という順序で決めます。

| 分類 | 該当するワークロード | 判定の根拠 |
|---|---|---|
| 乗せてよい | ステートレスなWeb API / リトライ前提の非同期ワーカー / CI・CDのビルドジョブ / 開発環境全般 | 処理中のリクエストを15秒以内に返し切れる。あるいは中断されても上位のリトライで吸収できる |
| 条件付き | キュー消費型のワーカー | 1メッセージの処理が15秒以内に完了し、かつ冪等であること。この2つが揃わなければ「乗せてはいけない」に落とす |
| 乗せてはいけない | 長時間バッチ / 大容量ファイルのアップロード受信 / 非冪等な決済・在庫処理 / シングルトン処理 | 第1回の条件2(Graceful Shutdown不耐性)と条件3(水平分散不可)に該当するもの全般 |
この表を見て気づくとおり、Spotに乗せられるかどうかの判定基準は、第1回でK8s自体の採否を判定した基準とほぼ同じです。第1回の条件2に該当してK8sから外したワークロードは、そもそもこの表に登場しません。第1回で「非該当」と判定して残ったワークロードの中を、もう一段細かく仕分けているのがこの表です。
仕分けの結果、「乗せてよい」が全体の何割を占めるかが、そのままSpot比率の上限になります。ここで出た数字が想定より小さくても、それが実態です。無理に比率を上げると、中断のたびに処理が壊れます。
Spotを使う場合の構成上の注意
Spot VMのノードにはtaintが付き、Podにはtolerationが必要です。Autopilotの場合はこの手当てが不要になります。Spot Podをリクエストすると、AutopilotがSpot VMのプロビジョニング、taintとtolerationの付与、自動スケーリングとスケジュール設定をまとめて管理します。
可用性についても設計上の指針があります。Googleは小さなマシンタイプを使うほうがSpotの可用性が上がると明記しています。大きなインスタンスをまとめて確保する構成は、回収の対象になりやすく、確保もしにくくなります。1ノードあたりのサイズを小さくして台数を増やす方向が、Spot利用時には有利に働きます。
ただしこの判断は、第3回のIPアドレス計画と衝突する可能性があります。ノードの台数を増やす方向は、Podセカンダリ範囲の消費を増やす方向です。小さいマシンタイプで台数を増やす設計を採るなら、max Pods per nodeも小さくして1ノードあたりのCIDR消費を抑える必要があります。この2つはセットで決めてください。
Standardクラスタで混在させる場合は、Spotノードプールとオンデマンドノードプールを併存させ、可用性が要るワークロードにはtolerationを付けないことでオンデマンド側に寄せます。ノードプールを跨いだ分散の設計(topologySpreadConstraints)は第11回で扱います。
コスト按分に、まず別ツールは要らない
第1回のヒアリング①で「コスト按分が必要」と確定した場合、Namespaceやチーム単位でコストを見る仕組みが要ります。ここで外部ツールの導入から検討を始める必要はありません。
GKEの費用の割り当て
GKEには費用の割り当て(cost allocation)という機能があります。有効にすると、Cloud Billingのコンソールと、詳細なBigQueryエクスポートで、クラスタの費用データを表示できます。Namespaceやラベル単位での内訳が、請求データそのものの中に入ります。
この機能には、押さえておくべき性質が2つあります。
1つ目。有効にしてもGKEの合計費用は変わりません。エクスポートの費目の合計は同じで、既存のクエリとレポートは同じ値を返します。増えるのは按分の粒度だけです。請求額が変わるものではないため、有効化そのものにコスト面の懸念はありません。
2つ目。ただしBigQueryのストレージとクエリの費用は増える可能性があります。そして増加額は、Podとクラスタ間で使う個別のラベルとNamespaceの組み合わせの数に依存します。
ここに設計上の含意があります。「とりあえず全部にラベルを付ける」という設計は、按分するためのコストを増やします。組み合わせの数がそのまま行数になるためです。
ラベリングは按分の単位から逆算する
したがって、ラベル設計は次の順序で行います。
- 按分の単位を先に決める(部門 / チーム / サービス / 環境のどれか、あるいはその組み合わせ)
- その単位を表現するために必要最小限のラベルだけを必須にする
- あれば便利という程度のラベルは、必須にせず任意にする
第1回のヒアリング①で「按分は不要」と確定している場合、この機能自体を有効にしないという判断もあります。按分の要件がないのにラベル設計とBigQueryのコストを負担する理由はありません。第1回で按分の要否を最初に確認させたのは、この判断を後回しにしないためです。
なお、ラベルを誰が付けるか(開発チーム)と、付いていないものを誰が弾くか(運用チーム)は第2回のRACIで決めた話です。付いていないワークロードを実際に拒否する仕組み(ポリシーエンジンによる強制)は第5回で扱います。第2回で「誰が」、本記事で「何を」、第5回で「どう強制するか」を決める、という3回にまたがる流れになります。
別ツールを検討する条件
組み込み機能で足りないのは、以下のような要件がある場合に限られます。
- 複数のクラウドをまたいだ按分が必要
- GKE以外のリソースと統合したチャージバックの仕組みが必要
- 請求データの反映を待てず、リアルタイムに近い粒度での可視化が必要
いずれにも該当しないのであれば、組み込み機能で足ります。ツールを選定する理由そのものは第6回のADRで扱います。
ResourceQuota は「開発を止めない上限」から設計する
ResourceQuotaの目的を取り違えないでください。節約のための仕組みではなく、1つのNamespaceがクラスタ全体を食い潰すのを防ぐための仕組みです。
ResourceQuota と LimitRange の役割分担
2つは別の階層を担当します。
| 仕組み | 対象の階層 | 役割 |
|---|---|---|
| ResourceQuota | Namespace全体 | そのNamespaceが要求できるCPU・メモリの総量の上限 |
| LimitRange | Pod / コンテナ単位 | 個々のコンテナのデフォルト値と上下限 |
第2回のグレーゾーン1で「値は開発が決め、範囲は運用が縛る」という分解をしました。このセクションが、その「範囲を縛る」側の実装です。個々のPodにいくつの値を入れるかという算出方法論は第11回で扱います。
LimitRangeにはもう1つ役割があります。第2回で述べたとおり、RequestsもLimitsも設定されていないPodはQoSクラスがBestEffortになり、Eviction時に最初に停止させられます。LimitRangeでデフォルト値を設定しておけば、設定漏れのPodがBestEffortに落ちること自体を防げます。
初期値は観測してから決める
いきなり厳しい値を入れないでください。開発を止めるQuotaは、運用開始後すぐに例外申請で穴だらけになります。穴だらけになったQuotaは、設定されていないのと同じです。
順序としては、まず観測期間を設けます。その間の実測のピークに一定の余裕を乗せた値を初期値とし、そこから徐々に締めていきます。例外申請のプロセスは第2回の責任境界定義書で定義したものを使います。例外に有効期限を設けるという設計も、第2回で決めた内容です。
見直しの周期も決めてください。第2回で責任境界定義書に四半期ごとの見直しを設定したのと同様、Quotaの値も陳腐化します。
CPUとメモリだけを縛っても足りない
ResourceQuotaで制限できるのはCPUとメモリだけではありません。実務で事故につながるのは、むしろ数を制限していない項目です。
| 制限する対象 | 制限しないと起きること |
|---|---|
| CPU / メモリのrequests合計 | スケジューラが確保する総量が青天井になり、他のNamespaceのPodが配置できなくなります |
| CPU / メモリのlimits合計 | 実使用がノードの容量を超え、Evictionが多発します。requestsだけを縛ってlimitsを放置する設計は片手落ちです |
| Podの個数 | 設定ミスや暴走したコントローラーが小さなPodを大量に作り、CPUやメモリの上限に達する前にスケジューラを圧迫します |
| PersistentVolumeClaimの個数と要求容量 | ストレージのコストは気づきにくい形で積み上がります。Podを消してもPVCが残る運用では、誰も使っていないディスクの料金を払い続けます |
| LoadBalancer型Serviceの個数 | Serviceを作るたびに転送ルールの課金が発生します。第3回で「公開単位ごとにロードバランサーを作らない」と述べた設計を、ここで数として強制できます |
特に最後の2つは、CPUとメモリの上限をいくら締めても防げません。コストの増え方には「計算資源として増える」経路と「個数として増える」経路があり、後者を止めるのがこの設定です。
Autopilot では意味合いが変わる
Autopilotを選んでいる場合、この設計の前提が変わります。
AutopilotはPodのリソースリクエストの値を管理します。具体的には以下の動作をします。
- リクエストを指定していないコンテナには、Autopilotがデフォルト値を割り当てます
- リクエストが許容される最小値を下回る場合、Autopilotがワークロード構成を自動的に変更して許容範囲に収めます
- リクエストが最大値を超える場合、ワークロードは拒否されます
つまり、LimitRangeが担っていた役割の大部分を、Autopilotがプラットフォーム側で担っています。設定漏れのPodがBestEffortに落ちるという問題も、Autopilotでは起きません。
あわせて、Autopilotの課金はPodが要求したリソースに対するものであり、ノードの空き容量という概念が実質的にありません。したがってResourceQuotaの役割は「ノードの取り合いを防ぐ」から「部門ごとの支出上限を設ける」に変わります。
Autopilotでは要求したリソースがそのまま請求になるため、Quotaの値は技術的な上限ではなく予算そのものを表します。この違いを設計書に明記してください。同じResourceQuotaという仕組みでも、運用モードによって説明の仕方が変わります。
確約利用割引は「中断されない割引」
Spotが「使えるワークロードを選ぶ」手段だとすれば、確約利用割引(CUD)は「使う量を約束する」手段です。両者は排他ではありません。
購入できるのはコンピューティング フレキシブル CUD
ここで注意が必要です。GKE Autopilot CUD は購入できなくなりました。GKEの費用に対して購入できるのは、コンピューティング フレキシブル コミットメントのみです。既存のアクティブなAutopilotコミットメントは期間の終了まで引き続きサポートされますが、新規に購入することはできません。
古い資料を参照して設計している場合、この点が変わっている可能性があります。両者の条件を並べておきます。
| 項目 | コンピューティング フレキシブル CUD | GKE Autopilot CUD(購入不可) |
|---|---|---|
| 1年コミット | オンデマンド料金に対して28%割引 | 20%割引 |
| 3年コミット | 46%割引 | 45%割引 |
| 適用範囲 | Cloud請求先アカウントの任意のリージョンとプロジェクト | 特定のリージョン内のすべてのプロジェクト |
購入できる側のほうが割引率が高く、かつリージョンの制約もありません。現時点で新規に検討するなら、コンピューティング フレキシブル CUDが選択肢になります。
なお、GKE Standardクラスタの使用量に対しては、Compute Engineのリソースベースの確約利用割引という別の仕組みもあります。費用ベースのコミットメント(フレキシブルCUD)とリソースベースのコミットメントは性質が異なるため、どちらを使うかは自社の使用パターンで判断してください。
Spot と CUD の二層構成
割引率だけを比べれば、Spotの60〜91%に対してCUDは28〜46%です。しかしCUDは中断されません。この差が設計上の役割分担を決めます。
| 手段 | 割引 | 代償 | 適用する対象 |
|---|---|---|---|
| Spot VM | 60〜91% | 15秒で中断される。可用性は保証されない | 前述の3分類で「乗せてよい」と判定したワークロード |
| 確約利用割引 | 28%(1年) / 46%(3年) | 期間を縛られる。使い切れなくても支払う | 常時稼働するベースラインの使用量 |
基本形は、中断されては困るベースライン部分をCUDで押さえ、その上に乗る変動分をSpotで賄うという二層構成です。ベースラインをSpotで賄おうとすると中断のたびに可用性が落ち、変動分をCUDで押さえると使い切れないコミットが残ります。

コミット期間は第1回の投資回収期間と突き合わせる
1年や3年のコミットを結ぶ前に、2つ確認してください。
- 第1回で算出した投資回収期間の枠内に収まるか
- そのコミット期間中、そのシステムが存在し続ける見込みがあるか
3年コミットを結んだ半年後にシステムを畳む判断が出れば、割引どころか損失になります。第1回で投資回収期間が18ヶ月を超える場合はスコープの縮小を検討すべきと述べましたが、その判断とコミット期間の判断は連動します。
コミットする量にも上限があります。第3回で決めた最大ノード数が、そのまま長期のキャパシティ上限です。それを超える量をコミットしても、IPアドレスの制約でノードを増やせないため使い切れません。ここでも第3回の値が効いてきます。
長期のキャパシティプランニング
ここまでは「今の使用量をいくら安くするか」の話でした。最後に、いつ上限に当たるかを見積もります。
先に当たるのは、たいていIPアドレスの上限
キャパシティの上限というと、CPUやメモリのクォータを思い浮かべがちです。しかしGKEで先に当たるのは、多くの場合Podセカンダリ範囲から導かれる最大ノード数です。
第3回で述べたとおり、110 Pods/nodeの設定ではノード1台が/24を丸ごと消費します。/21のPodセカンダリ範囲なら8ノードで頭打ちです。CPUのクォータは申請すれば引き上げられますが、IPアドレスの上限はクラスタの作り直しでしか動きません。
したがって長期計画では、以下の順序で「いつ当たるか」を出します。
- 現在のノード数と、直近数ヶ月の増加ペースを実測する
- 事業計画上のトラフィック増加率と、移行予定のシステム数を加える
- そのペースで第3回の最大ノード数に到達する時期を算出する
- 到達時期がクラスタの想定寿命より前なら、その時点で対処を計画に載せる
到達時期が見えていれば、対処はクラスタの作り替えとして計画的に実行できます。第3回で予備のセカンダリ範囲を確保しておくよう述べたのは、このためです。予備を確保していないと、上限に当たった時点で隣接する空き範囲が取れず、選択肢が限られます。
CUDのコミット量は上限を超えられない
この上限は、確約利用割引の設計にも効きます。3年コミットを結ぶとき、その期間中に使うであろう量をコミットします。しかしコミット量が第3回の最大ノード数を超えていれば、その分は物理的に使えません。
使い切れないコミットは、割引ではなく純粋な損失です。コミット量を決める前に、第3回で算出した上限を確認してください。上限のほうが小さければ、コミット量はそれに合わせるか、先にクラスタの作り替えを計画するかのどちらかになります。
なお、ノードあたりのスペックを上げて台数を抑えるという対処もありますが、これはSpotの可用性を下げる方向(小さいマシンタイプのほうが有利)と衝突します。ノードのサイズは、IPアドレスの消費・Spotの可用性・キャパシティの上限という3つの要素が同時に効く設計項目です。どれか1つだけを見て決めないでください。
【実務テンプレート】FinOps・スケーリング設計書
ここまでの内容を統合したテンプレートです。セクション1は第3回の成果物から転記し、セクション3の仕分けを終えてからセクション4を埋めてください。
FinOps・スケーリング設計書
プロジェクト名: ________________
作成日: ____/____/____
作成者: ________________
承認者: ________________
セクション1: 第3回からの入力値(クラスタトポロジー設計書から転記)
max Pods per node: ______(作成後変更不可)
Podセカンダリ範囲: ______________
そこから導かれる最大ノード数: ______台
セクション2: オートスケーリング設定
最小ノード数: ______台
最大ノード数: ______台
確認: 最大ノード数 ≦ セクション1の上限か: [はい / いいえ]
いいえの場合の対処: [Podセカンダリ範囲を広げる / max Pods per node を下げる(作り直し) / 上限を下げる]
セクション3: Spot採否のワークロード仕分け
各ワークロードについて、最長処理時間と冪等性を記入して分類すること。
ワークロードA: ____________ / 最長処理時間____秒 / 冪等 [はい / いいえ] / 分類 [乗せてよい / 条件付き / 乗せてはいけない]
ワークロードB: ____________ / 最長処理時間____秒 / 冪等 [はい / いいえ] / 分類 [乗せてよい / 条件付き / 乗せてはいけない]
ワークロードC: ____________ / 最長処理時間____秒 / 冪等 [はい / いいえ] / 分類 [乗せてよい / 条件付き / 乗せてはいけない]
猶予時間の前提: [15秒(デフォルト) / 120秒(Standard・プレビュー構成を採用)]
セクション4: Spot / オンデマンドの構成
「乗せてよい」の合計が全体に占める割合: ____%
→ これが結果としてのSpot比率の上限
ノードプール構成: [Autopilot Spot Pod / Standard でSpotとオンデマンドを併存 / Spotを使わない]
マシンタイプ: ____________
※小さいマシンタイプほどSpotの可用性は上がるが、ノード台数が増えIP消費も増える
セクション5: コスト按分
按分の要否(第1回のヒアリング①より): [要 / 不要]
按分の単位: [部門 / チーム / サービス / 環境 / その他______]
GKE費用の割り当ての有効化: [する / しない]
必須ラベル一覧(最小限に絞ること): ______________________________
任意ラベル: ______________________________
ラベル未設定ワークロードの扱い: [拒否 / 警告のみ](強制の仕組みは第5回)
セクション6: ResourceQuota / LimitRange
運用モード: [Autopilot / Standard]
→ Autopilotの場合、Quotaの位置づけは「支出上限」
観測期間: ____週間(この期間の実測ピークを初期値の根拠にする)
Namespace A: requests CPU______ / requests メモリ______ / limits CPU______ / limits メモリ______
Pod個数上限______ / PVC個数______ / PVC要求容量______ / LoadBalancer型Service個数______
Namespace B: requests CPU______ / requests メモリ______ / limits CPU______ / limits メモリ______
Pod個数上限______ / PVC個数______ / PVC要求容量______ / LoadBalancer型Service個数______
LimitRangeのデフォルト値: CPU______ / メモリ______(Standardの場合)
見直し周期: ____ヶ月 / 次回見直し日____/____/____
セクション7: 確約利用割引
CUDの利用: [する / しない]
種別: [コンピューティング フレキシブル CUD / Compute Engine リソースベースCUD]
期間: [1年(28%) / 3年(46%)]
コミット量: ______
確認1: 第1回の投資回収期間(____ヶ月)の枠内か: [はい / いいえ]
確認2: コミット期間中にシステムが存続する見込みか: [はい / いいえ]
確認3: コミット量が第3回の最大ノード数の範囲内か: [はい / いいえ]
セクション8: 長期キャパシティプランニング
現在のノード数: ____台
直近の増加ペース: ____台/月
事業計画上の増加要因: ______________________________
第3回の最大ノード数に到達する見込み時期: ____年____月
クラスタの想定寿命との比較: [寿命内に到達する / しない]
到達する場合の対処と実施時期: ______________________________
予備セカンダリ範囲の確保状況(第3回より): [確保済 / 未確保]
次回予告
ノードの供給量とNamespaceごとの総量が決まりました。次に決めるのは、そのクラスタを誰から、何から守るかという設計です。
次回の第5回「ゼロトラスト・ガバナンス設計書」では、RBACの権限モデル設計、Workload Identityによるクラウド側のIAM連携、Pod Security Standardsの適用レベル、ポリシーエンジンのルール定義、NetworkPolicyによるPod間通信制御、そしてシークレット管理のアーキテクチャを扱います。
本記事で決めたラベリングルールは、第5回でポリシーエンジンによって強制する対象になります。第2回で「誰がラベルを付けるか」を決め、本記事で「何を付けるか」を決め、第5回で「付いていないものをどう弾くか」を設計する。この3回にまたがる流れで、ようやくコスト按分は運用に乗ります。ルールを決めただけでは、付け忘れたワークロードが按分から漏れ続けます。
