StorageClass #

Di dalam kluster Kubernetes skala besar yang melayani ratusan aplikasi, melakukan penyediaan penyimpanan secara manual (static provisioning) adalah hal yang tidak praktis. Pengembang aplikasi tidak boleh terhambat oleh proses manual di mana administrator harus membuat PersistentVolume (PV) fisik terlebih dahulu di cloud console setiap kali aplikasi membutuhkan disk baru. Untuk mengotomatisasi seluruh daur hidup penyediaan penyimpanan ini secara dinamis (self-service storage), Kubernetes menyediakan objek StorageClass (SC).

StorageClass bertindak sebagai template atau “resep” pembuatan penyimpanan otomatis (dynamic provisioning). Ketika pengembang membuat PersistentVolumeClaim (PVC) baru yang menunjuk ke nama StorageClass tertentu, objek SC akan menginstruksikan driver CSI (Container Storage Interface) yang sesuai untuk memanggil API cloud provider dan membuat disk fisik secara instan. Artikel ini akan membedah secara mendalam anatomi manifes StorageClass, alur dynamic provisioning di balik layar, penyelesaian masalah zona melalui binding mode, parameter kustom driver cloud populer, hingga strategi penataan multi-storage class di produksi.


Alur Kerja Dynamic Provisioning dan Hubungannya dengan CSI #

Dynamic provisioning mengubah cara kluster mengelola siklus hidup penyimpanan. Kita tidak lagi membutuhkan intervensi manual administrator untuk membuat PV. Begitu PVC dideklarasikan, control plane akan berkoordinasi dengan driver CSI untuk menyiapkan hardware storage di belakang layar.

Berikut adalah diagram alur keputusan logis bagaimana volumeBindingMode memengaruhi proses penjadwalan dan pembuatan PV:

flowchart TD
    PVC_Create["User Membuat PVC Baru (Pending)"] --> BindingModeCheck{"volumeBindingMode?"}
    
    BindingModeCheck -- "Immediate" --> ProvisionImmediate["CSI Driver Langsung Membuat Disk Fisik & PV"]
    ProvisionImmediate --> BindImmediate["PVC Bound ke PV Baru"]
    BindImmediate --> PodSchedule1["Scheduler Mencoba Menjadwalkan Pod"]
    PodSchedule1 --> ZoneCheck1{"Apakah Zone Node =\nZone Disk Fisik?"}
    ZoneCheck1 -- "Tidak" --> StuckPending1["Pod Stuck (Volume Node Affinity Conflict)"]
    ZoneCheck1 -- "Ya" --> Running1["Pod Berhasil Berjalan"]
    
    BindingModeCheck -- "WaitForFirstConsumer" --> PodWait["Tunda Provisioning. Tunggu Pod Menggunakan PVC Dibuat."]
    PodWait --> PodSchedule2["Scheduler Memilih Node yang Tepat (Topology-Aware)"]
    PodSchedule2 --> ProvisionDelay["CSI Driver Membuat Disk Fisik di Zone Node Terpilih"]
    ProvisionDelay --> BindDelay["PVC Bound ke PV di Zone yang Sama"]
    BindDelay --> Running2["Pod Berhasil Berjalan (100% Lolos Zone Mismatch)"]

Anatomi Manifes StorageClass #

Berikut adalah contoh manifest StorageClass tingkat produksi untuk cloud AWS yang dikonfigurasikan dengan performa tinggi dan fitur keamanan enkripsi aktif:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: premium-ssd-sc
  annotations:
    # Menandakan class ini sebagai default di kluster:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com          # Driver CSI yang bertanggung jawab
reclaimPolicy: Retain                 # Retain | Delete (Default)
allowVolumeExpansion: true            # Mengizinkan PVC diperbesar secara online
volumeBindingMode: WaitForFirstConsumer # WaitForFirstConsumer | Immediate
parameters:                           # Parameter kustom spesifik driver CSI
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
mountOptions:                         # Opsi mount filesystem Linux
  - noatime
  - nodiratime

Penjelasan Parameter Kunci: #

1. provisioner #

Menentukan driver penyimpanan (CSI plugin) mana yang akan dipanggil untuk memproses pembuatan volume fisik. Setiap cloud provider atau produsen storage on-premise memiliki driver-nya masing-masing:

  • AWS EBS: ebs.csi.aws.com
  • GCP Persistent Disk: pd.csi.storage.gke.io
  • Azure Disk: disk.csi.azure.com
  • NFS Server: nfs.csi.k8s.io
  • Ceph RBD: rbd.csi.ceph.com

2. reclaimPolicy #

Menentukan kebijakan daur hidup PV yang akan dibuat secara otomatis oleh class ini.

  • Delete (Default): Disk fisik di cloud akan langsung dihapus otomatis ketika objek PVC dihapus oleh user.
  • Retain: Disk fisik di cloud tetap dipertahankan (status PV menjadi Released) untuk mengamankan data jika PVC terhapus secara tidak sengaja.

3. allowVolumeExpansion #

Ketika diatur sebagai true, parameter ini mengizinkan kita memperbesar kapasitas penyimpanan PVC secara deklaratif (misalnya menaikkan kapasitas dari 50GB ke 100GB pada YAML PVC) tanpa harus menghancurkan Pod atau mematikan aplikasi.

4. mountOptions #

Daftar opsi tambahan yang akan diteruskan ke perintah mount Linux di node worker saat volume dipasang ke kontainer. Menyetel opsi seperti noatime dan nodiratime sangat direkomendasikan untuk beban kerja database karena mengabaikan pembaruan stempel waktu akses (access timestamp update) pada filesystem, yang secara signifikan dapat meningkatkan performa I/O.


Volume Binding Mode: Solusi Problem Multi-Zone #

Salah satu keputusan arsitektural terpenting saat menulis StorageClass adalah menentukan nilai volumeBindingMode. Kubernetes menyediakan dua opsi: Immediate dan WaitForFirstConsumer.

1. Mode Immediate (Default) #

Ketika PVC dibuat, StorageClass akan langsung menghubungi cloud API untuk membuat disk fisik secara instan, bahkan sebelum Pod yang menggunakan PVC tersebut selesai dijadwalkan oleh scheduler.

  • Masalah di Multi-Zone Cloud: Cloud provider harus memilih Availability Zone (AZ) saat membuat disk fisik (misalnya membuat disk gp3 di zona ap-southeast-1a). Namun, setelah disk dibuat, scheduler mendeteksi bahwa node worker di zona ap-southeast-1a sedang penuh. Scheduler terpaksa menempatkan Pod kita di node worker zona ap-southeast-1b.
  • Konsekuensi: Pod di zona ap-southeast-1b tidak dapat me-mount disk fisik yang berada di zona ap-southeast-1a. Pod akan stuck selamanya di status ContainerCreating dengan pesan error: volume node affinity conflict.

2. Mode WaitForFirstConsumer (Sangat Direkomendasikan) #

Ketika PVC dibuat, StorageClass akan menunda pembuatan disk fisik. PVC akan dibiarkan berstatus Pending sementara waktu.

  • Cara Kerjanya: Kube-scheduler akan memproses Pod terlebih dahulu. Scheduler memilih node worker terbaik di zona yang sehat (misalnya terpilih node di zona ap-southeast-1b).
  • Eksekusi CSI: Setelah node worker terpilih secara definitif, StorageClass baru akan memicu pembuatan disk fisik secara dinamis di zona yang sama dengan lokasi node worker tersebut (ap-southeast-1b).
  • Hasil: Proses mounting dijamin 100% sukses tanpa ada konflik multi-zona.

Parameter Driver CSI Populer di Cloud dan On-Premise #

Blok parameters bersifat fleksibel dan isinya sepenuhnya tergantung pada dokumentasi teknis driver CSI masing-masing vendor storage. Berikut adalah beberapa contoh konfigurasi parameters produksi yang umum digunakan:

1. Amazon Web Services (AWS EBS CSI) #

parameters:
  type: gp3                          # Tipe disk (gp3 | io2 | st1)
  iops: "3000"                       # IOPS dasar gp3
  throughput: "125"                  # Throughput dalam MiB/s
  encrypted: "true"                  # Aktifkan enkripsi disk di tingkat hypervisor AWS
  kmsKeyId: "arn:aws:kms:us-east-1:123456789012:key/abc-123" # KMS key kustom

2. Google Cloud Platform (GCP PD CSI) #

parameters:
  type: pd-balanced                  # Tipe disk GCE (pd-standard | pd-balanced | pd-ssd)
  replication-type: regional-pd      # Membuat replikasi data otomatis di 2 zona (HA)

3. Microsoft Azure (Azure Disk CSI) #

parameters:
  skuName: Premium_LRS               # SKU Azure (Standard_LRS | Premium_LRS | UltraSSD_LRS)
  cachingMode: ReadOnly              # Cache I/O Azure (None | ReadOnly | ReadWrite)

4. On-Premise Ceph RBD (Ceph CSI) #

parameters:
  clusterID: "ceph-prod-cluster-id"
  pool: "kubernetes-rbd-pool"
  imageFeatures: "layering"
  csi.storage.k8s.io/provisioner-secret-name: "ceph-csi-secret"
  csi.storage.k8s.io/provisioner-secret-namespace: "kube-system"

Tata Kelola Default StorageClass di Kluster #

Di setiap kluster Kubernetes, kita dapat menetapkan salah satu StorageClass sebagai Default StorageClass. Ketika developer membuat PVC tanpa mendefinisikan properti storageClassName, Kubernetes akan secara otomatis menggunakan class default tersebut untuk melakukan provisioning.

1. Menandai StorageClass Sebagai Default #

Kita menetapkan class default dengan menyematkan anotasi storageclass.kubernetes.io/is-default-class: "true" pada metadata SC.

# Contoh melihat StorageClass default yang aktif (ditandai dengan kata '(default)')
kubectl get storageclass

Output:

NAME                 PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      AGE
standard-hdd         pd.csi.storage.gke.io   Delete          Immediate              365d
premium-ssd (default)pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   365d

2. Mengubah Default StorageClass via CLI #

Jika kita ingin memindahkan status default dari standard-hdd ke premium-ssd, kita dapat menjalankan perintah anotasi CLI berikut:

# Langkah 1: Hapus anotasi default dari class lama
kubectl annotate storageclass standard-hdd storageclass.kubernetes.io/is-default-class- --overwrite

# Langkah 2: Tambahkan anotasi default ke class baru
kubectl annotate storageclass premium-ssd storageclass.kubernetes.io/is-default-class="true" --overwrite

Strategi Multi-StorageClass untuk Kebutuhan Produksi #

Di lingkungan produksi yang kompleks, jangan pernah menyediakan hanya satu StorageClass tunggal untuk seluruh beban kerja. Kita harus membagi StorageClass berdasarkan profil beban kerja aplikasi untuk mengoptimalkan biaya dan keandalan operasional.

Berikut adalah tabel rancangan pembagian StorageClass yang direkomendasikan:

Nama StorageClass Penggunaan Utama Reclaim Policy Binding Mode Parameter Kunci
database-storage-sc Database Utama (Postgres, MariaDB, Kafka) Retain (Proteksi Data) WaitForFirstConsumer SSD / Premium / IOPS Tinggi / Enkripsi Aktif
app-default-sc Aplikasi Stateless (Log Cache, Node Cache) Delete (Pembersihan Cepat) WaitForFirstConsumer Balanced SSD / IOPS Standar / Biaya Efisien
archive-storage-sc Backup / Analisis / File Log Arsip Retain WaitForFirstConsumer Cold HDD / Throughput Tinggi / Biaya Sangat Murah

Anti-Pattern Terkait StorageClass & Solusinya #

Berikut adalah tiga kesalahan konfigurasi StorageClass yang paling sering menimbulkan kegagalan operasional di produksi:

Anti-Pattern 1: Menggunakan mode Immediate pada Kluster Cloud Multi-Zona #

Membiarkan properti volumeBindingMode default ke Immediate pada kluster cloud yang berjalan di beberapa availability zones.

ANTI-PATTERN: volumeBindingMode: Immediate pada Kluster GKE/EKS Multi-AZ
// KITA MELAKUKAN:
- Kita mendeploy kluster PostgreSQL dengan StorageClass yang memiliki volumeBindingMode: Immediate.

// KONSEKUENSI DI PRODUKSI:
- PVC langsung memicu pembuatan disk cloud di Zona A.
- Namun, Pod database PostgreSQL dijadwalkan di Zona B karena node di Zona A sedang overload.
- Pod PostgreSQL stuck selamanya di status `ContainerCreating` karena disk fisik di Zona A tidak 
  bisa ditempelkan ke node worker di Zona B, melumpuhkan ketersediaan database.
✓ SOLUSI YANG BENAR:
- Selalu gunakan `volumeBindingMode: WaitForFirstConsumer` pada semua StorageClass 
  yang berjalan di lingkungan kluster multi-zona cloud.

Anti-Pattern 2: Menyetel reclaimPolicy: Delete pada StorageClass Database Utama #

Mengabaikan konfigurasi reclaimPolicy sehingga default ke Delete pada StorageClass khusus database penting.

ANTI-PATTERN: reclaimPolicy: Delete untuk db-storage-sc
// KITA MELAKUKAN:
- Kita membiarkan default `reclaimPolicy: Delete` pada StorageClass yang digunakan oleh PVC StatefulSet database PostgreSQL.
- Developer secara tidak sengaja menghapus manifest StatefulSet atau PVC saat melakukan pembersihan environment.

// KONSEKUENSI DI PRODUKSI:
- Penghapusan Disk Fisik Seketika: Begitu PVC terhapus dari kluster, Storage Controller langsung 
  mengirim instruksi API ke cloud provider untuk menghapus volume disk fisik secara permanen.
- Seluruh data transaksi produksi hilang tanpa sisa dan tidak dapat dipulihkan.
✓ SOLUSI YANG BENAR:
- Selalu setel `reclaimPolicy: Retain` secara eksplisit pada StorageClass yang dikhususkan untuk 
  menyediakan volume penyimpanan bagi database stateful kritis.

Anti-Pattern 3: Lupa Mengonfigurasi allowVolumeExpansion: true #

Membuat StorageClass tanpa menyertakan properti allowVolumeExpansion karena menganggap kapasitas disk yang disewa saat ini sudah cukup besar.

ANTI-PATTERN: allowVolumeExpansion Dibiarkan Kosong (Default: false)
// KITA MELAKUKAN:
- Kita mendeploy database pada volume 50GB dengan StorageClass tanpa deklarasi `allowVolumeExpansion`.
- Enam bulan kemudian, disk database penuh hingga 99% akibat pertumbuhan data.

// KONSEKUENSI DI PRODUKSI:
- Sistem Kunci: Database menolak menerima data penulisan baru karena disk penuh (*read-only lock*).
- Kita mencoba mengubah kapasitas PVC menjadi 100GB, namun API Server Kubernetes langsung menolak request 
  tersebut dengan pesan error: `Forbidden: volume expansion is not allowed by the StorageClass`.
- Kita terpaksa melakukan maintenance window downtime yang lama untuk memindahkan data secara manual ke disk baru.
✓ SOLUSI YANG BENAR:
- Selalu aktifkan properti `allowVolumeExpansion: true` pada semua StorageClass produksi guna 
  memberikan ruang bagi tim operasional untuk melakukan penskalan kapasitas disk secara online tanpa downtime.

Ringkasan #

  • Template Dynamic Provisioning — StorageClass bertindak sebagai template otomatisasi pembuatan PV fisik secara dinamis melalui interaksi dengan driver CSI cloud provider.
  • WaitForFirstConsumer Wajib — Gunakan binding mode WaitForFirstConsumer pada kluster multi-zona cloud untuk menghindari kesalahan fatal zone-mismatch antara disk dan Pod.
  • Reclaim Policy Retain untuk DB — Lindungi data database kritis dengan menyetel reclaimPolicy: Retain pada StorageClass database agar disk fisik tidak dihapus saat PVC didelete.
  • Aktifkan allowVolumeExpansion — Selalu sertakan properti allowVolumeExpansion: true pada StorageClass produksi agar kapasitas disk dapat diperbesar secara online saat penuh.
  • Opsi Mount noatime — Manfaatkan mountOptions dengan opsi noatime pada StorageClass database untuk meningkatkan kecepatan transaksi I/O disk secara signifikan.
  • Dekopling CSI Driver — Kelola driver storage modern menggunakan plugin CSI eksternal (seperti ebs.csi.aws.com), membebaskan kluster dari dependensi kode bawaan.
  • Rancang Multi-Class — Pembagian StorageClass yang jelas (DB Class, App Class, Archive Class) mengoptimalkan performa I/O dan efisiensi biaya sewa cloud.

← Sebelumnya: PersistentVolumeClaim   Berikutnya: Database di Kubernetes →

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