Deploy jellyfin-ha as a true-HA StatefulSet under a new media project #237

Merged
benvin merged 10 commits from benvin/jellyfin-ha into main 2026-08-15 13:39:00 +10:00
4 changed files with 105 additions and 0 deletions
Showing only changes of commit 57ac95bdec - Show all commits
+3
View File
@@ -8,6 +8,9 @@ resources:
- cnpg_pooler.yaml
- cnpg_backup.yaml
- cephrgw-config-backup.yaml
- vaultauth.yaml
- vaultstaticsecret.yaml
- schedule.yaml
- pvc-config.yaml
- pvc-transcode.yaml
- pvc-media-tv.yaml
+58
View File
@@ -0,0 +1,58 @@
---
# k8up Schedule: restic backups of the jellyfin-config PVC (library metadata,
# plugins, config XML) to the dedicated Ceph RGW config-backup bucket. S3 creds
# come from the cephrgw BucketAccess Secret (jellyfin-config-backup-s3); the
# restic repo password comes from Vault via the jellyfin-k8up-restic Secret.
#
# s3.ceph.unkin.net presents the internal unkin.net CA, which the k8up/restic
# image does not trust by default, so the reflected vault-ca-cert Secret is
# mounted into every job pod and pointed at via backend.tlsOptions.caCert.
apiVersion: k8up.io/v1
kind: Schedule
metadata:
name: jellyfin-config
namespace: jellyfin
spec:
backend:
repoPasswordSecretRef:
name: jellyfin-k8up-restic
key: password
s3:
endpoint: https://s3.ceph.unkin.net
bucket: jellyfin-config-backup
accessKeyIDSecretRef:
name: jellyfin-config-backup-s3
key: AWS_ACCESS_KEY_ID
secretAccessKeySecretRef:
name: jellyfin-config-backup-s3
key: AWS_SECRET_ACCESS_KEY
tlsOptions:
caCert: /etc/k8up/ca/ca.crt
volumeMounts:
- name: vault-ca
mountPath: /etc/k8up/ca
readOnly: true
backup:
schedule: "0 2 * * *"
failedJobsHistoryLimit: 3
successfulJobsHistoryLimit: 3
volumes:
- name: vault-ca
secret:
secretName: vault-ca-cert
prune:
schedule: "0 3 * * 0"
retention:
keepDaily: 14
keepWeekly: 8
keepMonthly: 12
volumes:
- name: vault-ca
secret:
secretName: vault-ca-cert
check:
schedule: "0 4 * * 0"
volumes:
- name: vault-ca
secret:
secretName: vault-ca-cert
+20
View File
@@ -0,0 +1,20 @@
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: jellyfin
annotations:
argocd.argoproj.io/sync-wave: "0"
spec:
allowedNamespaces:
- jellyfin
kubernetes:
audiences:
- vault
role: default
serviceAccount: default
tokenExpirationSeconds: 600
method: kubernetes
mount: k8s/au/syd1
vaultConnectionRef: vso-system/default
+24
View File
@@ -0,0 +1,24 @@
---
# restic repository password for the k8up jellyfin-config backups. Seeded at
# kv/kubernetes/namespace/jellyfin/default/k8up-restic (key: password); the
# default k8s role's templated policy already grants read here, so no
# terraform-vault change is needed. VSO syncs it into the jellyfin-k8up-restic
# Secret that the Schedule references via backend.repoPasswordSecretRef.
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: jellyfin-k8up-restic
namespace: jellyfin
annotations:
argocd.argoproj.io/sync-wave: "0"
spec:
destination:
create: true
name: jellyfin-k8up-restic
overwrite: true
hmacSecretData: true
mount: kv
path: kubernetes/namespace/jellyfin/default/k8up-restic
refreshAfter: 5m
type: kv-v2
vaultAuthRef: default