Kubernetes ResourceQuota超過エラーの修正: pods is forbidden: exceeded quota

intermediate☸️ Kubernetes2026-03-22| Kubernetes 1.20以降、kubectl CLI、任意のクラウドプロバイダー(GKE、EKS、AKS)またはオンプレミスクラスター

Error Message

Error from server (Forbidden): pods "my-pod" is forbidden: exceeded quota: my-quota, requested: cpu=500m, used: cpu=900m, limited: cpu=1
#kubernetes#resourcequota#クォータ#ネームスペース#リソース制限

エラーの内容

Error from server (Forbidden): pods "my-pod" is forbidden: exceeded quota: my-quota, requested: cpu=500m, used: cpu=900m, limited: cpu=1

名前空間に ResourceQuota の上限が設定されており、このPodがその上限を超えてしまっています。エラーメッセージを見ると状況が明確です。クォータの上限は 1000m CPU で、すでに 900m が使用済み、さらに 500m を要求しているため、合計 1400m になります。Kubernetesはこのリクエストを即座に拒否します。

Podはペンディング状態にもなりません。スケジューラーが認識する前に、APIサーバーの段階でブロックされます。

ステップ1:現在のクォータ使用量を確認する

まず、何がどれだけ使用されており、何が許可されているかを正確に確認します。

# 'my-namespace' を実際の名前空間名に置き換えてください
kubectl describe resourcequota -n my-namespace

出力は以下のようになります。

Name:       my-quota
Namespace:  my-namespace
Resource    Used   Hard
--------    ----   ----
cpu         900m   1
memory      512Mi  2Gi
pods        8      10

CPUが問題の原因です。1000m のハード上限に対して 900m が使用されており、残りは 100m しかなく、500m を要求するPodには到底足りません。

すべての名前空間のクォータを一度に確認するには、以下を実行します。

kubectl get resourcequota --all-namespaces

ステップ2:クォータを消費しているリソースを特定する

何かを変更する前に、どのPodが 900m を消費しているかを特定します。

kubectl get pods -n my-namespace -o custom-columns=NAME:.metadata.name,CPU:.spec.containers[*].resources.requests.cpu

metrics-serverがインストールされている場合、kubectl top を使うと宣言されたリクエストではなく実際の使用量を確認できます。

kubectl top pods -n my-namespace

不一致に注意してください。CPU を 500m リクエストしているのに実際の平均使用量が 30m 程度のPodは、リソースサイズ見直しの格好のターゲットです。

ステップ3:修正方法

方法A — PodのリソースリクエストをReduceする

過大なリクエストが最もよくある原因です。Podが本当に 500m を必要としていない場合は、マニフェストで値を下げましょう。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: my-namespace
spec:
  containers:
  - name: my-container
    image: my-image:latest
    resources:
      requests:
        cpu: "100m"      # 500m から 100m に削減
        memory: "128Mi"
      limits:
        cpu: "200m"
        memory: "256Mi"

現実的な値を設定するために、まず kubectl top pods を実行してください。平均 80m のPodに 100m を設定すれば、クォータを無駄にせず安全なバッファを確保できます。

方法B — ResourceQuotaの上限を増やす

名前空間にもう少し余裕が必要な場合もあります。まず現在のクォータ定義を確認します。

kubectl get resourcequota my-quota -n my-namespace -o yaml

直接パッチを適用する場合:

kubectl patch resourcequota my-quota -n my-namespace \
  --type='json' \
  -p='[{"op": "replace", "path": "/spec/hard/cpu", "value": "2"}]'

クォータをYAMLファイルで管理している場合(推奨方法)は、更新して適用します。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-quota
  namespace: my-namespace
spec:
  hard:
    cpu: "2"        # 1 から 2 に増加
    memory: 4Gi
    pods: "20"
kubectl apply -f resourcequota.yaml

方法C — 未使用のPodを削除するか、Deploymentをスケールダウンする

完了済みや失敗したPodも、削除されるまでクォータを消費し続けます。不要なPodを整理しましょう。

# 完了済み・失敗したPodを削除
kubectl delete pods -n my-namespace --field-selector=status.phase==Succeeded
kubectl delete pods -n my-namespace --field-selector=status.phase==Failed

# 不要になったDeploymentをスケールダウン
kubectl scale deployment old-deployment -n my-namespace --replicas=0

他の方法を試す前にまずこれを確認する価値があります。古い Completed ジョブが大量に残っている名前空間は、数百ミリコアを静かに占有していることがあります。上限を変更せずにクォータの余裕を確保できるかもしれません。

ステップ4:修正を確認する

変更を加えたら、再試行する前にクォータに余裕があることを確認します。

# 更新されたクォータ使用量を確認
kubectl describe resourcequota -n my-namespace

# Podを再作成する
kubectl apply -f my-pod.yaml

# Podが起動していることを確認
kubectl get pod my-pod -n my-namespace

期待される出力:

NAME     READY   STATUS    RESTARTS   AGE
my-pod   1/1     Running   0          10s

今後のためのヒント

  • リソースのリクエストと制限は必ず設定する — ResourceQuotaが設定されている名前空間では、リクエストや制限が未定義のPodは拒否されます。すべてのPodに個別に指定したくない場合は、LimitRange を使って名前空間全体のデフォルト値を設定しましょう。
  • LimitRangeとResourceQuotaをセットで使うLimitRange はコンテナごとのデフォルト値を設定し、ResourceQuota は名前空間全体の合計に上限を設けます。これらは連携して機能するように設計されています。
  • CI/CDパイプラインにクォータチェックを組み込む — デプロイ前のステップとして kubectl describe resourcequota -n $NAMESPACE を実行し、利用可能なCPUがデプロイするPodのリクエストサイズを下回った場合にパイプラインを失敗させるようにしましょう。
  • リクエストの値は推測ではなく実際のメトリクスに基づいて設定するkubectl top pods を使うか、Prometheusから1週間分のp95 CPUデータを取得してください。「500m くらいで大丈夫だろう」という憶測よりはるかに信頼できる根拠になります。
  • クォータはポリシーであり、物理的な制約ではない — このエラーは物理的なリソース不足ではなく、管理上の上限に達したことを意味します。ノードには十分な空きCPUがあるかもしれません。ResourceQuotaはクラスター管理者が設定したガバナンス上の制限に過ぎません。

Related Error Notes