@@ -34,14 +34,40 @@ The system automatically backs up PVCs to NFS storage on TrueNAS using **Kopia**
3434│ (NFS inject) │ └────────┬────────┘
3535└─────────────────┘ │
3636 ▼
37- ┌─────────────────┐ ┌─────────────────┐
38- │ TrueNAS NFS │◀────│ Kyverno │
39- │ volsync-kopia- │ │ ClusterPolicy │
40- │ nfs │ │ (generates │
37+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
38+ │ TrueNAS NFS │◀────│ Kyverno │◀────│ pvc-plumber │
39+ │ volsync-kopia- │ │ ClusterPolicy │ │ (backup check) │
40+ │ nfs │ │ (generates │ └─────────────────┘
4141└─────────────────┘ │ resources) │
4242 └─────────────────┘
4343```
4444
45+ ## Automatic Restore Flow
46+
47+ When a PVC is created with a backup label, the system automatically checks if a backup exists and restores it:
48+
49+ ```
50+ PVC Created ──▶ Kyverno Rule 0 ──▶ Calls pvc-plumber ──▶ Backup exists?
51+ │
52+ ┌─────────────────────────────────────────┴─────────┐
53+ │ YES │ NO
54+ ▼ ▼
55+ Add dataSourceRef No mutation
56+ to PVC spec (fresh PVC)
57+ │
58+ ▼
59+ VolSync populates PVC
60+ from Kopia backup
61+ │
62+ ▼
63+ PVC becomes Bound ──▶ Kyverno Rule 2 ──▶ Creates ReplicationSource
64+ (backup schedule starts)
65+ ```
66+
67+ ** Key protections:**
68+ - Backup ReplicationSource only created AFTER PVC is Bound (prevents backup/restore conflicts)
69+ - Restore uses VolumePopulator pattern (dataSourceRef) for atomic restore
70+
4571## Components
4672
4773### 1. TrueNAS NFS Storage
@@ -54,19 +80,25 @@ The system automatically backs up PVCs to NFS storage on TrueNAS using **Kopia**
5480- Mounts ` /repository ` from TrueNAS NFS share
5581- No per-app configuration needed
5682
57- ### 3. Kyverno ClusterPolicy
83+ ### 3. pvc-plumber
84+ - HTTP service that checks if a backup exists in Kopia repository
85+ - Called by Kyverno before creating a PVC to determine if restore is needed
86+ - Image: ` ghcr.io/mitchross/pvc-plumber `
87+ - Endpoint: ` GET /exists/{namespace}/{pvc} ` returns ` {"exists": true/false} `
88+
89+ ### 4. Kyverno ClusterPolicy
5890- Triggers on PVCs with label ` backup: hourly ` or ` backup: daily `
59- - Generates:
60- - ExternalSecret (fetches KOPIA_PASSWORD from 1Password)
61- - ReplicationSource (backup schedule)
62- - ReplicationDestination (restore capability)
91+ - ** Rule 0 (mutate): ** Calls pvc-plumber; if backup exists, adds ` dataSourceRef ` to trigger restore
92+ - ** Rule 1 (generate): ** Creates ExternalSecret (fetches KOPIA_PASSWORD from 1Password)
93+ - ** Rule 2 (generate): ** Creates ReplicationSource (backup schedule) - only after PVC is Bound
94+ - ** Rule 3 (generate): ** Creates ReplicationDestination (restore capability)
6395
64- ### 4 . VolSync
96+ ### 5 . VolSync
6597- Performs actual backup/restore operations using ** Kopia**
6698- Uses Longhorn snapshots for consistent backups
6799- Stores data on NFS with Kopia encryption and zstd compression
68100
69- ### 5 . Kopia UI (Optional)
101+ ### 6 . Kopia UI (Optional)
70102- Web interface to browse backups
71103- Accessible at ` kopia-ui.{domain} `
72104- Mounts same NFS share as VolSync
@@ -214,6 +246,7 @@ The following namespaces are excluded from automatic backup:
214246
215247| File | Purpose |
216248| ------| ---------|
249+ | ` infrastructure/controllers/pvc-plumber/ ` | Backup existence checker service |
217250| ` infrastructure/storage/volsync/ ` | VolSync Helm chart |
218251| ` infrastructure/controllers/kyverno/policies/volsync-nfs-inject.yaml ` | Injects NFS mount into mover pods |
219252| ` infrastructure/storage/kopia-ui/ ` | Kopia web UI for browsing backups |
0 commit comments