PersistentVolumeClaim #
PersistentVolumeClaim (PVC) adalah cara developer meminta storage di Kubernetes tanpa perlu tahu detail infrastruktur di baliknya. Developer cukup mendeklarasikan “saya butuh 10Gi storage dengan akses ReadWriteOnce” — Kubernetes yang mencari PV yang sesuai, atau membuatnya secara dinamis jika StorageClass tersedia. PVC adalah abstraksi yang memisahkan kebutuhan aplikasi dari detail provisioning storage.
Anatomi Manifest PVC #
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
namespace: production # PVC adalah resource namespaced
spec:
accessModes:
- ReadWriteOnce # mode akses yang dibutuhkan
resources:
requests:
storage: 50Gi # ukuran minimum yang dibutuhkan
storageClassName: standard-ssd # StorageClass yang digunakan
# (kosongkan untuk pilih PV manual)
volumeMode: Filesystem # Filesystem (default) atau Block
Proses Binding #
Setelah PVC dibuat, Kubernetes mencari PV yang kompatibel untuk di-bind:
PVC dibuat:
accessModes: RWO
storage: 50Gi
storageClassName: standard-ssd
Kubernetes mencari PV yang memenuhi SEMUA kriteria:
✓ accessModes kompatibel (PV punya RWO)
✓ kapasitas >= yang diminta (PV minimal 50Gi)
✓ storageClassName cocok
✓ status PV: Available (belum diikat PVC lain)
Jika ditemukan → Binding terjadi
PVC status: Bound
PV status: Bound
PV.claimRef → menunjuk ke PVC ini
Jika tidak ditemukan:
PVC status: Pending → menunggu sampai PV tersedia
(atau PV dibuat secara dinamis via StorageClass)
Penting: Kubernetes tidak memilih PV yang paling pas — ia memilih PV yang pertama memenuhi semua kriteria. Jika ada PV 100Gi dan PV 50Gi yang keduanya memenuhi syarat PVC 10Gi, bisa saja yang terpilih adalah PV 100Gi, menyia-nyiakan 90Gi.
Menggunakan PVC di Pod #
PVC digunakan di Pod dengan cara yang sama seperti volume lainnya:
apiVersion: v1
kind: Pod
metadata:
name: postgres
spec:
containers:
- name: postgres
image: postgres:15
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: postgres-data # nama PVC yang sudah dibuat
readOnly: false
Lifecycle yang perlu dipahami: PVC tidak terikat ke Pod. PVC adalah resource independent — Pod yang menggunakan PVC bisa dihapus dan dibuat ulang, PVC dan datanya tetap ada. Ini yang membuat PVC berbeda dari emptyDir.
Selector untuk Memilih PV Tertentu #
Jika ada beberapa PV yang tersedia, kamu bisa menggunakan label selector untuk memastikan PVC diikat ke PV yang spesifik:
spec:
selector:
matchLabels:
type: ssd
environment: production
# PVC ini hanya akan diikat ke PV yang punya label:
# type=ssd dan environment=production
Ini berguna saat ada beberapa PV dengan karakteristik berbeda dan kamu ingin workload tertentu selalu mendapat storage dengan karakteristik spesifik.
PVC di StatefulSet #
StatefulSet punya cara khusus mendefinisikan PVC — bukan di volumes, tapi di volumeClaimTemplates. Ini secara otomatis membuat PVC terpisah untuk setiap Pod:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
volumeClaimTemplates: # ← di sini, bukan di spec.template.volumes
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: standard-ssd
resources:
requests:
storage: 50Gi
Untuk StatefulSet dengan 3 replica, Kubernetes otomatis membuat:
data-postgres-0(untuk Podpostgres-0)data-postgres-1(untuk Podpostgres-1)data-postgres-2(untuk Podpostgres-2)
Mendiagnosis PVC yang Stuck di Pending #
PVC yang tidak kunjung Bound adalah masalah yang umum dan perlu didiagnosis dengan tepat:
# Lihat status PVC
kubectl get pvc -n production
# Output:
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
# postgres-data Pending standard-ssd 5m
# Detail PVC — lihat bagian Events
kubectl describe pvc postgres-data -n production
Penyebab umum dan solusinya:
Events: "no persistent volumes available for this claim and
no storage class is set"
→ Tidak ada PV Available dan tidak ada StorageClass
→ Solusi: buat PV secara manual atau definisikan StorageClass
Events: "waiting for a volume to be created, either by external
provisioner... or manually created by system administrator"
→ StorageClass ditemukan tapi provisioner tidak berjalan
→ Solusi: pastikan CSI driver ter-install dan berjalan
Events: "no persistent volumes available for this claim"
→ Ada StorageClass tapi gagal membuat PV
→ Solusi: cek log CSI driver pod untuk detail error
Events: "volume node affinity conflict"
→ PV yang ditemukan punya nodeAffinity yang tidak cocok dengan Pod
→ Solusi: periksa nodeAffinity PV vs node yang bisa digunakan Pod
Memperluas PVC (Volume Expansion) #
Jika storage awalnya kurang, PVC bisa diperluas tanpa downtime — selama StorageClass mendukung:
# StorageClass harus punya allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard-ssd
provisioner: ebs.csi.aws.com
allowVolumeExpansion: true # ← ini yang memungkinkan resize
# Edit PVC untuk request storage yang lebih besar
kubectl edit pvc postgres-data -n production
# Ubah spec.resources.requests.storage dari 50Gi ke 100Gi
# Atau dengan patch
kubectl patch pvc postgres-data -n production \
-p '{"spec":{"resources":{"requests":{"storage":"100Gi"}}}}'
# Pantau status resize
kubectl describe pvc postgres-data -n production
# Conditions akan menunjukkan progress resize
Volume expansion hanya bisa memperbesar — tidak bisa memperkecil. Pastikan kamu benar-benar butuh lebih besar sebelum meminta expansion, karena tidak ada cara untuk mengurangi ukuran PVC setelah diperbesar.
Ringkasan #
- PVC adalah permintaan storage dari namespace — developer mendefinisikan kebutuhan (ukuran, access mode, StorageClass); Kubernetes yang mencari atau membuat PV yang sesuai.
- Binding mencari PV yang memenuhi semua kriteria — access mode, kapasitas, StorageClass, dan status Available; Kubernetes tidak selalu memilih yang paling pas ukurannya.
- PVC independen dari Pod — Pod bisa dihapus dan dibuat ulang tanpa kehilangan data di PVC; PVC hanya terhapus jika dihapus secara eksplisit.
volumeClaimTemplatesdi StatefulSet — membuat PVC terpisah untuk setiap replica secara otomatis; PVC tidak ikut terhapus saat StatefulSet dihapus.kubectl describe pvcuntuk diagnosis — bagian Events menjelaskan mengapa PVC tidak kunjung Bound dengan pesan yang spesifik.- Volume expansion hanya bisa membesar — tidak bisa diperkecil; rencanakan ukuran storage awal dengan cukup buffer, atau gunakan StorageClass yang mendukung
allowVolumeExpansion.