ยินดีต้อนรับสู่ วันที่ 9: Persistent Storage Primitives (PVs, PVCs และ StorageClasses)!
วันนี้เราจะมาเรียนรู้เรื่องการจัดการเนื้อที่จัดเก็บข้อมูลแบบถาวร (Persistent Storage) ใน Kubernetes ซึ่งช่วยให้ข้อมูลของแอปพลิเคชันยังคงอยู่ไม่สูญหาย แม้ตัว Pod จะถูกลบ สร้างใหม่ หรือย้ายไปรันบน Node อื่นก็ตามครับ
ช่วงที่ 1: สรุปแนวคิดสถาปัตยกรรม
เข้าใจปัญหา Ephemeral Storage, บทบาทของ 3 เสาหลัก SC, PV, PVC, กลไก Dynamic Provisioning และการส่องสถานะ Bound บน Headlamp
ช่วงที่ 2: การลงมือปฏิบัติจริง (5 ขั้นตอน)
ตรวจ StorageClass ในคลัสเตอร์, ร้องขอ PVC ขนาด 1Gi, ดูการจับคู่ Bound บน UI, เมานต์ดิสก์เข้า Pod และทดสอบความคงอยู่ของไฟล์ (Data Persistence)
สรุปแนวคิดและสถาปัตยกรรม (5–10 นาที)
3 เสาหลักของ Storage
โดยปกติคอนเทนเนอร์เป็น Ephemeral (ดับแล้วข้อมูลหาย) Kubernetes จึงแยกความรับผิดชอบออกเป็น:
• StorageClass (SC): ตัวกำหนดวิธีและไดรฟ์เวอร์สร้างดิสก์
• PV: เนื้อที่ดิสก์จริงระดับคลัสเตอร์
• PVC: ใบคำร้องขอพื้นที่จากนักพัฒนา
Dynamic Provisioning
เมื่อเรายื่นขอ PersistentVolumeClaim (เช่น ขอพื้นที่ 1Gi แบบ ReadWriteOnce) ตัว StorageClass จะเรียก Provisioner จัดสรรดิสก์สร้างเป็น PersistentVolume ให้แบบอัตโนมัติ และเปลี่ยนสถานะเป็น Bound โดยแอดมินไม่ต้องมานั่งสร้างดิสก์ล่วงหน้า
Storage บน Headlamp UI
Headlamp มีหมวด Storage แยกเฉพาะ ประกอบด้วย PersistentVolumeClaims, PersistentVolumes และ StorageClasses ทำให้ตรวจสอบสถานะการ Bound, ขนาดพื้นที่, Access Modes และ Reclaim Policy ได้อย่างชัดเจนโดยไม่ต้องจำคำสั่งยาวๆ
ขั้นตอนลงมือปฏิบัติจริง (15–20 นาที)
เปิด Terminal แล้วตรวจสอบ StorageClass เริ่มต้นที่มีอยู่ใน Cluster ของคุณ (เช่น standard หรือ k8s.io/minikube-hostpath):
kubectl get storageclass
(default) เช่น standard (default) หรือ local-path (default) แสดงว่าคลัสเตอร์พร้อมทำ Dynamic Provisioning
สร้างคำร้องขอจองพื้นที่จัดเก็บข้อมูลขนาด 1Gi ในโหมด ReadWriteOnce โดยตั้งชื่อว่า data-pvc:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
persistentvolumeclaim/data-pvc created และระบบจะเริ่มประสานงานกับ StorageClass เพื่อสร้าง PV จริงขึ้นมารองรับ
เปิด Headlamp UI เพื่อตรวจสอบการจับคู่ผูกมัด (Binding) ของทรัพยากรจัดเก็บข้อมูล:
- เปิด Headlamp UI ขึ้นมา (ผ่าน http://localhost:8080 หรือ Headlamp Desktop)
- ไปที่เมนูด้านซ้ายในส่วน Storage > PersistentVolumeClaims
- คลิกเลือก data-pvc เพื่อสังเกตสถานะ: จะต้องขึ้นเป็น Bound พร้อมระบุชื่อของ Volume (PV) ที่ระบบสร้างให้อัตโนมัติ (เช่น
pvc-xxxxxxxx-xxxx...) - คลิกสลับไปที่เมนูด้านซ้ายในส่วน Storage > PersistentVolumes เพื่อดูคุณสมบัติของดิสก์จริง เช่น ขนาดความจุ
1Gi, Access ModeRWOและ Reclaim Policy
สร้าง Pod ชื่อ storage-pod ที่นำ data-pvc มาเมานต์ไว้ที่โฟลเดอร์แสดงผลเว็บของ Nginx (/usr/share/nginx/html):
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: storage-pod
spec:
containers:
- name: web
image: nginx:alpine
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-storage
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: data-pvc
EOF
pod/storage-pod created และในหน้ารายละเอียด Pod บน Headlamp UI จะแสดงแถบ Volumes ที่ผูกติดกับ data-pvc อย่างสมบูรณ์
พิสูจน์ว่าไฟล์ที่เขียนลงดิสก์ถาวรจะไม่สูญหาย แม้สั่งลบ Pod ทิ้งแล้วสร้างใหม่:
index.html บน Volume:
kubectl exec storage-pod -- sh -c "echo 'Headlamp Storage Test' > /usr/share/nginx/html/index.html"
kubectl delete pod storage-pod
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: storage-pod
spec:
containers:
- name: web
image: nginx:alpine
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-storage
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: data-pvc
EOF
kubectl exec storage-pod -- cat /usr/share/nginx/html/index.html
Headlamp Storage Test แสดงว่าข้อมูลถูกเขียนลงดิสก์ถาวรจริง ไม่ได้เก็บไว้ในชั้น Ephemeral ของ Container
ลองทำตามขั้นตอนการสร้าง PVC และทดสอบ Data Persistence ดูนะครับ หากตรวจสอบสถานะการ Bound บน Headlamp UI และยืนยันว่าข้อมูลไม่หายเรียบร้อยแล้ว แจ้งได้เลยครับ!