Contents
現状把握と最初の一手
まずは可視化に時間を割いてください。クラウド請求データとクラスタ内メトリクスを紐付けることで、改善候補が明確になります。初手は課金エクスポート有効化、メトリクス基盤の導入、ラベリングルールの整備です。
初手チェックリスト
ここで最初に確認・実施すべき項目を示します。各項目は最小権限や前提を満たしているかを確認してから進めてください。
- クラウド側:課金エクスポートを有効化する(AWS Cost & Usage Report / GCP Billing export / Azure Cost Management)。エクスポート先(S3 / BigQuery / Storage)と必要な権限(billing 関連のアカウント権限)を整備すること。
- クラスタ側:Prometheus(kube-state-metrics / node-exporter / cAdvisor 等)と Grafana を用意する。Prometheus のスクレイプ対象やラベル名は環境で差が出るため検証する。
- ラベルと命名規約:namespace / cost-center 等のラベル付けルールを定め、Gatekeeper 等で強制することを検討する。
- 可視化ツール:Kubecost(OSSコア+有償エンタープライズ)などを使うと請求と k8s リソースの結合が早い。代替として BigQuery や CUR を自前で結合する方法もある。各ツールは権限やライセンス、運用コストを確認すること。
- 権限・前提の確認:helm/tf/gsutil 等の CLI、kubeconfig、必要な IAM / RBAC 権限が揃っていることを確認する。導入用の YAML/Helm/TF は前提が整っていないと動作しないため、直接コピペせず前提を満たすこと。
測定(可視化)
正確な測定なしに改善は難しいです。ここでは導入上の前提、主要な指標、そして運用で使える安全な PromQL の例を示します。PromQL はラベル名やエクスポータの実装差に注意してください。
導入と前提条件
導入前に満たすべき前提を示します。コード例や Helm/Terraform 断片を使う前に必ず確認してください。
- Kubernetes クラスタと操作権限(少なくとも helm や CRD の適用ができる権限)。
- Helm 3 を利用する場合、クライアントのみでサーバ側コンポーネントは不要。ただし CRD や ClusterRole の適用が必要なチャートがあるため cluster-admin 権限が一時的に必要なケースがある。
- Terraform を使う場合、クラウドプロバイダの認証設定(プロバイダブロック、サービスアカウント/IAM ユーザ)と、EKS などの作成に必要な IAM ロールが事前に用意されていること。
- Kubecost 等でクラウド請求データと紐付ける場合、CUR や BigQuery へのアクセス権限を付与する必要がある。外部ツール導入に伴うライセンス・運用コストを評価すること。
主要指標と安全な PromQL 例
PromQL を使う際は exporter のラベル名差(container / container_name / name)や pause コンテナ混入に注意してください。以下は一般的なパターンと単位の解説です。
- 注意点(PromQL と単位)
- rate(container_cpu_usage_seconds_total[5m]) はカウンタの1秒あたりの増加量を返します。container_cpu_usage_seconds_total は累積 CPU 秒のカウンタなので、rate() の結果は「秒/秒」=「コア数(CPUコア)」を意味します。例えば 0.5 は 0.5 コア(=500 millicore)です。
- container_memory_working_set_bytes はバイト単位です。GiB に変換するには / (1024^3) を行います。
- kube_pod_container_resource_requests_cpu_cores などのリソース指標はコア単位で提供されることが多いです。
-
ラベル差異に注意し、まずは label_names や metrics を query で確認してください。
-
Pod 単位の CPU 使用量(5m 平均、pause コンテナと空名を除外)
|
1 2 3 4 |
sum by (namespace, pod) ( rate(container_cpu_usage_seconds_total{container!="POD", container!=""}[5m]) ) |
- Pod の CPU リクエストに対する利用率(requests が設定されている Pod のみで計算)
|
1 2 3 4 5 6 7 8 |
sum by (namespace, pod) ( rate(container_cpu_usage_seconds_total{container!="POD", container!=""}[5m]) ) / sum by (namespace, pod) ( kube_pod_container_resource_requests_cpu_cores ) |
-
分母に requests が存在しない場合は除外するか、PromQL のゼロ除算対策を入れてください(例: sum(...) > 0 を使ってフィルタ)。
-
メモリ使用量(Working Set、バイト)
|
1 2 |
sum by (namespace, pod) (container_memory_working_set_bytes{container!="POD", container!=""}) |
-
GiB 表示: (...)/ (1024^3)
-
ノード単位の割当率(CPU)
|
1 2 3 4 |
sum by (node) (rate(container_cpu_usage_seconds_total{container!="POD", container!=""}[5m])) / sum by (node) (kube_node_status_allocatable_cpu_cores) |
- 実運用での注意
- メトリクス名・ラベルは環境差があるため、最初に label_values() 等で確認すること。
- rate のウィンドウ(5m/1m/15m)は workload の特性に合わせて選ぶ。短すぎるとノイズ、長すぎるとピークを見逃す可能性がある。
分析と優先順位付け
見える化できたら浪費箇所を洗い出し、効果とリスクを元に実行順を決めます。小さな施策で検証を繰り返すことが重要です。優先順位基準はコスト影響・工数・可用性リスク・計測精度の4軸で評価します。
優先度付けの具体例
評価尺度の例と簡易スコア算出方法を示します。閾値や重みは組織に合わせて調整してください。
- cost_rank の目安(例、$/月)
| rank | コスト影響の目安($ / 月、例) |
|---|---|
| 5 | > 10,000 |
| 4 | 2,000 – 10,000 |
| 3 | 500 – 2,000 |
| 2 | 100 – 500 |
| 1 | < 100 |
- effort_rank の目安
| rank | 工数の目安 |
|---|---|
| 1 | <1日 |
| 2 | 1日〜3日 |
| 3 | 1〜2週間 |
| 4 | 数週間〜数ヶ月 |
| 5 | アーキテクチャ改修等 大規模 |
- risk_rank の目安(可用性/運用リスク: 1=低, 5=高)
スコア計算(推奨例)は以下です。effort と risk は「低いほど良い」ため反転して扱います。
score = 0.6 * cost_rank + 0.2 * (6 - effort_rank) + 0.2 * (6 - risk_rank)
- サンプル計算
-
施策A(開発環境のスケジュール停止):cost_rank=4, effort_rank=1, risk_rank=1
score = 0.64 + 0.2(5) + 0.2*(5) = 2.4 + 1.0 + 1.0 = 4.4(高優先度) -
施策B(ステートフル本番のスポット移行):cost_rank=5, effort_rank=4, risk_rank=5
score = 0.65 + 0.2(2) + 0.2*(1) = 3.0 + 0.4 + 0.2 = 3.6(要注意の上位)
コンプライアンスとセキュリティのチェックポイント
改善を行う際の監査・権限面の考慮事項を示します。運用や法務と連携してリスクを管理してください。
- ログ retention の短縮は規約や監査要件に抵触する場合があるので、保存期間とログ内容(監査ログなど)を明確に分離すること。
- IAM / RBAC の変更は監査ログと変更管理(チケット)を残すこと。権限削減で監視やバックアップが止まらないように検証する。
- Gatekeeper 等で Pod を拒否するポリシーを入れる場合は、ステージングで十分に検証してから本番に適用すること。
最適化:実践手順(ノード・Pod・ストレージ・ネットワーク)
小さく始めて効果を測ることを優先します。ここではノード運用、Pod のリソース最適化、ストレージ/ネットワークの改善について具体的な注意点と手順を示します。
ノード運用改善(Autoscaler/スポット)
ノード設計とスケーリング方針はコストに直結します。まずは小さなワークロードでパイロットを行ってください。
- 設計方針
- インスタンスタイプは CPU バウンド / メモリバウンドで分ける。
- critical / batch / spot 用にノードプールを分割し、taint/toleration や nodeSelector で振り分ける。
- スポット適用のリスクと対策
- 中断頻度はリージョン・インスタンスファミリー・需給で大きく変動するため、過去のスポット価格履歴やプロバイダのドキュメントで事前評価すること。
- 中断が発生した場合の再試行コストやデータ損失を見積もる。チェックポイント、ジョブ再試行、短時間に何度も再起動が発生する場合のコスト上積みを計算に入れる。
- 多様なインスタンスタイプを許容することで中断リスクを低減する(mixed instances)。
- ローカル PV を使用しているステートフルなワークロードはスポットに適さないか、別途対策が必要。
- min_size=0 の注意
- min_size=0 を設定すると、完全にゼロになった際のコールドスタート遅延やスケジューリング失敗リスクがある。重要なワークロードがあるノードプールは min_size を 1 以上にすることを推奨する。
-
スケールアップの所要時間(起動時間、イメージプル時間)を考慮し、バッファを残す設計にする。
-
Terraform 断片(例)と前提
- 下記は参考断片です。実運用では IAM ロール、インスタンスプロファイル、VPC/subnet、OIDC プロバイダなどを用意する必要があります。直接コピペせず前提を満たしてから利用してください。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
resource "aws_eks_node_group" "spot" { cluster_name = aws_eks_cluster.main.name node_group_name = "spot-ng" node_role_arn = aws_iam_role.node.arn # 事前に IAM ロールを作成してください subnet_ids = aws_subnet.private[*].id scaling_config { desired_size = 2 max_size = 10 min_size = 0 # 本番のクリティカルなプールでは 0 を避けることを推奨 } instance_types = ["m5.large", "m5a.large"] # 複数タイプを指定して多様化すること capacity_type = "SPOT" tags = { "k8s.io/cluster-autoscaler/enabled" = "true" } } |
Pod・ストレージ・ネットワークの最適化
Pod レベルでは requests/limits の適正化が最も効果的なことが多いです。ストレージやネットワークもまとめて最適化します。
- requests/limits の実務手順
- 収集: 過去 7/30/90 日の CPU/メモリ使用の時系列を取得する。
- 分析: p50/p95/p99 等のパーセンタイルを算出し、ワークロード特性に応じて requests を決める(開発環境は p50×1.1、ミッションクリティカルは p95×1.2 など運用方針で差を付ける)。
- 適用: 小さなバッチで適用し、SLO(Latency/Errors)を監視して横展開する。
- 自動化: VPA や Goldilocks 等で推奨値取得を自動化する。ただし VPA は Pod の再作成を伴うためステートフルなサービスでは注意が必要。
- HPA の注意点
- apiVersion や metrics API の有無を確認してから YAML を適用する。下位互換に注意する。
- ストレージ
- 不要な PV の削除、コールドデータのオブジェクトストレージ化、適切なストレージクラス(IOPS とコストのトレードオフ)を検討する。
- ネットワーク
- egress 削減は高い優先度。リージョン内通信・VPCエンドポイント・キャッシュの利用や LoadBalancer の集約(Ingress)で削減する。
- イメージ最適化
- マルチステージビルドや distroless ベースでイメージをスリム化し、プル時間とストレージを削減する。
|
1 2 3 4 5 6 7 8 9 |
FROM golang:1.20 AS builder WORKDIR /app COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o myapp ./cmd/myapp FROM gcr.io/distroless/static COPY --from=builder /app/myapp /myapp ENTRYPOINT ["/myapp"] |
自動化・ガバナンス
改善を一度だけで終わらせず、CI とポリシーで継続的にコスト管理を行います。ガードレール、アラート、PR 時のコスト差分確認を組み合わせます。
ガードレールとアラート
ガードレールは問題の予防に有効です。導入時は段階的に適用してください。
- 予算アラート:クラウドの予算機能や Kubecost のアラート機能で閾値を設定する。
- ポリシー制御:OPA/Gatekeeper で必須ラベルや requests 未設定の Pod を拒否する。Gatekeeper の導入には CRD と cluster-admin 権限が必要なので、まずステージングで検証すること。
- IaC による差分可視化:Infracost 等を PR チェックに組み込み、Terraform 変更時にコスト影響を表示する。Infracost や同類ツールは OSS と商用版があり、機能差や運用コストを比較して選定すること。
CI/CD とコスト検査
CI パイプラインにコスト審査を入れることで運用負荷を減らせます。
- PR 時にリソース要求の検査や LoadBalancer 作成の有無をチェックするルールを入れる。
- コスト関連の自動テストを段階的に導入し、誤ったリソース作成を未然に防ぐ。
- ツール選定はチームのスキル・ライセンス条件・サポート体制を考慮して行う。
クラウド別の実務ポイントとケーススタディ
クラウドごとに効果的な施策や注意点が異なります。ここでは代表的なポイントと簡易試算の前提を示します。各クラウドの仕様は頻繁に変わるため、公式ドキュメントを必ず確認してください(例: AWS EKS / GKE Autopilot / AKS の各公式ページ)。
プロバイダ別の差分(抜粋)
- EKS(AWS)
- NAT Gateway、ELB、EBS などの設計がコストに直結する。NAT Gateway の削減や VPC エンドポイント活用を検討する。
- スポット(EC2 Spot)とマネージドノードグループ、Karpenter の組合せが有効。Karpenter は起動柔軟性が高いが設定と権限が必要。
- GKE(GCP)
- Autopilot はノード管理負荷を下げるが課金モデルが異なるためワークロード特性で評価する。
- Preemptible VM はスポットに相当、バッチ処理に向く。
- AKS(Azure)
- VM スケールセット、スポット VM、Disk と Blob の使い分けでストレージ最適化を行う。
ケーススタディと数値例(前提明示)
以下は概算例です。金額・割合は地域・インスタンスタイプ・需給状況で変動します。必ず自組織の単価で再計算してください。
- ケース1:開発環境のスケールダウン
- 前提:常時 5 ノードを業務時間のみ 1 ノードに変更(1か月を720時間で計算)
- node_hours_before = 5 × 720 = 3600h
- node_hours_after = 1 × 720 = 720h
- 節約率 = (3600 - 720) / 3600 = 80%
-
備考:ノード単価はリージョン・タイプで変わる。永続的な最小容量や CI ジョブの突発負荷を考慮すること。
-
ケース2:バッチのスポット移行(概算)
- 前提:月間バッチ 2000 vCPU-hour、オンデマンドと比較して平均スポット価格が 30% の場合
- スポット節約率 = 1 - 0.30 = 70%(理論値)
-
注意:中断による再実行コストを考慮する。実効節約は中断率と再実行コストで低下する。
-
ケース3:ログ retention 短縮
- 前提:ログ 10 TB を 30日→7日に短縮
- 保持量削減 = 1 - 7/30 ≒ 76.7%
-
注意:監査や法令で一定期間の保持が必要な場合は対象データを分けて保持方針を決めること。
-
効果見積もりの簡易テンプレート(擬似)
- before_cost = node_hours_before * price_per_node_hour + storage_gb_before * price_per_gb_month + egress_before_gb * price_per_gb
- after_cost = node_hours_after * price_per_node_hour + storage_gb_after * price_per_gb_month + egress_after_gb * price_per_gb
- savings = before_cost - after_cost
まとめ
まず可視化を優先し、クラウド課金と k8s メトリクスを紐付けることが出発点です。測定→分析→小さな最適化→自動化の順で進め、各施策は必ず効果測定とリスク評価(コンプライアンス、可用性、再試行コスト)を行ってください。ツール選定は OSS と商用のトレードオフ、ライセンスと運用負荷を確認し、段階的に導入することを推奨します。