Welcome to the first chapter of our deep dive into Velero's Restore Hooks! If you have ever performed a system restore, you know that simply putting files back where they belong isn't always enough. Sometimes, the application needs a little "nudge" to start working correctly again.
Imagine you are moving into a new house.
If you immediately invite guests over (start the application), it will be a disaster. The boxes are there, but the TV isn't plugged in, and the dishes aren't in the cupboards.
Restore Hooks are the steps you take after the boxes arrive but before you invite guests. They allow you to:
Let's say you are restoring a PostgreSQL database. When the database comes up from a backup, it might contain an old "PID file" (a file that says "I am running") from the previous crash. If the database sees this file, it might refuse to start, thinking it's already running.
The Solution: Use a Restore Hook to delete that PID file before the database application tries to start.
Velero provides two main ways (hooks) to perform these actions during a restore. These bring feature parity with Backup Hooks (which you might already use to freeze data before backing up).
In Kubernetes, a Pod can have "InitContainers." These are helper containers that run and complete before your main application container starts.
Velero can automatically inject an InitContainer into your restored Pod.
This involves executing a command directly inside a container.
pg_ctl restart or rm /tmp/session.lock.To solve our PostgreSQL use case (removing the PID file), we don't need to manually edit Kubernetes YAML files. We just tell Velero what we want to do.
Velero allows you to define these hooks in two places:
Here is a simplified conceptual example of what we want to achieve. We want to tell the Pod: "Hey, before you run postgres, run rm /var/run/postgresql/postmaster.pid."
How does Velero actually make this happen? It doesn't magically pause Kubernetes. Instead, it modifies the definition of your application before Kubernetes even sees it.
When you ask Velero to restore a backup, it reads the stored data and reconstructs the Kubernetes objects (like Deployments and Pods).
Here is a sequence diagram illustrating this flow:
While we won't dive deep into the Go code just yet, it's helpful to understand that Velero uses a "Patch" mechanism.
Inside Velero's code structure (specifically in the pkg/restore logic), the restorer looks for specific annotations. If it finds a request for a hook, it creates a structure like this (simplified):
// Conceptual Go code snippet inside Velero's restore logic
// This represents creating the InitContainer definition
initContainer := corev1.Container{
Name: "velero-restore-init",
Image: "alpine:latest", // Or the user's image
Command: []string{"/bin/sh", "-c", "rm /var/run/postmaster.pid"},
VolumeMounts: originalVolumeMounts, // Needs access to the same data
}
// Prepend this container to the Pod's Spec
pod.Spec.InitContainers = append([]corev1.Container{initContainer}, pod.Spec.InitContainers...)
Explanation: The code above creates a standard Kubernetes Container object. Crucially, it copies VolumeMounts so the hook can access the same data files as the main application. Finally, it adds this container to the front of the InitContainers list of the Pod being restored.
In this chapter, we learned:
In the next chapter, we will look at how to define these rules globally using the Restore Custom Resource Definition (CRD).
Next Chapter: Configuration via Restore CRD Spec
Generated by Code IQ