Behind every Bound claim is a PersistentVolume: the disk, as an object.
A volume by hand
Dynamic provisioning needs a provisioner. Without one, or when the storage already exists, an administrator writes the PV:
apiVersion: v1
kind: PersistentVolume
metadata:
name: archive-pv
spec:
capacity:
storage: 2Gi
accessModes: [ReadWriteOnce]
persistentVolumeReclaimPolicy: Retain
storageClassName: ""
hostPath:
path: /mnt/archive| Field | Means |
|---|---|
capacity.storage | How much it offers |
accessModes | The modes it supports |
persistentVolumeReclaimPolicy | Retain or Delete when its claim goes away |
storageClassName: "" | No class: static binding only |
hostPath / nfs / csi | Where the bytes are |
PVs are cluster-scoped. kubectl get pv needs no -n; its STATUS starts as Available.
Binding by hand
A claim with storageClassName: "" never triggers a provisioner. The binder looks for an Available PV where:
If nothing fits, the claim stays Pending:
Normal FailedBinding persistentvolume-controller no persistent volumes available for this claim and no storage class is setCreate a fitting PV later and the claim binds on the next pass. Nothing has to be retried.
Pre-binding
A PV can name its claim in advance with spec.claimRef (namespace and name), and a claim can name its volume with spec.volumeName. Either pins the pair; use it when a specific dataset must land on a specific disk.