Ultimate PVC
PVC with storage class
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim # Name of the PVC
namespace: default # Optional: Namespace in which the PVC resides
labels: # Optional: Labels for the PVC
app: myapp
tier: backend
annotations: # Optional: Annotations for metadata
volume.beta.kubernetes.io/storage-class: "standard" # Older annotation-based approach for SC
pv.kubernetes.io/bind-completed: "true" # Indicates if PVC/PV binding is completed (system-managed)
pv.kubernetes.io/bound-by-controller: "true" # Mark that it was bound by the PV controller
# Any custom annotation can go here
finalizers: # Optional: Ensures PVC is not removed while in use
- kubernetes.io/pvc-protection
spec:
accessModes: # Defines how the volume can be accessed
- ReadWriteOnce | ReadWriteMany | ReadOnlyMany
# Common usage:
# - ReadWriteOnce (RWO): The volume can be mounted as read-write by a single node
# - ReadWriteMany (RWX): The volume can be mounted as read-write by many nodes
# - ReadOnlyMany (ROX): The volume can be mounted as read-only by many nodes
storageClassName: "standard" | "" | null # Name of the StorageClass used for dynamic provisioning
# - If empty (""), uses default storage class if it exists
# - If null, manual binding to an existing PV is required
# - If set to a specific class name, dynamic provisioning or binding to a PV with that SC is triggered
volumeName: "myexistingpv" # Optional: Binds this PVC to an existing PV by name
selector: # Optional: Constraints to match certain PV labels
matchLabels:
environment: production
matchExpressions:
- key: release
operator: In | NotIn | Exists | DoesNotExist
values:
- stable
# The above example selects any PV with label `release=stable` and `environment=production`
resources:
requests:
storage: 500Mi # The minimum amount of storage requested
# Although rarely used for PVCs, ephemeral volumes might define limits:
# limits:
# storage: 1Gi
volumeMode: "Filesystem" | "Block" # Optional: The mode of the volume. "Filesystem" is default.
dataSource: # Optional: For cloning or restoring from a snapshot
name: "my-snapshot-or-pvc" # Name of the source VolumeSnapshot or PVC
kind: "VolumeSnapshot" | "PersistentVolumeClaim"
apiGroup: "snapshot.storage.k8s.io" | "" # Must match the group of the resource
dataSourceRef: # Newer recommended approach to specify dataSource
name: "my-snapshot-or-pvc"
kind: "VolumeSnapshot" | "PersistentVolumeClaim"
apiGroup: "snapshot.storage.k8s.io" | "storage.k8s.io"
# ephemeral: # Optional: For CSI ephemeral volumes (alpha feature)
# volumeClaimTemplate:
# metadata:
# ...
# spec:
# accessModes: ...
# resources:
# requests:
# storage: ...
# etc.
# Additional fields that are less commonly used or typically set at the PV-level are NOT included here
# (e.g., nodeAffinity, reclaimPolicy, mountOptions, etc. — those are on the PV, not the PVC)
PVC Status
status:
phase: Bound | Pending | Lost # Current status of the PVC
# Common phases: "Bound" means the PVC is bound to a PV,
# "Pending" means the claim is waiting to be bound,
# "Lost" means the bound PV is invalid or cannot be located.
accessModes: # Mirrored from spec, indicating how the bound volume can be accessed
- ReadWriteOnce
capacity: # Mirrored from the actual bound PV’s capacity
storage: 500Mi
conditions: # Optional: Conditions that represent the status of resizing or binding
- type: "Resizing"
status: "True"
lastProbeTime: "2021-03-10T09:14:00Z"
lastTransitionTime: "2021-03-10T09:14:00Z"
reason: "Expanding"
message: "Expanding volume from 500Mi to 1Gi"
# The status fields are primarily populated by the system (read-only).
# Users typically do not provide 'status' in the YAML; it’s returned by the API server.