Set spec.clusterTemplate on an OpenBaoRestore to have the operator create a new target cluster and restore into
it. Because the target starts empty, the operator can confirm that the snapshot applied.
To provision the target yourself, use a restore request for an existing cluster or follow Restore a snapshot manually.
Before you begin
- The namespace is enrolled with the operator and approved for restore targets. See Prepare a recovery namespace.
- The required unseal, storage, and TLS credentials are available in that namespace.
- The original unseal key material decrypts the source snapshot.
force: truebypasses OpenBao’s seal-consistency check; it does not make an incompatible key usable. - The profile is one OpenBao 2.7.0 or 2.7.1 voter, matching the snapshot source version, with
OperatorManagedorExternalTLS.unsealuses the same provider configuration asOpenBaoCluster. Supply required KMS plugins, credentials, workload identity, and network access, and rehearse your provider before relying on it. - You know the source cluster’s native ID, version, and ideally digest and size. The operator records them for each
successful backup in
status.backup.latestSnapshoton the source cluster; copy them before an outage. - You have
createonopenbaoclusters,geton the referenced unseal and image pull Secrets, anduseon the StorageClass and any ServiceAccount in the destination namespace.
Admission requires these fields whenever spec.clusterTemplate is set:
targetLifecycleandforce: true.source.expectedClusterID, andsource.expectedVersionequal toclusterTemplate.version.- No
jwtAuthRole,tokenSecretRef, oroverrideOperationLock; the operator bootstraps the target itself.
Restore in another Kubernetes cluster
Create the OpenBaoRestore in the recovery Kubernetes cluster. Its operator creates and manages the target locally.
The source Kubernetes API does not need to be available after you have the snapshot and its metadata.
- Install the operator in the recovery cluster and prepare an approved recovery namespace.
- Provide access to the snapshot object and the original unseal key independently of the source cluster. Record the snapshot key, native cluster ID, version, digest, and size before an outage.
- Apply the request below through the recovery cluster’s kubeconfig. Use destination-local Secret references and endpoint addresses that the recovery workloads can reach.
- For
Disposable, wait for application confirmation and target cleanup. It does not require restored JWT trust repair. - For
Retain, inspect the restored data through an administrator login that works without the source Kubernetes API. Repair controller and lifecycle JWT trust, then acknowledgeResume. Wait for the managed restart and check the retained target before admitting application traffic.
Scheduled spec.backup.restoreTest runs within one Kubernetes cluster. A test in another Kubernetes cluster starts
with an administrator-created OpenBaoRestore; the operator does not discover remote backups or schedule remote runs.
Create the request
For KMS plugins distributed as OCI images, set spec.clusterTemplate.configuration.plugin.autoDownload: true.
This applies to AWS, Azure, GCP, OCI, PKCS#11, and custom KMS plugins. Declaring plugins alone does not download
their binaries: OpenBao defaults automatic downloads to false.
The target needs registry access and a compatible seal key. Images with preinstalled plugin binaries can use
command declarations and leave automatic downloads disabled.
Add this fragment beside clusterTemplate.plugins when the target downloads its plugins:
spec:
clusterTemplate:
configuration:
plugin:
autoDownload: true
The plugin settings use the same fields as OpenBaoCluster.spec.configuration.plugin. Other server configuration
fields are not exposed by the restore template.
Select destination Service IP families
Set spec.clusterTemplate.service to create an optional ClusterIP Service for the target. For example, this fragment
requires both Service IP families with IPv6 first:
spec:
clusterTemplate:
service:
ipFamilyPolicy: RequireDualStack
ipFamilies: [IPv6, IPv4]
Choose families supported by the recovery Kubernetes cluster. The operator does not inherit the source cluster’s
Service settings or restore its allocated Service IPs. If you omit service, the target has only its internal headless
Service, which publishes both families when the cluster supports them. An empty service: {} creates a client Service
with Kubernetes defaults. These fields do not change Pod IP allocation.
Select the primary family before target creation. Kubernetes does not permit changing an existing Service’s primary family. See IPv6 and dual-stack networks.
Transit example
For a Transit target, apply this request after replacing the source identity and storage settings:
apiVersion: openbao.org/v1alpha1
kind: OpenBaoRestore
metadata:
name: recovery-20261005
namespace: recovery
spec:
cluster: recovery-20261005
targetLifecycle: Retain
force: true
source:
target:
provider: s3
endpoint: https://storage.example.com
bucket: snapshots
credentialsSecretRef:
name: recovery-storage
key: clusters/production/snapshot.snap
expectedClusterID: REPLACE_WITH_SOURCE_NATIVE_CLUSTER_ID
expectedVersion: "2.7.1"
# Recommended: expectedDigest: sha256:<64 lowercase hexadecimal characters>
# Optional: expectedSize: <snapshot bytes>
clusterTemplate:
version: "2.7.1"
storage:
size: 10Gi
tls:
enabled: true
mode: OperatorManaged
rotationPeriod: 720h
unseal:
type: transit
credentialsSecretRef:
name: recovery-transit
transit:
address: https://seal.example.com:8200
mountPath: transit
keyName: production-unseal
tlsCACert: /etc/bao/seal-creds/ca.crt
The operator creates the cluster and waits up to about 30 minutes for it to bootstrap. It then runs the normal
restore executor. Within about 10 minutes of submission, the target must report the expected identity, which sets
status.target.appliedAt.
Before Resume, the target has no Kubernetes API token, service registration, or peer discovery. The operator installs
no NetworkPolicies or published endpoints for it.
During Resume, the operator prepares the normal configuration and Kubernetes API token mount under the restore hold.
It keeps automatic rollouts stopped and replaces the target Pod through the managed restart. It releases the hold only
after the replacement uses the prepared template and passes readiness, health, and controller authentication checks.
Normal reconciliation then resumes without a second Pod rollout.
Choose a lifecycle
targetLifecycle | Outcome |
|---|---|
Retain | Keeps the cluster and storage. Inspect it, repair controller JWT trust if needed, then acknowledge as in Recover an uncertain restore. Resume on a confirmed target ends Completed. Abandon keeps the phase Unknown and the cluster paused. A failure before submission leaves the target paused for you. |
Disposable | Deletes the restore Job, the target, and its data PVC once the restore finishes or fails. Set cleanupAfterSeconds (up to 86400) to keep a confirmed target for inspection first. Resume is not supported. status.target.cleanup reports Pending, Complete, or Failed. |
Resolve blocked cleanup
Cleanup ends Failed when a recorded cluster or PVC was replaced, or a PVC lacks proof that the target created it.
The operator still deletes the cluster it created; it leaves the refused PVC for inspection.
- Compare the live objects with the UIDs in
status.target. - Delete or retain those resources yourself.
- Annotate the request with
openbao.org/restore-acknowledge=<restore-UID>/Abandon.
The request ends Failed, and the operator permits deleting it. Replacement resources stay untouched, and cleanup
stays Failed.