Danh sách bài viết trong series Học Kubernetes Từ Cơ Bản Đến Chứng Chỉ CKAD
- Lộ Trình Học Kubernetes Từ Cơ Bản Đến Chứng Chỉ CKAD
- Bài 1: Giới Thiệu Kubernetes Và Khái Niệm Cluster Cho CKAD
- Bài 2: Cài Đặt Minikube Và sử dụng kubectl Cơ Bản
- Bài 3: Quản Lý Pod Cơ Bản (Create, Delete, Describe)
- Bài 4: Sử Dụng ConfigMap Và Secret Trong YAML
- Bài 5: Quản Lý Environment Variables Và Command/Args
- Bài 6: Cấu Hình Deployment Và Replica Set
- Bài 7: Thiết Kế Pod Với Nhiều Container
- Bài 8: Sử Dụng Sidecar Và Init Container
- Bài 9: Chia Sẻ Tài Nguyên Giữa Các Container
- Bài 10: Giám Sát Log Và Events Với kubectl logs
- Bài 11: Debug Pod Với kubectl describe Và exec
- Bài 12: Tối Ưu Pod Với Resource Limits Và Requests
- Bài 13: Sử Dụng Liveness Và Readiness Probes
- Bài 14: Tối Ưu Hóa Pod Với HPA (Horizontal Pod Autoscaler)
- Bài 15: Cấu Hình Service (ClusterIP, NodePort)
- Bài 16: Sử Dụng Ingress Và Network Policy
- Bài 17: Quản Lý DNS Và Load Balancing Trong Kubernetes
- Bài 18: Sử Dụng Volume (emptyDir, hostPath)
- Bài 19: Cấu Hình Persistent Volume Và Persistent Volume Claim
- Bài 20: Tổng Kết, Mẹo Thi CKAD, Bài Tập Thực Hành Cuối
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) và 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ì?

PersistentVolume (PV) là storage thực tế trong cluster, được admin hoặc hệ thống provision sẵn. PersistentVolumeClaim (PVC) là 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 lifecycle và access 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 claimName và metadata.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
Retaintrong 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.







