Resource Quota
Kubernetes の Namespace ごとに CPU / メモリ / オブジェクト数の上限を定め、1 つのチームがクラスターを占有するのを防ぐ仕組み
Resource Quota とは
Resource Quota は、Kubernetes の Namespace ごとに CPU、メモリ、Pod 数などのリソース使用量の上限を設定するリソースである。マルチテナント環境で、1 つのチームやアプリケーションがクラスター全体のリソースを占有するのを防ぐ。
物理的なサーバーリソースは有限だ。Resource Quota がなければ、あるチームのバッチ処理が CPU を 100% 消費し、他チームのサービスが応答不能になる事態が起こりうる。
効くのは作成・更新のリクエストが API サーバーを通る瞬間だけである。ResourceQuota アドミッションプラグインが有効で、かつその Namespace に ResourceQuota オブジェクトが置かれているときに集計が始まり、枠を超える要求は 403 Forbidden として、どの制約に触れたかを添えて拒否される。裏を返せば、既に存在するリソースには遡及しない。Pod を作った後で Quota を作っても、枠を後からきつくしても、動いている Pod が追い出されることはなく、使用量が上限を超えたまま表示され続ける。既存クラスターへ入れるときは、まず現在の使用量を測ってから、それを包む値で枠を切るのが安全な順序だ。
Resource Quota の設定例
チーム単位で枠を切るときは、CPU とメモリの requests・limits、それに Pod や Service のようなオブジェクト数を 1 つの ResourceQuota にまとめて書く。
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "10" # CPU リクエストの合計上限: 10 コア
requests.memory: 20Gi # メモリリクエストの合計上限: 20GiB
limits.cpu: "20" # CPU リミットの合計上限: 20 コア
limits.memory: 40Gi # メモリリミットの合計上限: 40GiB
pods: "50" # Pod 数の上限
services: "10" # Service 数の上限
persistentvolumeclaims: "5" # PVC 数の上限
この設定では、team-a Namespace 内の全 Pod の CPU リクエスト合計が 10 コアを超える Pod の作成は拒否される。集計に入るのは非終了状態の Pod だけで、status.phase が Succeeded または Failed になった Pod は枠を返す。requests.cpu は cpu、requests.memory は memory と書いても同じ意味になる。
services や persistentvolumeclaims のように専用の名前が用意されていない種類は、count/deployments.apps のように count/<リソース>.<API グループ> の形で数を絞れる (コア API グループのものは count/pods のようにグループ名を省く)。この形は容量というより制御プレーンの保護に効く。Secret を無制限に作らせるとその大きさで API サーバーやコントローラーの起動を妨げうるし、設定を誤った CronJob が Job を作り続ける事故も、count/jobs.batch で頭を押さえられる。
対象を絞りたい場合は scopes / scopeSelector を併用する。Kubernetes 1.36 のドキュメント時点で使えるのは BestEffort、NotBestEffort、spec.activeDeadlineSeconds が設定されている Pod に当たる Terminating とその補集合の NotTerminating、指定した PriorityClass を参照する Pod に当たる PriorityClass、名前空間をまたぐ Pod アフィニティを持つ Pod に当たる CrossNamespacePodAffinity、それに PersistentVolumeClaim 向けの VolumeAttributesClass である。「本番の優先度クラスにだけ厚い枠を与える」といった書き分けができる。
Resource Quota と LimitRange の違い
この 2 つは混同されやすいが、制御の粒度が異なる。
| 観点 | Resource Quota | LimitRange |
|---|---|---|
| 制御対象 | Namespace 全体の合計 | 個々の Pod / Container |
| 役割 | チーム全体のリソース上限 | 1 つの Pod が使えるリソースの範囲 |
| 設定例 | 「Namespace 全体で CPU 10 コアまで」 | 「1 Pod あたり CPU 最大 2 コア」 |
| デフォルト値 | 設定不可 | Pod にデフォルトの requests/limits を付与 |
実務では両方を組み合わせて使う。Resource Quota で Namespace 全体の枠を決め、LimitRange で個々の Pod のデフォルト値と上限を設定する。
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-a
spec:
limits:
- default: # limits のデフォルト値
cpu: "500m"
memory: 512Mi
defaultRequest: # requests のデフォルト値
cpu: "100m"
memory: 128Mi
max: # 1 Container の上限
cpu: "2"
memory: 2Gi
type: Container
Resource Quota が必要になる場面
- マルチテナントクラスター: 複数チームが 1 つのクラスターを共有する場合、チームごとに Namespace を分け、Quota でリソースを公平に配分する
- 開発環境のコスト制御: 開発環境で無制限にリソースを使われると、クラスターのコストが膨らむ。Quota で上限を設けて抑制する
- 暴走 Pod の防止: バグで無限にレプリカが増える Pod がクラスター全体を圧迫するのを防ぐ
実務での設計指針
リソース配分の考え方
クラスター全体のリソースを 100% として、各 Namespace に配分する。
クラスター全体: CPU 100 コア, メモリ 400GiB
├── team-a (本番サービス): CPU 40, メモリ 160GiB (40%)
├── team-b (本番サービス): CPU 30, メモリ 120GiB (30%)
├── team-c (バッチ処理): CPU 20, メモリ 80GiB (20%)
└── 予備 (バースト用): CPU 10, メモリ 40GiB (10%)
ただし Quota はクラスター容量と連動しない絶対値の枠にすぎない。ノードを足しても各 Namespace の枠は自動では広がらず、逆に枠の合計が容量を超えていても Quota 自体は何も文句を言わない。足りなくなるのは実際にスケジュールされる段階で、そこから先は先着順の取り合いになり、後から要求した Pod は Pending のまま残る。ノードを増やしたら枠も引き上げる、という手当てが別途必要になる。
だから合計を 100% にせず、10〜20% の予備を残すのがポイントだ。予備がないと、バースト時に一時的に枠を広げる余地すら無くなる。
環境ごとの Quota 設計
| 環境 | CPU requests | メモリ requests | Pod 数 |
|---|---|---|---|
| prod | 40 コア | 160GiB | 200 |
| stg | 10 コア | 40GiB | 50 |
| dev | 5 コア | 20GiB | 30 |
開発環境は本番の 1/8 程度に抑え、コストを最適化する。
よくある落とし穴
- requests/limits の指定漏れ:
cpuとmemoryについては、Quota を置いた Namespace で requests か limits のどちらも書いていない Pod は admission で弾かれる。一方で ephemeral-storage やオブジェクト数の Quota は、指定の無い Pod をそのまま通す。「Quota さえ置けば全リソースで指定を強制できる」わけではないので、指定漏れそのものを無くしたいなら LimitRange で既定値を与える - 拒否が Pod の作成エラーとして見えない: 実務で人が作るのは Deployment であって Pod ではない。枠を超える Deployment の作成自体は成功し、その後 ReplicaSet が Pod を作れずに 403 を受け取る。
kubectl applyは通ったのにレプリカが揃わない、という形で現れるため、kubectl describe deploymentやkubectl describe replicasetのイベントまで降りないと原因に届かない - Quota の過小設定: 通常時は問題なくても、デプロイ時に新旧 Pod が同時に存在する (Rolling Update) ため、一時的にリソース使用量が増える。デプロイ時のオーバーヘッドを考慮した余裕が必要
- 監視の欠如: Quota の使用率を見ていないと、上限に近づいていることに気づかず、ある日突然 Pod が作れなくなる。kube-state-metrics が出す
kube_resourcequotaは、同じresourceラベルに対してtype="hard"とtype="used"の 2 系列を返すので、used を hard で割った比率でアラートを組める。kubectl describe quotaでも Used と Hard が並ぶが、これは詰まってから見るものなので、常時監視は前者に寄せる
Kubernetes 公式ドキュメントの「Resource Quotas」セクションが一次情報源であり、「Kubernetes in Action」(Marko Lukša 著) でも詳しく解説されている。対象にできるリソース名の一覧や scope の種類は版ごとに増えるため、枠を設計する前に使用中のバージョンのドキュメントで確かめるのが確実だ。
この記事は役に立ちましたか?
関連用語
Kubernetes
コンテナのデプロイ、スケーリング、管理を自動化するオープンソースのオーケストレーションプラットフォーム
Namespace 分離
Kubernetes の Namespace を使ってリソース、ネットワーク、権限を論理的に分離するマルチテナント戦略
マルチテナンシー
1 つのシステムで複数のテナント (顧客) のデータを安全に分離して提供するアーキテクチャ
Horizontal Pod Autoscaler
Kubernetes で Pod のレプリカ数を CPU 使用率やカスタムメトリクスに基づいて自動調整する仕組み
Kubernetes サービスアカウント
Pod に割り当てる ID で、RBAC と連携して Pod の API アクセス権限を制御する
Pod Disruption Budget (PDB) とは - Kubernetes の可用性を守る設定方法
PDB は Kubernetes でノードメンテナンス時に同時停止できる Pod 数を制限するリソース。maxUnavailable と minAvailable の使い分け / YAML 設定例を解説
関連する記事
インフラ / クラウド本ガイド - AWS や Docker を本で学ぶ
クラウドインフラ、コンテナ、IaC を学べる技術書の選び方と学習順序を紹介。インフラ本の賞味期限問題と公式ドキュメントとの使い分けも解説します。
技術書の情報が古くなったときの対処法
技術書の内容が古くなったときの対処法を紹介。古くなる部分と古くならない部分の見分け方、購入前の鮮度チェック方法を解説します。
AWS 本の選び方 - 全体像 / 構築 / 設計 / 運用 / セキュリティの 5 視点
AWS を学ぶ技術書の選び方を「全体像 / 構築 / 設計 / 運用 / セキュリティ」の 5 視点で整理。公式ドキュメントと本の役割分担、資格対策書の位置づけまで、2026 年 8 月時点の定番書で AWS 独学のルートを解説します。