--- # Velero VOLUME POLICIES — the opt-out escape hatch for the external bulk tier (R-STATE-04). # # WHY THIS EXISTS. platform/velero/helmrelease.yaml schedule (1) runs # `defaultVolumesToFsBackup: true` — the OPT-OUT model, so no volume with real data is ever # forgotten. That model collides with the NFS bulk tier prod grew on 2026-09-11: # # plex-media 9Ti claim -> 192.168.2.102:/mnt/Storage/plex (8.32 TiB measured) # sonarr-media 9Ti claim -> the SAME export # radarr-media 9Ti claim -> the SAME export # nextcloud-legacy-archive 270Gi -> 192.168.2.102:/mnt/Storage/nextcloud # # Left to opt-out, one nightly run reads that library THREE TIMES over NFS and pushes ~8.6 TiB at # Cloudflare R2, every night, held for ${VELERO_RETENTION} (prod: 720h). kopia dedups the STORED # bytes, not the reads. That is not DR; it is a self-inflicted outage plus a recurring bill. # # WHY NOT namespace exclusion. plex / sonarr / radarr / nextcloud each ALSO hold a real Longhorn # PVC (plex-config 8Gi, sonarr-config 5Gi, radarr-config 5Gi, nextcloud-data 20Gi) whose loss is # unrecoverable. Excluding those namespaces — the shape schedule (2) uses for monitoring+unifi — # would silently drop exactly the data that matters. The opt-out has to be per VOLUME. # # WHY NOT the per-pod `backup.velero.io/backup-volumes-excludes` annotation. It works, but it fails # OPEN: the next NFS PV someone mounts is backed up in full until a human remembers to annotate its # pod, and nothing tells them. A volume policy tests the PROPERTY that makes a volume bulk-tier — # its source is the out-of-cluster NFS export — so it covers volumes that do not exist yet. # # `nfs: {}` is the documented "match any NFS volume source" condition (server/path may be given to # narrow it; deliberately not, so a second export is covered too). First matching rule wins. # # PROVEN, not assumed (prod, 2026-09-12, velero 1.18.1 / chart 12.1.0): a Backup of ns nextcloud # with defaultVolumesToFsBackup:true and this policy produced exactly ONE PodVolumeBackup — # `data` (nextcloud-data, Longhorn, 875,417,102 bytes, Completed). The NFS `legacy-archive` volume # produced NO PodVolumeBackup at all. # # Referenced by name from schedule (1)'s template (`resourcePolicy: {kind: configmap, name: ...}`). # Applied to BOTH environments: dev has no NFS PVs today, so the rule is a no-op there, and it is # already correct if dev ever grows one. apiVersion: v1 kind: ConfigMap metadata: name: velero-volume-policies namespace: velero data: policies.yaml: | version: v1 volumePolicies: - conditions: nfs: {} action: type: skip