diff --git a/deployments/backups/longhorn-recurring-jobs.yaml b/deployments/backups/longhorn-recurring-jobs.yaml new file mode 100644 index 0000000..73bf546 --- /dev/null +++ b/deployments/backups/longhorn-recurring-jobs.yaml @@ -0,0 +1,25 @@ +apiVersion: longhorn.io/v1beta2 +kind: RecurringJob +metadata: + name: daily-snapshot + namespace: longhorn-system +spec: + cron: "0 1 * * *" + task: snapshot + retain: 7 + concurrency: 2 + labels: + backup-tier: daily +--- +apiVersion: longhorn.io/v1beta2 +kind: RecurringJob +metadata: + name: weekly-backup + namespace: longhorn-system +spec: + cron: "0 3 * * 0" + task: backup + retain: 4 + concurrency: 1 + labels: + backup-tier: weekly diff --git a/deployments/backups/namespace.yaml b/deployments/backups/namespace.yaml new file mode 100644 index 0000000..5106245 --- /dev/null +++ b/deployments/backups/namespace.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: backups + labels: + app.kubernetes.io/managed-by: argocd diff --git a/deployments/backups/pelican-pg-backup-cronjob.yaml b/deployments/backups/pelican-pg-backup-cronjob.yaml new file mode 100644 index 0000000..9058c19 --- /dev/null +++ b/deployments/backups/pelican-pg-backup-cronjob.yaml @@ -0,0 +1,62 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: pelican-pg-backup + namespace: backups +spec: + schedule: "0 2 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: pg-dump + image: postgres:16-alpine + env: + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: pelican-pg-backup-credentials + key: password + - name: PGHOST + value: postgresql.pelican.svc.cluster.local + - name: PGUSER + valueFrom: + secretKeyRef: + name: pelican-pg-backup-credentials + key: username + - name: PGDATABASE + valueFrom: + secretKeyRef: + name: pelican-pg-backup-credentials + key: database + command: + - /bin/sh + - -c + - | + set -e + BACKUP_DIR=/backups/pelican + mkdir -p "$BACKUP_DIR" + FILENAME="$BACKUP_DIR/pelican-$(date +%Y%m%d-%H%M%S).sql.gz" + pg_dump -h "$PGHOST" -U "$PGUSER" -d "$PGDATABASE" | gzip > "$FILENAME" + echo "Backup written: $FILENAME" + find "$BACKUP_DIR" -name '*.sql.gz' -mtime +7 -delete + echo "Retention cleanup done (keeping 7 days)" + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + volumeMounts: + - name: backup-storage + mountPath: /backups + volumes: + - name: backup-storage + persistentVolumeClaim: + claimName: backup-storage diff --git a/deployments/backups/pelican-pg-externalsecret.yaml b/deployments/backups/pelican-pg-externalsecret.yaml new file mode 100644 index 0000000..d21d711 --- /dev/null +++ b/deployments/backups/pelican-pg-externalsecret.yaml @@ -0,0 +1,26 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: pelican-pg-backup-credentials + namespace: backups +spec: + refreshInterval: 1h + secretStoreRef: + name: vault-backend + kind: ClusterSecretStore + target: + name: pelican-pg-backup-credentials + creationPolicy: Owner + data: + - secretKey: username + remoteRef: + key: Talos Cluster/pelican/panel/db + property: DB_USER + - secretKey: password + remoteRef: + key: Talos Cluster/pelican/panel/db + property: DB_PASSWORD + - secretKey: database + remoteRef: + key: Talos Cluster/pelican/panel/db + property: DB_NAME diff --git a/deployments/backups/pvc.yaml b/deployments/backups/pvc.yaml new file mode 100644 index 0000000..0e5c960 --- /dev/null +++ b/deployments/backups/pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: backup-storage + namespace: backups +spec: + accessModes: + - ReadWriteOnce + storageClassName: longhorn + resources: + requests: + storage: 50Gi