CKAD field manual

Kubernetes PersistentVolume YAML example

A PersistentVolume is cluster storage. A claim in a namespace binds to one volume, and a Pod mounts the claim.

A clamped cargo crate stays on the deck while a shuttle lifts away. A clamped cargo crate stays on the deck while a shuttle lifts away.
PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
  name: data-pv
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath:
    path: /mnt/data
    type: DirectoryOrCreate
PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  storageClassName: manual
  resources:
    requests:
      storage: 1Gi
StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: manual
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Retain
volumeBindingMode: Immediate
Bind, replace, reuse
kubectl get pv,pvc
kubectl delete pvc data
kubectl patch pv data-pv --type=json -p='[{"op": "remove", "path": "/spec/claimRef"}]'

Fields

storageClassName
Same string on the volume and the claim. Immutable after create. Empty string on both means no class.
accessModes
ReadWriteOnce is one node. The claim and the volume list the same mode.
volumeMode
Filesystem or Block. The default is Filesystem. Both objects must agree.
persistentVolumeReclaimPolicy
Retain keeps the volume after the claim is deleted. It stays Released until claimRef is removed.
hostPath.path
Directory on the node, not in the image. The Pod and the volume have to land on that node.
hostPath.type
DirectoryOrCreate makes the directory. Directory requires it to exist already.
capacity.storage
What the volume offers. The claim request must be less than or equal to this.
requests.storage
What the claim asks. Larger than the volume, and the claim stays Pending.
provisioner
kubernetes.io/no-provisioner means you create the PersistentVolume yourself.
volumeBindingMode
Immediate binds as soon as a volume matches. WaitForFirstConsumer waits for a Pod.
kubectl delete
Delete a Pending claim and create it again. The class, the mode, and volumeMode do not change in place.
kubectl patch
Removes claimRef on a Released volume so the next claim can bind. Retain leaves that ref behind.

Watch

  • A claim binds when storageClassName, accessModes, and volumeMode match a volume, and requests.storage is less than or equal to capacity.storage. Read the volume first and copy those four from it.
  • storageClassName is immutable. Delete a Pending claim and create it again with the class the volume already has. A claim that omits the field takes the default StorageClass, which does not match a volume named manual.
  • volumeBindingMode: WaitForFirstConsumer stays Pending until a Pod uses the claim. Immediate binds as soon as a volume matches. kubernetes.io/no-provisioner does not create disks. You write the PersistentVolume.
  • Retain leaves the volume Released after the claim is deleted. Remove claimRef before another claim can bind. hostPath type DirectoryOrCreate creates the path on the node. The volume is cluster-scoped. The claim is namespaced. The Pod names the claim.

Official docs Persistent Volumes Storage Classes

Practice these objects on a live cluster →