Qingular

PersistentVolumeClaim (PVC)

·CKAk8sPractice

CKA Exam Domain 4 — PVC creation, PV binding mechanism, Pod mounting, expansion, Selector binding

← Back to CKA Practice Index PersistentVolumeClaim is a user's request for storage. Pods use PVCs to request storage resources, and Kubernetes binds PVCs to PVs that meet the requirements.


1. PVC and PV Binding Mechanism

The following conditions must be met for a PVC to bind to a PV:

  • Capacity: The PV's capacity.storage >= PVC's resources.requests.storage`
  • Access Mode: The PV must support the access mode requested by the PVC
  • Storage Class: If the PVC specifies storageClassName, the PV must match (or use dynamic provisioning)
  • Selector: If the PVC sets a selector, the PV's labels must match

Note: A PVC can only bind to one PV — the relationship is one-to-one.


2. PVC Example

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: ""    # "" means use static PV, omit to use default StorageClass

3. Binding With Selector vs Without Selector

Without Selector

Kubernetes automatically matches an eligible PV (capacity, access mode, storage class).

spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

With Selector

Precisely matches a PV with specific labels.

spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  selector:
    matchLabels:
      type: ssd
      environment: production
    matchExpressions:
      - key: tier
        operator: In
        values:
          - fast

Corresponding PV labels:

metadata:
  labels:
    type: ssd
    environment: production
    tier: fast

4. Pod Mounting a PVC

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: my-storage
  volumes:
    - name: my-storage
      persistentVolumeClaim:
        claimName: my-pvc

5. Complete Example: PV + PVC + Pod

PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /data/pv

PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi

Pod

apiVersion: v1
kind: Pod
metadata:
  name: storage-pod
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "echo 'Hello CKA' > /data/index.html && sleep 3600"]
      volumeMounts:
        - name: storage
          mountPath: /data
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: example-pvc

6. PVC Expansion

Requires the PV backend to support expansion (e.g., AWS EBS, GCE PD, etc.) and the PV's allowVolumeExpansion: true.

# Edit PVC and change the storage size
kubectl edit pvc example-pvc
spec:
  resources:
    requests:
      storage: 2Gi   # Expand from 1Gi to 2Gi

After expansion, use kubectl get pvc to check status. The PVC will show FileSystemResizePending until complete.


7. Useful Commands

# View PVCs
kubectl get pvc

# View PVC details (check bound PV)
kubectl describe pvc <pvc-name>

# View PVC YAML
kubectl get pvc <pvc-name> -o yaml

# Delete PVC
kubectl delete pvc <pvc-name>

# Check if PVC is bound
kubectl get pvc -o wide

8. Exam Key Points

  • PVC and PV must be in the same namespace to bind
  • PVC's storageClassName: "" means use static PV (disable dynamic provisioning)
  • kubectl describe pvc shows the reason for binding failure
  • If no PV meets the conditions, the PVC will remain in Pending state
  • PVC expansion can only increase, not decrease

🧪 Complete Hands-On Example: Pod Mounts PVC for Persistent Storage

Scenario

Create a PVC bound to a PV, then use that PVC in a Pod to store data. Delete the Pod and recreate it to verify that data persists.

Prerequisites

  • Cluster has an available PV (or use dynamic provisioning)
  • Ability to create and manage Pods

Steps

Step 1: Create hostPath PV

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-data
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /data/pv-data
    type: DirectoryOrCreate
EOF

kubectl get pv
# NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   AGE
# pv-data  1Gi        RWO            Retain           Available           manual         5s

Step 2: Create PVC

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi
EOF

Step 3: Verify PVC Binding Status

kubectl get pvc
# NAME         STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
# claim-data   Bound    pv-data  1Gi        RWO            manual         10s

kubectl describe pvc claim-data
# Name:          claim-data
# Namespace:     default
# Status:        Bound
# Volume:        pv-data
# ...

Step 4: Create Pod Mounting PVC and Write Data

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: writer-pod
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "echo 'CKA Data Persistence Test' > /data/test.txt && sleep 3600"]
      volumeMounts:
        - name: storage
          mountPath: /data
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: claim-data
EOF

# Wait for Pod to run
kubectl get pod writer-pod -w

Step 5: Verify Data Written

kubectl exec writer-pod -- cat /data/test.txt
# CKA Data Persistence Test

Step 6: Delete Pod and Recreate

kubectl delete pod writer-pod

# Recreate with a new Pod mounting the same PVC
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: reader-pod
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "cat /data/test.txt && sleep 3600"]
      volumeMounts:
        - name: storage
          mountPath: /data
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: claim-data
EOF

# Wait for new Pod to run
kubectl get pod reader-pod -w

Verification

# Verify data persistence (previously written data still exists)
kubectl logs reader-pod
# CKA Data Persistence Test

# Or execute a command directly
kubectl exec reader-pod -- cat /data/test.txt
# CKA Data Persistence Test

Exam Tips

  • PVC to PV binding is one-to-one; after binding, other PVCs cannot use the same PV
  • After a Pod is deleted, PVC and PV still exist and data is not lost
  • Whether multiple Pods can mount the same PVC depends on Access Mode (RWO allows single node only)
  • Common exam mistake: forgetting to correctly configure volumes and volumeMounts in Pod
  • Use kubectl describe pvc to view the PV name and status bound to a PVC

Official Documentation