PersistentVolume #

PersistentVolume (PV) adalah representasi sepotong storage di cluster Kubernetes. Ia abstraksi dari storage fisik yang sesungguhnya — bisa berupa disk cloud, NFS share, iSCSI target, atau storage lainnya. PV adalah resource cluster-level, seperti Node: ia ada dan tersedia untuk digunakan oleh siapa saja, independen dari namespace mana pun. Memahami PV adalah langkah pertama memahami bagaimana Kubernetes mengelola storage persisten.

Posisi PV dalam Ekosistem Storage #

Sebelum membahas detail PV, penting memahami perannya dalam hubungan tiga arah:

Admin cluster membuat PV:
  PersistentVolume (PV)
  └── merepresentasikan storage fisik yang tersedia

Developer membuat PVC yang "mengklaim" PV:
  PersistentVolumeClaim (PVC)
  └── "Saya butuh 10Gi storage dengan akses ReadWriteOnce"

Binding terjadi:
  PVC ──────── diikat ke ──────── PV
  (setelah bound, PV tidak bisa diklaim PVC lain)

Pod menggunakan PVC:
  Pod → PVC → PV → storage fisik

PV adalah milik cluster; PVC adalah milik namespace. Satu PV hanya bisa diikat ke satu PVC pada satu waktu.


Anatomi Manifest PV #

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-postgres-data
  labels:
    type: ssd
    environment: production
spec:
  capacity:
    storage: 50Gi              # ukuran storage yang tersedia

  accessModes:
  - ReadWriteOnce              # mode akses yang didukung volume ini

  persistentVolumeReclaimPolicy: Retain   # apa yang terjadi saat PVC dihapus

  storageClassName: manual     # class untuk matching dengan PVC

  volumeMode: Filesystem       # Filesystem (default) atau Block

  # Spesifikasi storage fisik (contoh: NFS)
  nfs:
    path: /exports/postgres-data
    server: 10.0.0.100

  # Atau untuk AWS EBS (via CSI):
  # csi:
  #   driver: ebs.csi.aws.com
  #   volumeHandle: vol-0a1b2c3d4e5f6g7h8
  #   fsType: ext4

Access Modes #

Access mode mendefinisikan bagaimana volume bisa di-mount:

ReadWriteOnce (RWO):
  → Satu node yang bisa mount sebagai read-write
  → Paling umum, didukung hampir semua storage backend
  → Cocok untuk database dan aplikasi stateful per-node

ReadOnlyMany (ROX):
  → Banyak node bisa mount sebagai read-only
  → Untuk distribusi file statis atau konfigurasi

ReadWriteMany (RWX):
  → Banyak node bisa mount sebagai read-write bersamaan
  → Butuh backend yang mendukung: NFS, CephFS, Azure Files, Amazon EFS
  → Ada overhead latensi vs block storage

ReadWriteOncePod (RWOP):   ← Kubernetes 1.22+
  → Hanya satu Pod (bukan satu node) yang bisa mount
  → Jaminan eksklusivitas lebih ketat dari RWO

Penting: access mode yang didukung PV harus cocok dengan yang diminta PVC untuk bisa di-bind.


Reclaim Policy #

Reclaim policy menentukan apa yang terjadi dengan PV setelah PVC yang mengikatnya dihapus:

Retain:
  → PV tidak dihapus, statusnya berubah jadi Released
  → Data pada storage fisik tetap ada
  → Admin harus secara manual menentukan nasib PV ini:
    a. Hapus PV dan data (untuk benar-benar membersihkan)
    b. Hapus PV tapi simpan data di storage fisik
    c. Recycle manual: bersihkan data, buat PV baru untuk digunakan lagi

Delete:
  → PV dan storage fisik di belakangnya DIHAPUS bersamaan dengan PVC
  → Default untuk PV yang dibuat via dynamic provisioning
  → Berbahaya jika salah konfigurasi — data langsung hilang permanen

Recycle: (deprecated, tidak direkomendasikan lagi)
  → Jalankan rm -rf pada volume untuk membersihkan isi
  → Kembalikan PV ke status Available
  → Digantikan oleh dynamic provisioning
Untuk storage yang mengandung data produksi, selalu gunakan Retain sebagai reclaim policy jika kamu ingin data tetap ada setelah PVC dihapus. Policy Delete akan menghapus data secara permanen dan tidak bisa dipulihkan.

Lifecycle PV #

PV memiliki empat fase dalam siklus hidupnya:

Available
  → PV sudah dibuat, belum diikat ke PVC manapun
  → Siap diklaim

Bound
  → PV sudah diikat ke sebuah PVC
  → Tidak bisa diklaim PVC lain
  → Dalam kondisi ini selama PVC masih ada

Released
  → PVC yang mengikatnya sudah dihapus
  → PV masih ada (karena policy Retain atau Recycle)
  → Data mungkin masih ada, PV belum bisa langsung diklaim PVC baru

Failed
  → Terjadi kegagalan pada reclaim otomatis
  → Membutuhkan intervensi manual admin
# Lihat status semua PV
kubectl get pv

# Output:
# NAME               CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS    CLAIM
# pv-postgres-data   50Gi      RWO           Retain          Bound     prod/postgres-pvc
# pv-redis-data      10Gi      RWO           Delete          Available
# pv-old-data        20Gi      RWO           Retain          Released  (PVC sudah dihapus)

# Detail PV
kubectl describe pv pv-postgres-data

Static Provisioning #

Static provisioning adalah pendekatan di mana admin cluster membuat PV secara manual sebelum developer bisa menggunakannya. Cocok untuk environment dengan storage yang sudah ada (NFS server, SAN) atau ketika butuh kontrol penuh atas detail storage.

# Admin membuat PV untuk NFS share yang sudah ada
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv-01
spec:
  capacity:
    storage: 100Gi
  accessModes:
  - ReadWriteMany                # NFS mendukung RWX
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs-storage
  nfs:
    server: nfs-server.internal
    path: /exports/data/vol-01

Proses static provisioning:

1. Admin menyiapkan storage fisik (disk, NFS share, iSCSI LUN)
2. Admin membuat PV yang merepresentasikan storage tersebut
3. Developer membuat PVC yang mendeskripsikan kebutuhan storage
4. Kubernetes mencocokkan PVC dengan PV yang sesuai (binding)
5. Pod menggunakan PVC sebagai volume

Keterbatasan static provisioning: admin harus selalu selangkah lebih maju dari developer. Jika tidak ada PV yang tersedia saat PVC dibuat, PVC akan stuck di status Pending.


Node Affinity untuk PV #

Beberapa jenis storage (terutama local storage) hanya tersedia di node tertentu. PV bisa mendefinisikan node affinity untuk memastikan Pod yang menggunakan PV ini dijadwalkan ke node yang tepat:

spec:
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - worker-1                # storage ini hanya ada di worker-1

  local:
    path: /mnt/fast-ssd/data       # path ke storage lokal di worker-1

Dengan nodeAffinity ini, Kubernetes akan memastikan Pod yang menggunakan PV ini selalu dijadwalkan ke worker-1 — karena datanya memang ada di sana.


Kapan Menggunakan Static Provisioning #

Gunakan static provisioning jika:
  ✓ Storage fisik sudah ada dan dikelola oleh tim berbeda (storage team)
  ✓ Butuh kontrol penuh atas detail setiap PV
  ✓ Storage backend tidak didukung oleh StorageClass / CSI driver
  ✓ Compliance yang mengharuskan storage diprovision oleh proses tertentu

Gunakan dynamic provisioning (via StorageClass) jika:
  ✓ Cluster berjalan di cloud dengan CSI driver yang tersedia
  ✓ Developer perlu self-service tanpa menunggu admin membuat PV
  ✓ Skala besar — membuat PV manual untuk ratusan service tidak praktis

Ringkasan #

  • PV adalah resource cluster-level — independen dari namespace; merepresentasikan storage fisik yang tersedia di cluster.
  • Lifecycle empat fase — Available → Bound → Released → Failed; PV di status Released masih menyimpan data tapi tidak bisa langsung diklaim PVC baru.
  • Reclaim policy Retain untuk produksi — data tidak dihapus otomatis saat PVC dihapus; admin yang memutuskan nasib data; jangan gunakan Delete untuk storage kritikal.
  • Access mode harus cocok — PV dengan RWO tidak bisa di-bind ke PVC yang meminta RWX; pastikan keduanya kompatibel.
  • Static provisioning untuk storage yang sudah ada — admin membuat PV manual; cocok untuk NFS, SAN, atau storage yang dikelola tim berbeda.
  • Node affinity untuk local storage — memastikan Pod dijadwalkan ke node yang memiliki storage lokal yang dimaksud.

← Sebelumnya: Storage Problem di Distributed Systems   Berikutnya: PersistentVolumeClaim →

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