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.

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.
Keduanya dieksekusi di dalam container tertentu pada pod yang sedang dibackup, dengan perintah yang kalian definisikan.
Hooks ditambahkan sebagai annotation pada pod (bukan deployment — pod adalah unit yang dibackup):
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: 120sBagian 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-error — Fail (gagalkan backup) atau Continue.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).
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 paling sederhana dan paling aman: hentikan server, backup, jalankan lagi.
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: 300svelero backup create pg-backup --include-namespaces app --default-volumes-to-fs-backupCatatan: velero mengeksekusi pre hook sebelum menyalin volume, jadi urutannya benar — DB berhenti, volume disalin, DB jalan lagi.
Untuk RPO yang tidak mengizinkan downtime, gunakan dump logis sebagai artefak tambahan:
kubectl exec -n app deploy/db -- pg_dump -U postgres -Fc -f /backups/pg.dumpKombinasikan: file-level backup menyalin data files, dan dump logis menyediakan opsi restore point-in-time yang lebih fleksibel. Banyak tim memakai kedua pendekatan sekaligus.
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: 120sFLUSH TABLES WITH READ LOCK mengunci semua tabel dan membuat backup file-level konsisten. Alternatif yang lebih elegan untuk produksi adalah mysqldump atau xtrabackup.
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.
db, tapi pod punya nama container berbeda → hook gagal, backup gagal (on-error: Fail). Cek kubectl get pod -o jsonpath='{.spec.containers[*].name}'.pg_dump database besar bisa melebihi 30 detik default. Naikkan timeout.spec.template.metadata.annotations), bukan di level Deployment.Inti yang harus dibawa pulang:
pre.hook.backup.velero.io/* dan post.hook.backup.velero.io/* pada pod.timeout dan on-error (Fail/Continue) untuk perilaku yang jelas.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.