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 Pod postgres-0)
  • data-postgres-1 (untuk Pod postgres-1)
  • data-postgres-2 (untuk Pod postgres-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.
  • volumeClaimTemplates di StatefulSet — membuat PVC terpisah untuk setiap replica secara otomatis; PVC tidak ikut terhapus saat StatefulSet dihapus.
  • kubectl describe pvc untuk 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.

← Sebelumnya: PersistentVolume   Berikutnya: StorageClass →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact