jellyfin: scope k8up backup to config PVC only
ci/woodpecker/pr/vector-test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful

The jellyfin-config Schedule had no PVC selector and the k8up chart runs
skipWithoutAnnotation=false, so restic swept in every PVC in the namespace
(media, transcode scratch, redis, per-pod cache, CNPG data) — RWO volumes
also fail to mount while in use. k8up 4.10.0's Schedule CRD has no positive
PVC selector, so exclude every non-config PVC by annotation.

- Annotate media-tv, media-movies, transcode and redis-data PVCs with
  k8up.io/backup: "false".
- Annotate the per-pod cache volumeClaimTemplate the same way.
- Propagate the annotation to the CNPG data PVCs via inheritedMetadata
  (postgres has its own barmanObjectStore backup).
- Leave jellyfin-config unannotated so it remains the only backup target.
This commit is contained in:
2026-08-15 12:34:25 +10:00
parent 57ac95bdec
commit 066dc41b55
6 changed files with 32 additions and 0 deletions
+7
View File
@@ -10,6 +10,13 @@ metadata:
name: jellyfin-postgres
namespace: jellyfin
spec:
# Exclude the operator-managed data PVCs (jellyfin-postgres-N) from the
# jellyfin-config k8up Schedule (skipWithoutAnnotation is false cluster-wide,
# so unannotated PVCs are swept in). Postgres has its own barmanObjectStore
# backup below; restic must not touch the raw RWO data volumes.
inheritedMetadata:
annotations:
k8up.io/backup: "false"
affinity:
podAntiAffinityType: preferred
backup:
+5
View File
@@ -7,6 +7,11 @@ kind: PersistentVolumeClaim
metadata:
name: jellyfin-media-movies
namespace: jellyfin
annotations:
# Exclude from the jellyfin-config k8up Schedule (skipWithoutAnnotation is
# false cluster-wide, so unannotated PVCs are swept in). Only jellyfin-config
# is backed up; the media library is not restic-backup material.
k8up.io/backup: "false"
spec:
accessModes:
- ReadWriteMany
+5
View File
@@ -7,6 +7,11 @@ kind: PersistentVolumeClaim
metadata:
name: jellyfin-media-tv
namespace: jellyfin
annotations:
# Exclude from the jellyfin-config k8up Schedule (skipWithoutAnnotation is
# false cluster-wide, so unannotated PVCs are swept in). Only jellyfin-config
# is backed up; the media library is not restic-backup material.
k8up.io/backup: "false"
spec:
accessModes:
- ReadWriteMany
+5
View File
@@ -8,6 +8,11 @@ kind: PersistentVolumeClaim
metadata:
name: jellyfin-transcode
namespace: jellyfin
annotations:
# Exclude from the jellyfin-config k8up Schedule (skipWithoutAnnotation is
# false cluster-wide, so unannotated PVCs are swept in). Transcode is RWX
# scratch — nothing to back up.
k8up.io/backup: "false"
spec:
accessModes:
- ReadWriteMany
+5
View File
@@ -4,6 +4,11 @@ kind: PersistentVolumeClaim
metadata:
name: jellyfin-redis-data
namespace: jellyfin
annotations:
# Exclude from the jellyfin-config k8up Schedule (skipWithoutAnnotation is
# false cluster-wide, so unannotated PVCs are swept in). Redis holds only
# ephemeral transcode-lease state; RWO would also fail to mount while in use.
k8up.io/backup: "false"
spec:
accessModes:
- ReadWriteOnce
+5
View File
@@ -230,6 +230,11 @@ spec:
# Per-pod scratch cache — RWO, disposable, one PVC per replica.
- metadata:
name: cache
annotations:
# Exclude the per-pod cache PVCs from the jellyfin-config k8up Schedule
# (skipWithoutAnnotation is false cluster-wide). Cache is disposable and
# RWO — it would also fail to mount into the backup pod while in use.
k8up.io/backup: "false"
spec:
accessModes:
- ReadWriteOnce