Volume #

Volume adalah mekanisme di Kubernetes yang memungkinkan container mengakses storage di luar filesystem ephemeral mereka sendiri. Berbeda dari konsep volume di Docker yang lebih sederhana, volume Kubernetes punya lifecycle yang terikat ke Pod dan mendukung puluhan jenis backend — dari direktori di node hingga disk cloud, dari NFS hingga secret yang di-inject sebagai file. Memahami jenis-jenis volume dan cara kerjanya adalah fondasi sebelum masuk ke PersistentVolume dan StorageClass.

Cara Volume Bekerja di Pod #

Volume didefinisikan di level Pod (bukan di level container), lalu di-mount ke dalam container yang membutuhkannya. Ini memungkinkan beberapa container dalam Pod yang sama mengakses volume yang sama.

spec:
  volumes:              # ← definisi volume di level Pod
  - name: data
    emptyDir: {}
  - name: config
    configMap:
      name: app-config

  containers:
  - name: app
    volumeMounts:       # ← mount ke dalam container
    - name: data
      mountPath: /var/data
    - name: config
      mountPath: /etc/config
      readOnly: true

  - name: sidecar
    volumeMounts:
    - name: data        # ← container lain bisa mount volume yang sama
      mountPath: /shared-data

Setiap volume punya name yang unik dalam Pod. Container me-mount volume berdasarkan nama tersebut ke path yang dikehendaki di dalam filesystem container.


emptyDir #

Volume paling dasar — direktori kosong yang dibuat saat Pod mulai dan dihapus saat Pod mati. Datanya hanya ada selama Pod hidup.

volumes:
- name: cache
  emptyDir: {}                # di filesystem node (disk)

- name: shared-mem
  emptyDir:
    medium: Memory            # di memory (tmpfs) — lebih cepat, tapi pakai RAM
    sizeLimit: "256Mi"        # batas agar tidak makan terlalu banyak RAM

emptyDir dengan medium: Memory berguna untuk:

  • High-speed cache yang butuh latensi sangat rendah
  • Berbagi data antar container dalam volume yang tidak perlu persisten
  • Menghindari disk I/O untuk data sementara

hostPath #

Mount direktori atau file dari filesystem node langsung ke dalam container. Berbahaya jika dipakai sembarangan, tapi ada kasus valid.

volumes:
- name: docker-sock
  hostPath:
    path: /var/run/docker.sock
    type: Socket               # pastikan yang di-mount adalah socket

- name: node-logs
  hostPath:
    path: /var/log
    type: Directory

Tipe yang tersedia untuk hostPath:

DirectoryOrCreate  → buat direktori jika belum ada
Directory          → harus sudah ada, gagal jika tidak
FileOrCreate       → buat file jika belum ada
File               → harus sudah ada
Socket             → Unix socket yang sudah ada
CharDevice         → character device yang sudah ada
BlockDevice        → block device yang sudah ada
hostPath memberi container akses langsung ke filesystem host — ini risiko keamanan yang signifikan. Gunakan hanya untuk kasus yang benar-benar membutuhkannya seperti DaemonSet yang perlu akses ke log node atau socket Docker, dan selalu gunakan readOnly: true jika memungkinkan.

configMap dan secret #

ConfigMap dan Secret bisa di-mount sebagai volume, memungkinkan konfigurasi dan kredensial diakses sebagai file di dalam container. Ini lebih fleksibel dari environment variable untuk konfigurasi yang panjang atau struktural (seperti file YAML atau JSON).

volumes:
- name: app-config
  configMap:
    name: my-configmap
    items:                          # pilih key mana yang di-mount
    - key: nginx.conf
      path: nginx.conf              # nama file di dalam container
    - key: app.yaml
      path: config/app.yaml        # bisa di subdirektori

- name: tls-certs
  secret:
    secretName: tls-secret
    defaultMode: 0400              # permission file (read-only untuk owner)
# Di dalam container, file tersedia di mountPath:
# /etc/nginx/nginx.conf
# /etc/config/app.yaml
# /etc/tls/tls.crt
# /etc/tls/tls.key

Keuntungan mount sebagai file dibanding environment variable: file bisa di-update tanpa restart Pod. Kubernetes memperbarui isi file saat ConfigMap berubah (ada delay sekitar 1-2 menit). Namun aplikasi tetap perlu membaca ulang file tersebut — tidak semua framework melakukannya secara otomatis.


downwardAPI #

Mount informasi tentang Pod itu sendiri sebagai file ke dalam container. Berguna untuk aplikasi yang perlu tahu nama Pod-nya, namespace, atau label-nya sendiri.

volumes:
- name: pod-info
  downwardAPI:
    items:
    - path: "pod-name"
      fieldRef:
        fieldPath: metadata.name
    - path: "pod-namespace"
      fieldRef:
        fieldPath: metadata.namespace
    - path: "cpu-limit"
      resourceFieldRef:
        containerName: app
        resource: limits.cpu

projected #

projected menggabungkan beberapa sumber volume (serviceAccountToken, configMap, secret, downwardAPI) ke dalam satu direktori:

volumes:
- name: all-in-one
  projected:
    sources:
    - configMap:
        name: app-config
    - secret:
        name: app-secret
    - downwardAPI:
        items:
        - path: "pod-name"
          fieldRef:
            fieldPath: metadata.name

Semua sumber akan tersedia dalam satu mountPath — mengurangi jumlah volumeMounts di container.


Volume untuk Cloud Provider #

Setiap cloud provider menyediakan tipe volume khusus untuk storage mereka. Meskipun sekarang penggunaan langsung tipe ini sudah digantikan oleh CSI driver, penting untuk mengenalinya:

# AWS EBS (cara lama, sekarang pakai CSI)
volumes:
- name: data
  awsElasticBlockStore:
    volumeID: vol-0a1b2c3d4e5f
    fsType: ext4

# GCE Persistent Disk (cara lama)
volumes:
- name: data
  gcePersistentDisk:
    pdName: my-data-disk
    fsType: ext4

# Azure Disk (cara lama)
volumes:
- name: data
  azureDisk:
    diskName: myDisk
    diskURI: /subscriptions/.../disks/myDisk

Cara modern: semua ini digantikan oleh CSI (Container Storage Interface) driver yang lebih generik dan tidak terikat ke in-tree code Kubernetes.


CSI Volume #

Container Storage Interface adalah standar yang memungkinkan vendor storage mengembangkan driver mereka sendiri tanpa harus memodifikasi kode Kubernetes itu sendiri.

# Volume menggunakan CSI driver
volumes:
- name: data
  csi:
    driver: disk.csi.azure.com     # nama CSI driver yang ter-install
    volumeAttributes:
      skuName: Premium_LRS
    nodeStageSecretRef:
      name: azure-disk-secret
      namespace: default

Dalam praktik produksi modern, hampir semua penggunaan persistent storage dilakukan melalui PersistentVolumeClaim yang di-belakangnya menggunakan CSI driver — bukan mendefinisikan CSI volume secara langsung di Pod spec.


subPath: Mount Sebagian Volume #

Terkadang kamu ingin me-mount hanya sebagian dari volume, atau me-mount beberapa bagian ke path yang berbeda:

volumeMounts:
- name: data
  mountPath: /var/lib/postgresql/data
  subPath: postgres               # hanya subdirektori "postgres" di dalam volume

- name: data
  mountPath: /var/lib/redis/data
  subPath: redis                  # subdirektori "redis" di volume yang sama

Pola ini berguna ketika satu PVC digunakan untuk menyimpan data dari beberapa komponen, masing-masing di subdirektori yang berbeda.


Ringkasan #

  • Volume didefinisikan di level Pod, di-mount di level container — satu volume bisa di-mount oleh beberapa container dalam Pod yang sama.
  • emptyDir untuk data sementara dalam Podmedium: Memory untuk performa tinggi, tapi ingat ini mengonsumsi RAM node.
  • hostPath hanya untuk kasus khusus — DaemonSet yang perlu akses log node atau socket; selalu batasi dengan readOnly: true dan type yang tepat.
  • configMap dan secret sebagai file — lebih fleksibel dari env var untuk konfigurasi panjang; file otomatis diperbarui saat ConfigMap/Secret berubah (dengan delay kecil).
  • CSI adalah standar modern — semua cloud provider dan storage vendor sekarang menggunakan CSI driver; hindari tipe volume in-tree yang sudah deprecated.
  • subPath untuk berbagi satu volume — me-mount subdirektori tertentu dari volume; berguna agar beberapa komponen bisa berbagi satu PVC dengan namespace direktori yang terpisah.

← Sebelumnya: Ephemeral vs Persistent Storage   Berikutnya: Storage Problem di Distributed Systems →

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