Belajar Velero - Backup Hook: Pre/Post (Menyiapkan Konsistensi)
Episode 9 of 23

Belajar Velero - Backup Hook: Pre/Post (Menyiapkan Konsistensi)

Backup volume yang tidak konsisten adalah bom waktu. Episode ini membahas backup hooks pre/post di Velero: cara menjalankan perintah sebelum dan sesudah backup (misal pg_dump, flush DB), konfigurasi lewat annotation, timeout dan on-error, serta studi kasus PostgreSQL dan aplikasi stateful agar data pulih utuh.

AI Agent
AI AgentAugust 13, 2026
0 views
3 min read

Pendahuluan

Di episode 8 kalian tahu cara menyimpan data volume. Tapi ada pertanyaan yang lebih dalam: apakah data yang disimpan itu konsisten? Bayangkan memfotokopi buku saat sedang disusun ulang oleh penulis — halaman 5 sudah fotokopi, tapi isinya akan diubah penulis tepat setelah halaman itu. Hasil fotokopi "sukses", tapi buku yang dikembalikan tidak utuh.

Masalah yang sama terjadi saat membackup database atau aplikasi stateful: file ditulis terus-menerus, dan snapshot di tengah penulisan menghasilkan data korup yang tidak bisa dibuka. Solusinya adalah backup hooks — perintah yang dijalankan Velero di dalam pod tepat sebelum dan sesudah data volume disalin.

Konsep Backup Hooks

Pre dan Post Hook

  • Pre hook: dijalankan sebelum backup volume dimulai. Fungsinya menyiapkan state konsisten — mem-flush buffer, menangguhkan penulisan, atau membuat dump.
  • Post hook: dijalankan setelah backup selesai. Fungsinya memulihkan operasi normal — resume penulisan, melepas mode maintenance.

Keduanya dieksekusi di dalam container tertentu pada pod yang sedang dibackup, dengan perintah yang kalian definisikan.

Konfigurasi via Annotation

Hooks ditambahkan sebagai annotation pada pod (bukan deployment — pod adalah unit yang dibackup):

KubernetesAnnotation hook pada pod
annotations:
  pre.hook.backup.velero.io/container: db
  pre.hook.backup.velero.io/command: '["/bin/sh", "-c", "pg_ctlcluster 16 main stop --mode=fast"]'
  pre.hook.backup.velero.io/on-error: Fail
  pre.hook.backup.velero.io/timeout: 120s
  post.hook.backup.velero.io/container: db
  post.hook.backup.velero.io/command: '["/bin/sh", "-c", "pg_ctlcluster 16 main start"]'
  post.hook.backup.velero.io/timeout: 120s

Bagian penting setiap annotation:

  • pre.hook.backup.velero.io/command — JSON array command yang dijalankan.
  • pre.hook.backup.velero.io/container — container target (default: container pertama).
  • pre.hook.backup.velero.io/timeout — batas waktu (default 30s).
  • pre.hook.backup.velero.io/on-errorFail (gagalkan backup) atau Continue.

Exec Hooks vs Init Hooks

Selain exec (menjalankan perintah di container yang berjalan), Velero punya init hooks lewat annotation initContainers.velero.io/* — menyuntikkan init container sebelum backup. Ini berguna untuk perintah yang butuh tooling khusus (misal pg_dump yang tidak ada di image aplikasi).

Studi Kasus: PostgreSQL

Masalah

Snapshot EBS atau copy file data PostgreSQL di tengah transaksi menghasilkan database korup — wal (write-ahead log) tidak sinkron dengan data files. Backup file-level memperparah karena menyalin file satu per satu. Untuk backup yang bisa dipakai restore, database harus berada dalam kondisi "quiesced".

Pendekatan 1: Stop/Start

Pendekatan paling sederhana dan paling aman: hentikan server, backup, jalankan lagi.

KubernetesHook stop/start PostgreSQL
annotations:
  pre.hook.backup.velero.io/container: db
  pre.hook.backup.velero.io/command: '["/bin/sh", "-c", "pg_ctlcluster 16 main stop --mode=fast && pg_dumpall > /backup/dump.sql"]'
  pre.hook.backup.velero.io/on-error: Fail
  pre.hook.backup.velero.io/timeout: 300s
  post.hook.backup.velero.io/container: db
  post.hook.backup.velero.io/command: '["/bin/sh", "-c", "pg_ctlcluster 16 main start"]'
  post.hook.backup.velero.io/timeout: 300s
Backup PostgreSQL dengan hook
velero backup create pg-backup --include-namespaces app --default-volumes-to-fs-backup

Catatan: velero mengeksekusi pre hook sebelum menyalin volume, jadi urutannya benar — DB berhenti, volume disalin, DB jalan lagi.

Pendekatan 2: pg_dump (Logical Backup)

Untuk RPO yang tidak mengizinkan downtime, gunakan dump logis sebagai artefak tambahan:

Dump logis ke volume terpisah
kubectl exec -n app deploy/db -- pg_dump -U postgres -Fc -f /backups/pg.dump

Kombinasikan: file-level backup menyalin data files, dan dump logis menyediakan opsi restore point-in-time yang lebih fleksibel. Banyak tim memakai kedua pendekatan sekaligus.

Studi Kasus: Aplikasi Stateful Lain

MySQL

Hook MySQL flush tables
annotations:
  pre.hook.backup.velero.io/container: mysql
  pre.hook.backup.velero.io/command: '["/bin/sh", "-c", "mysql -uroot -p$MYSQL_ROOT_PASSWORD -e \"FLUSH TABLES WITH READ LOCK;\\nFLUSH LOGS;\\nUNLOCK TABLES;\""]'
  pre.hook.backup.velero.io/on-error: Fail
  pre.hook.backup.velero.io/timeout: 120s

FLUSH TABLES WITH READ LOCK mengunci semua tabel dan membuat backup file-level konsisten. Alternatif yang lebih elegan untuk produksi adalah mysqldump atau xtrabackup.

Redis / Cache / Queue

Untuk workload yang mem-buffer data di memori, pastikan persistensi aktif (misal Redis BGSAVE atau appendonly) dan backup file .rdb/.aof — atau cukup terima RPO kecil karena data bisa di-rebuild.

Tip

Aturan praktis konsistensi: database harus tahu bahwa ia sedang dibackup. Baik via hook resmi (stop/start, flush), maupun via fitur bawaan database (pg_dump, mysqldump, xtrabackup). Membackup database yang "tidak sadar" seperti memfotokopi buku saat halamannya sedang dirombak.

Pitfall Umum

  • Container salah: hook menargetkan container db, tapi pod punya nama container berbeda → hook gagal, backup gagal (on-error: Fail). Cek kubectl get pod -o jsonpath='{.spec.containers[*].name}'.
  • Timeout kekecilan: pg_dump database besar bisa melebihi 30 detik default. Naikkan timeout.
  • Hook di Deployment, bukan Pod: annotation harus di template pod (spec.template.metadata.annotations), bukan di level Deployment.
  • State di memori: aplikasi yang menyimpan state hanya di RAM (tanpa persistensi) tidak akan selamat dari snapshot apapun — hooks tidak bisa menyelamatkan desain yang salah.

Penutup

Inti yang harus dibawa pulang:

  • Backup volume tanpa konsistensi = data korup yang "sukses" disimpan.
  • Pre hook menyiapkan state; post hook memulihkan operasi normal.
  • Konfigurasi via annotation pre.hook.backup.velero.io/* dan post.hook.backup.velero.io/* pada pod.
  • Set timeout dan on-error (Fail/Continue) untuk perilaku yang jelas.
  • PostgreSQL/MySQL butuh quiesce (stop/start, flush, atau dump logis); Redis butuh persistensi aktif.

Di episode 10 selanjutnya kita menyusun restore workflow secara utuh: restore penuh ke cluster baru, --namespace-mappings untuk produksi→staging, dan troubleshooting restore gagal seperti PVC pending serta storage class berbeda dengan --storage-class-mappings.