Bài 19: Cấu Hình Persistent Volume Và Persistent Volume Claim

Sau khi đã học cách sử dụng emptyDir và hostPath trong Bài 18, chúng ta bước vào phần cuối của domain State Persistence (10%) giúp ứng dụng lưu trữ dữ liệu một cách bền vững ngay cả khi Pod bị xóa hoặc node gặp sự cố.

Bài viết này thuộc domain State Persistence, tập trung vào hai khái niệm cốt lõi: PersistentVolume (PV)PersistentVolumeClaim (PVC). Trong kỳ thi CKAD, bạn có thể gặp task như “Tạo PVC 5Gi RWO, bind với PV có hostPath /mnt/data, mount vào Pod tại /db-data”, hoặc debug lỗi PVC Pending, PV chưa bind. Đây là phần hay ra đề nhất trong domain này, và nếu nắm vững, bạn dễ dàng ghi trọn điểm nhờ hiểu rõ lifecycle và binding process của storage.

PersistentVolume (PV) Và PersistentVolumeClaim (PVC) Là Gì?

https://cdn.prod.website-files.com/626a25d633b1b99aa0e1afa7/671fa86f86c5fc2e66cadf4c_671fa580fd31ec659ca5c3e6_image2.jpeg

PersistentVolume (PV)storage thực tế trong cluster, được admin hoặc hệ thống provision sẵn. PersistentVolumeClaim (PVC)yêu cầu storage mà người dùng gửi đến cluster để xin dung lượng theo nhu cầu. Khi PVC phù hợp với một PV (về size, access mode, storageClass), Kubernetes sẽ tự động bind hai thành phần này.

Khái niệm Mô tả Vai trò
PV Storage thực tế (cluster-wide) Cung cấp bởi admin, bind 1:1 với PVC
PVC Yêu cầu storage (namespace-scoped) User tạo, bind tự động nếu match PV
StorageClass Template cho dynamic PV Tự động tạo PV khi PVC yêu cầu

CKAD Tip: PV/PVC tách biệt rõ giữa người cung cấp (admin) và người dùng (developer). Trong kỳ thi, bạn thường đóng vai dev chỉ tạo PVC, không cần quyền admin để tạo PV.

Các Thuộc Tính Quan Trọng Của PV/PVC

2.1 Access Modes

Mode Mô tả Ví dụ
ReadWriteOnce (RWO) Read/write từ 1 node duy nhất Database
ReadOnlyMany (ROX) Read từ nhiều node Shared config
ReadWriteMany (RWX) Read/write từ nhiều node NFS, GlusterFS

Lưu ý: Không phải backend nào cũng hỗ trợ RWX (e.g., local disk chỉ hỗ trợ RWO).

2.2 Reclaim Policy

Policy Mô tả
Retain Giữ PV lại sau khi PVC bị xóa
Delete Xóa PV cùng với PVC
Recycle Dọn sạch data rồi reuse (đã deprecated)

2.3 Lifecycle Phases

  • PV: Available => Bound => Released => Failed
  • PVC: Pending => Bound => Lost

CKAD Tip: Nếu PVC bị Pending, kiểm tra ngay kubectl describe pvc để xem Events thường do accessMode hoặc storageClass mismatch.

Thực Hành 1: Tạo Static PV Và PVC Với hostPath (Local Storage)

Bước 1: Tạo PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath:
    path: /mnt/data

Chạy lệnh:

kubectl apply -f pv.yaml
kubectl get pv local-pv

CKAD Tip: Trong Minikube, cần tạo thư mục /mnt/data trên host trước bằng minikube ssh 'sudo mkdir -p /mnt/data'.

Bước 2: Tạo PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: local-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: manual

Chạy lệnh:

kubectl apply -f pvc.yaml
kubectl get pvc local-pvc  # Bound
kubectl get pv local-pv    # Bound

Nếu PVC Pending, kiểm tra lại accessModes, capacity hoặc storageClassName.

Thực Hành 2: Mount PVC Vào Pod Và Kiểm Tra Dữ Liệu Bền Vững

apiVersion: v1
kind: Pod
metadata:
  name: pvc-pod
spec:
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: local-pvc
  containers:
  - name: db-container
    image: busybox
    command: ['sh', '-c', 'echo "Persistent Data" > /db/data.txt && sleep 3600']
    volumeMounts:
    - name: persistent-storage
      mountPath: /db

Kiểm tra:

kubectl exec -it pvc-pod -- cat /db/data.txt

Xóa và tạo lại Pod:

kubectl delete pod pvc-pod
kubectl apply -f pod-with-pvc.yaml
kubectl exec -it pvc-pod -- cat /db/data.txt

Data vẫn còn vì PV được giữ lại theo policy Retain.

5. Dynamic Provisioning Với StorageClass (Nâng Cao)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete

PVC có storageClassName: local-storage sẽ tự động tạo PV dynamic nếu có provisioner.

CKAD Tip: Khi đề nói “use default storage class”, chỉ cần tạo PVC có storageClassName: "" hoặc bỏ field này.

6. Debug PV/PVC Không Bind

Lỗi Nguyên nhân Cách fix
PVC Pending Không PV match Kiểm tra accessMode, capacity, storageClass
PV Bound nhưng Pod fail Sai claimName kubectl describe pod
Storage full Thiếu dung lượng Giảm request
Node affinity fail PV local chỉ thuộc 1 node Add nodeAffinity

Liên Hệ Với Chứng Chỉ CKAD

Domain State Persistence (10%) thường có 1-2 câu hỏi về PV/PVC, chiếm khoảng 5-10 điểm. Trong kỳ thi, bạn có thể gặp yêu cầu tạo PV/PVC thủ công với hostPath, hoặc debug lỗi PVC không bind được. Một số câu yêu cầu bạn mount PVC vào Pod để ghi/đọc file đây là điểm kiểm tra khả năng hiểu storage lifecycleaccess modes.

Các lỗi thí sinh hay mắc là quên match storageClassName, tạo PVC trước PV, hoặc nhầm giữa claimNamemetadata.name trong YAML.

Mẹo thi:

  • Luôn tạo PV trước PVC (PV phải ở trạng thái Available).
  • Match chính xác: capacity, accessModes, storageClassName.
  • Dùng Retain trong test để kiểm tra data bền vững.
  • Nếu PVC Pending => kubectl describe pvc để xem Events.
  • Khi mount PVC vào Pod, nhớ claimName đúng với PVC đã tạo.

Bài Tập CKAD

Đề: Tạo PV exam-pv 10Gi, hostPath /exam/data, reclaim Retain, storageClass manual. Tạo PVC exam-pvc 10Gi, match storageClass manual. Tạo Pod exam-pod mount PVC vào /persist, ghi "CKAD Pass" vào /persist/file.txt.

Đáp án:

# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: exam-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath:
    path: /exam/data
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: exam-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: manual
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: exam-pod
spec:
  volumes:
  - name: exam-storage
    persistentVolumeClaim:
      claimName: exam-pvc
  containers:
  - name: busybox
    image: busybox
    command: ['sh', '-c', 'echo "CKAD Pass" > /persist/file.txt && sleep 3600']
    volumeMounts:
    - name: exam-storage
      mountPath: /persist

Tóm Tắt Kiến Thức Cho CKAD

Thành phần Ghi nhớ
PV v1, cluster-wide, có storage thật
PVC namespace, yêu cầu storage
Access Modes RWO, ROX, RWX
Reclaim Policy Retain, Delete
StorageClass Dynamic provision
Mount vào Pod volumes.persistentVolumeClaim.claimName

Kết Luận

Bài này mình đã hướng dẫn chi tiết cách tạo, bind, và mount Persistent Volume và Persistent Volume Claim, cũng như giải thích cơ chế binding và reclaim trong thực tế. Bạn giờ đã hiểu cách lưu trữ dữ liệu bền vững, debug lỗi Pending, và triển khai cả static lẫn dynamic provisioning trong Kubernetes. Tiếp theo, ở Bài 20: Tổng Kết Và Mẹo Thi CKAD, chúng ta sẽ tổng hợp toàn bộ domains, hệ thống mẹo thi, và hướng dẫn cách luyện tập trong 2 tiếng cuối cùng trước kỳ thi thật.

Điều hướng chuỗi bài viết<< Bài 18: Sử Dụng Volume (emptyDir, hostPath)
>> Bài 20: Tổng Kết, Mẹo Thi CKAD, Bài Tập Thực Hành Cuối

Thông tin nổi bật

Sự kiện phát trực tiếp​

Event Thumbnail

Báo cáo quan trọng

Article Thumbnail
Article Thumbnail
Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận

Tiêu điểm chuyên gia