「No StorageClass Set」エラーの解決策:KubernetesのPVCがPending状態のままになる理由

beginner☸️ Kubernetes2026-04-12| Kubernetes (EKS, GKE, AKS, オンプレミス・クラスター), kubectl CLI

Error Message

persistentvolumeclaims "my-pvc" is forbidden: no persistent volumes available for this claim and no storage class is set
#kubernetes#pvc#devops#storageclass#トラブルシューティング

エラーメッセージこれはよくある悩みの一つです。ステートフルなアプリケーションをデプロイしたものの、PersistentVolumeClaim(PVC)が Pending 状態から一向に動かないことがあります。kubectl describe pvc <pvc-name> を使って詳細を調査すると、次のような壁に突き当たります。

persistentvolumeclaims "my-pvc" is forbidden: no persistent volumes available for this claim and no storage class is set

何が起きているのか?Kubernetesは本質的に、データの保存先をどこに用意すればよいのか分からないと伝えています。PVCを、劇場の座席のチケットだと考えてみてください。劇場側が座席をまだ作っておらず(静的プロビジョニング)、かつ座席を自動で作ってくれる機械もない(動的プロビジョニング)場合、あなたはロビーで立ち尽くすことになります。

このエラーは通常、次の3つの理由で発生します:

  • デフォルト設定の欠如: クラスターに「デフォルト(Default)」の StorageClass が指定されていません。- マニフェストの空欄: PVCのYAMLで storageClassName が指定されていないため、Kubernetesが判断を保留しています。- 手動設定の不一致: PersistentVolume(PV)を手動で作成したが、そのサイズ(例:5Gi)や AccessMode が、PVCが要求しているもの(例:10Gi)と一致していません。## 解決策1:デフォルトの StorageClass を割り当てるAWS EKS や Google GKE などのマネージドサービスの多くはストレージドライバーがプリインストールされていますが、それらがデフォルトとして設定されていない場合があります。特定のクラスをデフォルトとしてマークすることで、タイプを指定していないPVCは自動的にそのクラスを使用するようになります。 まず、利用可能なクラスを一覧表示します:
kubectl get storageclass

もし gp2 (AWS) や standard (GKE) のようなクラスが表示されているのに、(default) と表示されていない場合は、次のコマンドを実行して修正します:

kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

パッチを適用したら、止まっていたPVCを削除して再作成してください。ほぼ瞬時にバインド(Bind)されるはずです。

解決策2:storageClassName を明示的に定義するグローバルなデフォルト設定を望まない場合もあります。例えば、データベースには高性能なSSDが必要だが、ログの保存には安価なHDDストレージを使いたいといったケースです。この場合、PVCに対してどの「テンプレート」を使用するかを正確に伝える必要があります。

pvc.yaml を更新して、storageClassName フィールドを含めます:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: database-storage
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: premium-r3 # ここに特定のクラス名を指定します
  resources:
    requests:
      storage: 20Gi

更新を適用します。Kubernetesは指定された CSI ドライバー(EBS や Azure Disk ドライバーなど)にアクセスし、その 20Gi のボリュームをプロビジョニングします。

解決策3:ベアメタル環境での手動プロビジョニングホームラボや、クラウドプロバイダーを利用しないベアメタル・クラスターを実行している場合、動的プロビジョニングは標準では利用できません。あなた自身が「ストレージ作成機」になる必要があります。

PVCの要求事項に一致する手動の PersistentVolume を作成します:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv-01
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: "/mnt/data/mysql"

プロのヒント: PVCがこの手動ボリュームを要求できるように、PVC内の storageClassName を空("")にするか、PVに付けたクラス名と一致させてください。

修正の確認いずれかの修正を適用した後、PVCの状態を再度確認します:

kubectl get pvc

Bound ステータスになっていれば成功です。以下のようになります:

NAME             STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
database-storage Bound    pvc-8a7b6c...    20Gi       RWO            premium-r3     15s

ステータスが Bound になれば、Podはついに ContainerCreating から Running へと移行します。

予防のためのヒント- デフォルトは1つだけ: 2つの StorageClass をデフォルトに設定しないでください。スケジューラーが混乱し、予測不可能なプロビジョニングが発生する可能性があります。- ドライバーの確認: StorageClass が存在するのに失敗する場合は、プロビジョナー Pod(ebs-csi-controller など)が実際に kube-system ネームスペースで動作しているか確認してください。- クォータの監視: クラウドプロバイダーを使用している場合、IOPS や総ディスク容量のアカウント制限に達していないか確認してください。

Related Error Notes