Skip to main content
Version: 9.0.11 (latest)

Late Capture of Hook-Created Resources

Late capture lets a resource-bound backupPrehook action declare a resource it creates or updates. Kasten then captures that resource into the restore point in its post-hook state.

Discovery runs before backupPrehook and never runs again during the backup. Without a late-capture declaration, a resource the hook creates never reaches the restore point. Additionally, an updated resource reaches the restore point in its pre-hook state. See Per-Resource Backup Processing.

This page describes the declaration contract. For a complete database dump and replay pattern, see the staging PVC how-to.

Declaration Artifacts​

A backupPrehook output artifact declares a resource when its name starts with lateCapture. Kasten reads this artifact after backupPrehook completes and treats it as a declaration, not as plain metadata. The prefix is case-sensitive. An artifact named LateCapture or latecapture is plain metadata, and Kasten does not capture the resource it describes.

actions:
backupPrehook:
kind: StatefulSet
outputArtifacts:
lateCapture:
keyValue:
apiVersion: "{{ .Phases.createStagingPVC.Output.apiVersion }}"
group: "{{ .Phases.createStagingPVC.Output.group }}"
resource: "{{ .Phases.createStagingPVC.Output.resource }}"
name: "{{ .Phases.createStagingPVC.Output.name }}"
namespace: "{{ .Phases.createStagingPVC.Output.namespace }}"

KubeOps returns these 5 fields as phase outputs automatically. A KubeTask or KubeExec phase can produce the same fields with kando output. A declaration can also set the values directly, without a phase output. See Output Artifacts.

Each artifact declares one resource. A blueprint can declare several resources with one lateCapture-prefixed artifact for each, such as lateCapturePVC1, lateCapturePVC2 and lateCaptureCR.

The following artifact declares a Percona Server for MongoDB backup. It sets group and gives apiVersion as the version only.

outputArtifacts:
lateCaptureCR:
keyValue:
apiVersion: v1
group: psmdb.percona.com
resource: perconaservermongodbbackups
name: "{{ .Phases.createBackup.Output.name }}"
namespace: "{{ .Phases.createBackup.Output.namespace }}"

Declaration Fields​

Every keyValue entry carries the following fields.

Field Required Description
apiVersion Yes API version only, such as v1. Must not include the group.
group Conditional API group of the declared resource. Omit or leave empty for core resources such as PersistentVolumeClaims and ConfigMaps. Required for custom resources.
resource Yes Plural, lowercase resource name, such as persistentvolumeclaims
name Yes Name of the declared resource
namespace Yes Namespace of the declared resource. Must match the bound workload's namespace.

A declaration missing apiVersion, resource, name or namespace fails the backup before Kasten captures anything.

Supported Resource Types​

Late capture supports 3 resource types: PersistentVolumeClaims, ConfigMaps and custom resources.

Kasten rejects a declaration of any other type, including Secrets.

Kasten also rejects certain custom resources it already restores through dedicated handling. Examples include KubeVirt VirtualMachines, CDI DataVolumes and resources Kasten must create before workloads, such as NetworkAttachmentDefinitions.

Common Requirements​

Every declaration must meet the following conditions.

  • The backup is a namespace-scoped application backup. A VM-scoped backup rejects every declaration.
  • The declared resource is in the bound workload's namespace.
  • The declared resource exists when backupPrehook finishes.
  • The policy's resource filters do not exclude the declared resource.

Staging PVC Requirements​

A declared PersistentVolumeClaim must meet these conditions as well.

  • The blueprint is bound to a workload. Kasten treats any resource that owns pods as a workload, including an operator custom resource.
  • The blueprint does not define a backup action.
  • The PersistentVolumeClaim is Bound when backupPrehook finishes. A hook phase that mounts the volume binds it.
  • The PersistentVolumeClaim uses the Filesystem volume mode. Kasten rejects the Block volume mode.
  • The PersistentVolumeClaim uses CSI-provisioned storage.
  • The backupPosthook deletes the PersistentVolumeClaim. See Capture Behavior.

A blueprint bound to a resource that owns no pods has no volume snapshot step. Kasten fails such a declaration rather than restore an empty volume. ConfigMap and custom resource declarations carry no such restriction.

Capture Behavior​

Kasten adds a late-captured PersistentVolumeClaim to the volume snapshot set and snapshots it after backupPrehook completes. The restore point then contains the data the hook wrote.

Kasten captures a declared ConfigMap or custom resource as a resource spec. Only PersistentVolumeClaims join the volume snapshot set.

Reuse across backups follows different rules for each resource type:

  • ConfigMaps and custom resources. If discovery already captured the resource earlier in the same backup, late capture replaces that copy. Leaving the resource on the cluster between backups is safe.
  • PersistentVolumeClaims. The declared volume must not exist before backupPrehook creates it. Kasten fails the whole backup when it already exists.

A crashed or cancelled backup can leave a staging PersistentVolumeClaim behind, because backupPosthook never ran. That volume still holds the dump from the previous run, so a snapshot of it could contain stale data. Kasten fails the next backup that declares the same volume. Delete the leftover PersistentVolumeClaim before you run the next backup.

Restore Behavior​

A restore point stores the lateCapture output artifact and the captured spec for every declared resource. A declared PersistentVolumeClaim also carries a volume snapshot.

Kasten restores a late-captured resource like any other captured resource, with no extra configuration.

A restored staging PersistentVolumeClaim remains in the namespace until the restore hook deletes it. If the volume still exists when the next backup runs, Kasten fails that backup. See Capture Behavior.

A restore action reads the declaration when it lists the artifact name in inputArtifactNames. The action then references the fields through .ArtifactsIn.<artifactName>.KeyValue.<field>. A restorePosthook uses this to find the resource name, even when backupPrehook generated that name. See Input Artifact Names.

actions:
restorePosthook:
kind: StatefulSet
inputArtifactNames:
- lateCapture
phases:
- func: PrepareData
name: replayDump
args:
namespace: "{{ .StatefulSet.Namespace }}"
image: postgres:16
volumes:
"{{ .ArtifactsIn.lateCapture.KeyValue.name }}": /restore
command: ["bash", "-c", "psql -U postgres -f /restore/full.sql"]
failOnError: true

Failure Behavior​

A declaration that Kasten cannot honor fails the whole backup. Kasten does not publish a restore point that omits a declared resource.