feat(k8s/media): migrate backups from rclone to restic, add seerr-db backup
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
apiVersion: batch/v1
|
apiVersion: batch/v1
|
||||||
kind: CronJob
|
kind: CronJob
|
||||||
metadata:
|
metadata:
|
||||||
name: sonarr-db-backup
|
name: media-db-backup
|
||||||
namespace: media
|
namespace: media
|
||||||
labels:
|
labels:
|
||||||
app: sonarr-db-backup
|
app: media-backup
|
||||||
spec:
|
spec:
|
||||||
schedule: "0 3 * * *"
|
schedule: "0 3 * * *"
|
||||||
concurrencyPolicy: Forbid
|
concurrencyPolicy: Forbid
|
||||||
@@ -15,11 +15,11 @@ spec:
|
|||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: sonarr-db-backup
|
app: media-backup
|
||||||
spec:
|
spec:
|
||||||
restartPolicy: OnFailure
|
restartPolicy: OnFailure
|
||||||
initContainers:
|
initContainers:
|
||||||
- name: pg-dump
|
- name: pg-dump-sonarr
|
||||||
image: postgres:14.21
|
image: postgres:14.21
|
||||||
env:
|
env:
|
||||||
- name: PGHOST
|
- name: PGHOST
|
||||||
@@ -42,52 +42,11 @@ spec:
|
|||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- pg_dump --clean --if-exists -v > /backup/dump.sql
|
- pg_dump --clean --if-exists > /backup/sonarr.sql
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: backup
|
- name: backup-tmp
|
||||||
mountPath: /backup
|
mountPath: /backup
|
||||||
containers:
|
- name: pg-dump-radarr
|
||||||
- name: rclone-upload
|
|
||||||
image: rclone/rclone:1.69
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
- -c
|
|
||||||
- rclone copy /backup/dump.sql b2crypt:sonarr/ --config /config/rclone/rclone.conf -v 2>&1
|
|
||||||
volumeMounts:
|
|
||||||
- name: backup
|
|
||||||
mountPath: /backup
|
|
||||||
- name: rclone-config
|
|
||||||
mountPath: /config/rclone
|
|
||||||
readOnly: true
|
|
||||||
volumes:
|
|
||||||
- name: backup
|
|
||||||
emptyDir: {}
|
|
||||||
- name: rclone-config
|
|
||||||
secret:
|
|
||||||
secretName: rclone-config
|
|
||||||
---
|
|
||||||
apiVersion: batch/v1
|
|
||||||
kind: CronJob
|
|
||||||
metadata:
|
|
||||||
name: radarr-db-backup
|
|
||||||
namespace: media
|
|
||||||
labels:
|
|
||||||
app: radarr-db-backup
|
|
||||||
spec:
|
|
||||||
schedule: "0 3 * * *"
|
|
||||||
concurrencyPolicy: Forbid
|
|
||||||
successfulJobsHistoryLimit: 3
|
|
||||||
failedJobsHistoryLimit: 3
|
|
||||||
jobTemplate:
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: radarr-db-backup
|
|
||||||
spec:
|
|
||||||
restartPolicy: OnFailure
|
|
||||||
initContainers:
|
|
||||||
- name: pg-dump
|
|
||||||
image: postgres:14.21
|
image: postgres:14.21
|
||||||
env:
|
env:
|
||||||
- name: PGHOST
|
- name: PGHOST
|
||||||
@@ -110,26 +69,70 @@ spec:
|
|||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- pg_dump --clean --if-exists -v > /backup/dump.sql
|
- pg_dump --clean --if-exists > /backup/radarr.sql
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: backup
|
- name: backup-tmp
|
||||||
mountPath: /backup
|
mountPath: /backup
|
||||||
containers:
|
- name: pg-dump-seerr
|
||||||
- name: rclone-upload
|
image: postgres:14.21
|
||||||
image: rclone/rclone:1.69
|
env:
|
||||||
|
- name: PGHOST
|
||||||
|
value: seerr-db
|
||||||
|
- name: PGUSER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: seerr-credentials
|
||||||
|
key: SEERR_DB_USER
|
||||||
|
- name: PGPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: seerr-credentials
|
||||||
|
key: SEERR_DB_PASSWORD
|
||||||
|
- name: PGDATABASE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: seerr-credentials
|
||||||
|
key: SEERR_DB_NAME
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- rclone copy /backup/dump.sql b2crypt:radarr/ --config /config/rclone/rclone.conf -v 2>&1
|
- pg_dump --clean --if-exists > /backup/seerr.sql
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: backup
|
- name: backup-tmp
|
||||||
mountPath: /backup
|
mountPath: /backup
|
||||||
- name: rclone-config
|
containers:
|
||||||
mountPath: /config/rclone
|
- name: resticprofile
|
||||||
|
image: creativeprojects/resticprofile:0.32.0
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n sonarr-db backup
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n sonarr-db copy
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n radarr-db backup
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n radarr-db copy
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n seerr-db backup
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n seerr-db copy
|
||||||
|
env:
|
||||||
|
- name: B2_ACCOUNT_ID
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: media-backup-config
|
||||||
|
key: B2_ACCOUNT_ID
|
||||||
|
- name: B2_ACCOUNT_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: media-backup-config
|
||||||
|
key: B2_ACCOUNT_KEY
|
||||||
|
volumeMounts:
|
||||||
|
- name: secrets
|
||||||
|
mountPath: /secrets
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- name: backup-tmp
|
||||||
|
mountPath: /backup
|
||||||
volumes:
|
volumes:
|
||||||
- name: backup
|
- name: secrets
|
||||||
emptyDir: {}
|
|
||||||
- name: rclone-config
|
|
||||||
secret:
|
secret:
|
||||||
secretName: rclone-config
|
secretName: media-backup-config
|
||||||
|
- name: backup-tmp
|
||||||
|
emptyDir: {}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ spec:
|
|||||||
app: sonarr
|
app: sonarr
|
||||||
- podSelector:
|
- podSelector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: sonarr-db-backup
|
app: media-backup
|
||||||
---
|
---
|
||||||
# radarr-db: only reachable from radarr and backup jobs
|
# radarr-db: only reachable from radarr and backup jobs
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
@@ -73,7 +73,7 @@ spec:
|
|||||||
app: radarr
|
app: radarr
|
||||||
- podSelector:
|
- podSelector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: radarr-db-backup
|
app: media-backup
|
||||||
---
|
---
|
||||||
# Allow prowlarr to receive connections from sonarr and radarr
|
# Allow prowlarr to receive connections from sonarr and radarr
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
@@ -169,7 +169,7 @@ spec:
|
|||||||
matchLabels:
|
matchLabels:
|
||||||
app: jellyfin
|
app: jellyfin
|
||||||
---
|
---
|
||||||
# seerr-db: only reachable from seerr
|
# seerr-db: only reachable from seerr and backup jobs
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
kind: NetworkPolicy
|
kind: NetworkPolicy
|
||||||
metadata:
|
metadata:
|
||||||
@@ -186,3 +186,34 @@ spec:
|
|||||||
- podSelector:
|
- podSelector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: seerr
|
app: seerr
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: media-backup
|
||||||
|
---
|
||||||
|
# Allow backup pods egress to Synology (rest-server), B2, DNS, and DB
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-backup-egress
|
||||||
|
namespace: media
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: media-backup
|
||||||
|
policyTypes:
|
||||||
|
- Egress
|
||||||
|
egress:
|
||||||
|
- ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 8888
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 443
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 5432
|
||||||
|
protocol: TCP
|
||||||
|
|||||||
26
kubernetes/app/media/secret-backup.sops.yaml
Normal file
26
kubernetes/app/media/secret-backup.sops.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: media-backup-config
|
||||||
|
namespace: media
|
||||||
|
stringData:
|
||||||
|
profiles.yaml: ENC[AES256_GCM,data:FvqC4eyDKTqy+rCcuq5XiAcOF6oVFGVrsPKY0ElwMVqhsxTxdbGmfoeB6tjvOaz4IS0MyM7hekU4ydGCQN+O9O97eazNj2QIrmjw354Ckt+k/5R+i61jua96ErVnJef9RzrhfW1L+4gV3nYTx4oy6YVGoGk0FDpCuD98SR0TGWxbk+HOJ7BN7QZ91GPNre8G4SrizAoTIkYUmfQK/h8XvKhgScLdAZf4f9UDfW2bra9oekQc1EzzA33XeeOxuWr7lTeTG7/EIJCijtFmu+XdAvxWHgQ6S7breHGcAbyRtXF/ZSdPxtU/4y9RCxDmcd4tNhmP9b0QOaBeo6AAqq7epu7SC/dXHriOROJJ0orF88OVX+ptrP+3OwFE3WyuDCTcoOFoznXdGii+CHX7DJRnnsY3Q4HAL3jxOSGmtqauvoB6hMVO3l45gMG/DRJofHTJbIXZY08fw27cukeJlh0cWKyA+/KTPYI/V18OdMNfKrTuQ6rrpD29j6xbmI0m4Ho9FbeInatDtix21JJ2EpFEtBi3RrCeDXk0uqPU1eC7buUHdVQ3VO+01KLGrMIaVx5taP+4tclzdzbatEZ3hjI8u0g84jMJUryG0yjFpqAuZLqwFRuYzCALyWXtfj8aQt3+7ljEXaf8Ho2Pq3xDJAz1u7NArci7CYOXHHtJXINhgVEyFI+LTtkphdMP39k6rZ63KG7HISjzH1Fchqqzl8FJj6wyTIGLK2PoSizjBNoKO1bc3mMtbM+/x4MV5tYGOVzbQ9z9xqutEXoUZaBat7fWdKIMK4TsdOcrQt0x65Sa5/AewyGcHJh2yq2QgvaCPKzT6pY+88NGoWGUeqB62GO/nDybWFUPk1rdv2hdCwKIuLjbxxP5P123VOeOdfodKRqIjGZq97lZLiccCObrW9WvOuAKnDTL3s0fWa5zmYM19xJaq/Iwg9GyjUJMRhRaTdrttaOMYle2Yt+E0VW4ETGEG/3PwH7M/FzjEyGn4FTjYxbxcmkJha75JX3L3Q6bb5x9bIV6s0uDvptX3pKlw2431TUaWDkuJ+ZzpcLJwFZvNJ40maF3bI+LC9abHYQHtIxtPDF6EI70G3paO0UVItpd33+J92X/qiCFCTasdjzAr+HqGQ1SepkV74Puj/sIKs+6f1Sot+i22USXASGdaD0F/IqpwbgJXufbiYSrRdVw/EgZ7WuzGme0gL1AW7lchw0jBcNA7T2dKbVeuhmN3hUHe6rCCAS+mmBg+KxybXH9UJabfe9N7XYzjCeZ5afmSn663UxCq5V3wC0qh8edLih41XYTAMOw2ytlBWxZsVQE8mwTJRQrXDZrj3aB3Xc10vmj+mlma38lfz4ghGb3AqAFtdALJyqYeBxx1Wan6KA2tpWR39hCj1Jj3dPlAZc/ZXcs/zQJTsf3ohVqjBJD7s/42jp5wTO9lEvPESyekYsvaS82gSSuAJ57K0Yvbx278jciHyjX6vhi1uzdXFep0TPjQ3/rBf8PgngOyEjWV216C7dBLry0ou8B3HJElqItFuchtBVOHXvFY4B55OzzEaDJJ2eWFW7LZKS2UO12j/xFzfSdx2UdGkGUuJ9DjpvRdLB58HtbSDjclECvmyLQ7iRN7Q0W+7ei/aSWj/3t3ZC01IoCrj4arg4JlrjtC4VYxpKI4hyhX1M5ibdw8J3rOX/KqBtFBwoEiQgvSP5YxD1sfjwPRelaMgUHO8n6eXrfNTA0X2LJB++5B6nDaxTmNEq9eVu9L/kUo/WuE59UulRtkYs/ClP5zTclqUKdTVkPnNRQV9dcZOCjuiSpyDTIOlxwUR3I/7xRVP7B33CCgkXOWUISZb98RmQOJFkBPsXqiyRYVgHfn/SbarrvqvWF3XXNcQ+at2taYGF/WJB1Y2B+oFTppC+mNHfxmklJKwcIcwk39Q==,iv:hP5emno4sxU0g+hcCpfXtf8lhxhk7NDCjwcq5lSjmQ8=,tag:K3bNiO9BnGnMRqvM7E9TfQ==,type:str]
|
||||||
|
restic-password-nas: ENC[AES256_GCM,data:OfCOmmU85bnWWFAAir90+Vj3d0Vh0bUqNICQg+2aCksd5aiVl3M+OUXZaVhQQtukVd2Mw22y4Die3zO7wlzXAQ==,iv:M7SuVZfm541Rvm7m3Gh8EkDgQ3kU2gKIMJZ+u1s+xf8=,tag:5EwXbugyG+idxt12sJXNhQ==,type:str]
|
||||||
|
restic-password-b2: ENC[AES256_GCM,data:dSt6fWJknKPslHKrjfaCLRI+r4K2lhz9hYYE4CKcEaTutxFNBfAoj70abwtIj1hoLv0SzyZUWtxrIrZCILR/yw==,iv:5tRzv0KQMqbw5zAx9eBGGxngiowOxLYSMf3vsvoRcVA=,tag:2utz3OFpup4/NK/sWKzKVg==,type:str]
|
||||||
|
B2_ACCOUNT_ID: ENC[AES256_GCM,data:os8HLCWv9ujoZWLFEuhondgCVvRwMNBlHQ==,iv:bQNshEL7pFF/+1hjStaRo8Aa2uzVmai3L+5wFLoC8BE=,tag:7JGG/ocByA83E1ncNoZEXw==,type:str]
|
||||||
|
B2_ACCOUNT_KEY: ENC[AES256_GCM,data:+CNHqdPcTqHONYOY4DYJZ9G+mi3RHfX8hxzLXuSemw==,iv:Ojx0XDGUdvt+9UvEopQLpqQhoCmAzlz4kZTdYtq+Qcs=,tag:lYq7T2Q+wvycnU1JcNpvZQ==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlQnBxVFhqY3l4U1hLZlhC
|
||||||
|
RWE5RHlIQXo3U2FqZVg3d2ZpRDhmbk1XSkI4CmxFcEt5VjBPZTNGQlRDYmIxMU91
|
||||||
|
VVphNE5TcUdnK29mcXVIc0VYaFkwWVEKLS0tIExOWTdjUGd5eHlBOVJTcXJHNFFQ
|
||||||
|
cER0MEpOb1J2Y1ZYQWlwT3A3dkdkZ1kK0PhrZsURFuA8c4rMVRE/jLiHBkxQ65ds
|
||||||
|
iVqJJHjuiOuOed5Wcr4FbAaghKIsc5AiZO06Zsj+pfpt5aQGdcettw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2026-03-22T09:08:31Z"
|
||||||
|
mac: ENC[AES256_GCM,data:veSRpp9RZatCrGkS5w/OPrPz1Av2SZQ+M5d/MlNYFraoMFluhejAQIt3vh+mO3Bd1hxPm3PPZzxHvLwpVH10lczxD9Uvc+LhA7FWrhr0BWrjbN5WKwhP3T3v/VFfkJctPi9ITOd/aGkusWfZ9ghVWnW4oe7RXxtCZhsh141QBHs=,iv:JPvqfB6T9DGFFsNrSGbrlaHv0UhQJB005Uj5tJgBVJQ=,tag:ih/gh7+FORz+CfP/nKahmA==,type:str]
|
||||||
|
encrypted_regex: ^(data|stringData|email)$
|
||||||
|
version: 3.12.2
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: rclone-config
|
|
||||||
namespace: media
|
|
||||||
stringData:
|
|
||||||
rclone.conf: ENC[AES256_GCM,data:aTthn7P4ESDNtqRDW+R7RI1e0B2ftgHg6406vqHtsUPW25SEaNUiGuWlSY/BoiCuagBBM6TM+Gow2XrtTQauPND1irb5D5xyhcphFM5uF+8dE4qNJV4J09NjBd7Lzdp1udej2BJoRAeCwgAEwq8857log4TRwrbGzNrfRKOPrz7D3okBQP2hyxfZ85dlQH0ojUEodPi4U3mpwgXc8Kb0JhziZc1KjHbIzZ1/GkaKcYLI8Rl8q7esdqxnrA51sssWVkmSC4zoiPjwPwUWifSNMb7KC8L8bXRIVdpP8/f4rDyYJoa9uC7GW44nYIBVfLJrM015ZtpSzh05/IS9ev6N2REkjudLmOwwvOw52s8dKh1IRXixcV1JPk3knam2jnezYcnvmLYgyReryZFRFFP0xgaVOmZa5is=,iv:zrFW+ssUTt8T14TZz5n30rVr792FiDYxr89BdIIxn1c=,tag:XVtMvVbuo1vQU3hp8VTnHQ==,type:str]
|
|
||||||
sops:
|
|
||||||
age:
|
|
||||||
- recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlR1BZak5zZWdmZ2g3YktL
|
|
||||||
Q1lqZzVTWEtpVGhqSk9WamxmRm1WSFNnNkN3CjNzMEtyMnh6bEtjbW9BY0NGZm1G
|
|
||||||
dnMyOW5DVFpZT3JMVGNxVW9raWZkSzAKLS0tIHNHMXdZTlhXYWFRYmYvS21tQUps
|
|
||||||
MXB5QVkyZDZlQWlMd1NqdEl1V0g0d00KMSyMsWeN5oEx3s5Zh3x9MHiRywFvRuZm
|
|
||||||
lZEdl0ho90lJ8m+rPHIT+pI7vBMHLB3mJiBfIVR4KJQRUkhPjGSMRQ==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
lastmodified: "2026-02-22T16:12:51Z"
|
|
||||||
mac: ENC[AES256_GCM,data:gUyVh53pNCUHfW9+pww9sQ10kL/U92N0AV1Ys+fKt3W/wq4msyXLErQVVJBrHoPQo/ncKUMbCUGvMNHsUnJT7H8g8LuqMUxLbZhFju6rLHrgg+1hIKeA1cStOlTgBTQLbXA2gfsclQQ+nAf9zeAsgz3MfuK8PEHs3U2O8cSrtP4=,iv:fQd6lggTw3OI+8lZ1BOZvD+lLt7p5wlelf59sFsQHZE=,tag:4V8do9D3IiNPDDR5GRLXOg==,type:str]
|
|
||||||
encrypted_regex: ^(data|stringData|email)$
|
|
||||||
version: 3.11.0
|
|
||||||
Reference in New Issue
Block a user