Scenario 08 — Clone an app's data into another namespace
Reproduce a prod bug against real data, or seed staging. You want production’s data in a staging or preview namespace. Not a hand-exported dump, the actual latest snapshot, and without touching the production volume.
You do this with a cross-namespace restore: the Restore lives in the destination namespace, and the source reference names the source namespace. The one wrinkle is credentials. The restore mover runs in the destination, so the repository’s credential Secret has to be reachable there.
Step 1 — Make credentials reachable in the destination
Section titled “Step 1 — Make credentials reachable in the destination”The restore mover loads the repository password and any backend credentials with envFrom, from a Secret in its own namespace. A brand-new staging namespace doesn’t have one. You have two options:
- Shared
ClusterRepositoryplus projection, recommended. With a cluster-scoped repository, setcredentialProjection.enabled: trueon theRestore. The operator copies the repository’s Secret intostagingfor the run. The copy is owned by theRestoreand is garbage-collected with it. This needs the operator’s Secret-projection RBAC, which is Helm valuefeatures.credentialProjection.enabled, off by default. - Place the Secret yourself. Copy the repository’s credential Secret into
stagingahead of time and skipcredentialProjection.
Step 2 — Restore prod’s snapshot into the destination
Section titled “Step 2 — Restore prod’s snapshot into the destination”The bundle creates the staging namespace and a Restore. That Restore resolves prod’s latest snapshot with source.fromPolicy and namespace: billing, into a new postgres-data-clone PVC in staging. The mover’s securityContext matches the staging app’s UID so the cloned files are usable.
To clone a specific snapshot instead of the latest, use source.snapshotRef with the prod Snapshot’s name and namespace. See example 16.
# Scenario 08 — Clone an app's data into another namespace (prod → staging)## Reproduce a production bug against REAL data, or seed a staging/preview# environment, by cloning prod's latest snapshot into another namespace. The# `snapshotRef` carries the SOURCE namespace (billing); the Restore and its target PVC# live in the DESTINATION namespace (staging). The restore mover runs in the# destination, so the repo credentials must be readable there — a shared# `ClusterRepository` + `credentialProjection` does that without hand-placing# Secrets.## Field shapes verified against crates/api: source.snapshotRef = { name, namespace? };# credentialProjection = { enabled }; mover.securityContext is a core/v1# SecurityContext.---# The clone target namespace.apiVersion: v1kind: Namespacemetadata: name: staging---apiVersion: kopiur.home-operations.com/v1alpha1kind: Restoremetadata: name: clone-prod-postgres namespace: staging # DESTINATIONspec: repository: kind: ClusterRepository # shared, cluster-scoped — reachable from any namespace name: platform-shared source: fromPolicy: name: postgres-data namespace: billing # SOURCE — resolve prod's latest snapshot by identity target: pvc: name: postgres-data-clone storageClassName: standard # staging can use cheaper storage than prod capacity: 100Gi accessModes: - ReadWriteOnce # Copy the ClusterRepository's credential Secret into `staging` for this run # (owned by this Restore, GC'd with it). Needs Helm features.credentialProjection.enabled. credentialProjection: enabled: true # Run as the staging app's UID so the cloned data is usable. mover: securityContext: runAsUser: 1000 runAsGroup: 1000 runAsNonRoot: true allowPrivilegeEscalation: false capabilities: drop: ["ALL"] seccompProfile: type: RuntimeDefault policy: onMissingSnapshot: Fail waitTimeout: 5m## Then mount postgres-data-clone in your staging Postgres Deployment/StatefulSet and# you have prod data in staging. The prod namespace and volume are never touched.$ kubectl get restore clone-prod-postgres -n staging -wNAME PHASE AGEclone-prod-postgres Resolving 3sclone-prod-postgres Restoring 11sclone-prod-postgres Completed 52sStep 3 — Mount the clone
Section titled “Step 3 — Mount the clone”Point your staging Deployment or StatefulSet at postgres-data-clone and you have production data in staging. The production namespace and its volume are only ever read, never modified.
See also
Section titled “See also”- Example 16: cross-namespace clone restore and example 17: restore from a shared repo with projection.
- Movers, RBAC & credentials: credential projection and the minted mover ServiceAccount.
- Scenario 04, migrate across clusters / namespaces: when it’s a permanent move, not a clone.