feat(backup-system): migración completa a GitOps
- CronJob rclone-mega-backup entra en git (solo existía imperativo) - Scripts backup.sh/verify.sh/rclone-mega.sh como ConfigMap backup-scripts (antes hostPath /data/backups/scripts — cambios ahora pasan por git+ArgoCD) - rclone.conf vía InfisicalStaticSecret (homelab/prod//backup-system → RCLONE_CONF), sustituye al hostPath de ~/.config/rclone/rclone.conf - Imágenes pinneadas: rclone 1.74.3, bitnami/kubectl por digest (v1.36.2) - ClusterRole/CRB de backup-sa entran en git - Application ArgoCD backup-system (auto-sync + prune + selfHeal) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
apiVersion: v1
|
||||
data:
|
||||
backup.sh: |
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BACKUP_DIR="/data/backups/backups"
|
||||
DATE=$(date +%Y-%m-%d_%H-%M-%S)
|
||||
KUBECONFIG=/etc/rancher/k3s/k3s.yaml
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||||
|
||||
# === n8n ===
|
||||
log "Backing up n8n..."
|
||||
tar -czf "$BACKUP_DIR/n8n_${DATE}.tar.gz" -C /data/n8n . 2>/dev/null && log "n8n OK"
|
||||
|
||||
# === openclaw ===
|
||||
log "Backing up openclaw..."
|
||||
tar -czf "$BACKUP_DIR/openclaw_${DATE}.tar.gz" -C /data/openclaw . 2>/dev/null && log "openclaw OK"
|
||||
|
||||
# === homarr ===
|
||||
log "Backing up homarr..."
|
||||
HOMARR_DB_PV=$(kubectl get pvc -n homarr homarr-db-pvc -o jsonpath='{.spec.volumeName}' 2>/dev/null)
|
||||
HOMARR_REDIS_PV=$(kubectl get pvc -n homarr homarr-redis-pvc -o jsonpath='{.spec.volumeName}' 2>/dev/null)
|
||||
mkdir -p /tmp/backup-homarr/db /tmp/backup-homarr/redis
|
||||
cp /var/lib/rancher/k3s/storage/${HOMARR_DB_PV}_homarr_homarr-db-pvc/db.sqlite /tmp/backup-homarr/db/ 2>/dev/null || true
|
||||
cp /var/lib/rancher/k3s/storage/${HOMARR_REDIS_PV}_homarr_homarr-redis-pvc/dump.rdb /tmp/backup-homarr/redis/ 2>/dev/null || true
|
||||
tar -czf "$BACKUP_DIR/homarr_${DATE}.tar.gz" -C /tmp/backup-homarr . 2>/dev/null && log "homarr OK"
|
||||
rm -rf /tmp/backup-homarr
|
||||
|
||||
# === authentik PostgreSQL ===
|
||||
log "Backing up authentik postgres..."
|
||||
kubectl exec -n authentik postgresql-0 -- pg_dump -U authentik authentik 2>/dev/null | \
|
||||
gzip > "$BACKUP_DIR/authentik-pg_${DATE}.sql.gz" && log "authentik-pg OK"
|
||||
|
||||
# === polymarket PostgreSQL === (retirado 2026-07-06, decomisión del bot)
|
||||
# postgres escalado a 0; dump definitivo verificado en
|
||||
# $BACKUP_DIR/polymarket-decommission/ (+ último nocturno .last-nightly).
|
||||
|
||||
# === grafana ===
|
||||
log "Backing up grafana..."
|
||||
GRAFANA_PV=$(kubectl get pvc -n monitoring kube-prometheus-stack-grafana -o jsonpath='{.spec.volumeName}' 2>/dev/null)
|
||||
mkdir -p /tmp/backup-grafana
|
||||
cp /var/lib/rancher/k3s/storage/${GRAFANA_PV}_monitoring_kube-prometheus-stack-grafana/grafana.db /tmp/backup-grafana/ 2>/dev/null || true
|
||||
tar -czf "$BACKUP_DIR/grafana_${DATE}.tar.gz" -C /tmp/backup-grafana . 2>/dev/null && log "grafana OK"
|
||||
rm -rf /tmp/backup-grafana
|
||||
|
||||
# === k3s SQLite ===
|
||||
log "Backing up k3s SQLite..."
|
||||
tar -czf "$BACKUP_DIR/k3s-db_${DATE}.tar.gz" \
|
||||
/data/k3s-db/state.db \
|
||||
/data/k3s-db/state.db-shm \
|
||||
/data/k3s-db/state.db-wal 2>/dev/null \
|
||||
&& log "k3s-db OK" \
|
||||
|| log "k3s-db WARNING: backup parcial (WAL/SHM pueden estar ausentes si DB está idle)"
|
||||
|
||||
# === Cleanup old backups (keep last 7 per service) ===
|
||||
log "Cleaning old backups..."
|
||||
for prefix in n8n openclaw homarr authentik-pg grafana k3s-db; do
|
||||
find "$BACKUP_DIR" \( -name "${prefix}_*.tar.gz" -o -name "${prefix}_*.sql.gz" \) | \
|
||||
sort | head -n -7 | \
|
||||
xargs -r rm -f
|
||||
done
|
||||
|
||||
log "Backup complete!"
|
||||
rclone-mega.sh: |
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||||
|
||||
log "Iniciando sync a Mega..."
|
||||
log "Origen: /data/backups/backups"
|
||||
log "Destino: mega:k3s-backups/"
|
||||
|
||||
rclone sync /data/backups/backups mega:k3s-backups/ \
|
||||
--config /rclone/rclone.conf \
|
||||
--log-level INFO \
|
||||
--stats 30s
|
||||
|
||||
log "Sync completado."
|
||||
log "Archivos en Mega:"
|
||||
rclone ls mega:k3s-backups/ --config /rclone/rclone.conf
|
||||
verify.sh: |
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||||
|
||||
# polymarket-pg retirado el 2026-07-06 (decomisión del bot)
|
||||
EXPECTED_SERVICES="n8n openclaw homarr authentik-pg grafana k3s-db"
|
||||
ERRORS=0
|
||||
|
||||
# Ventana de frescura: el sync a Mega es semanal (domingos 03:00), así que
|
||||
# un backup es "reciente" si su fecha está en los últimos 8 días (0..7 atrás).
|
||||
# BusyBox date no soporta -d 'yesterday'; se calcula con epoch (-d @segundos).
|
||||
NOW=$(date +%s)
|
||||
ACCEPTED_DATES=""
|
||||
for i in $(seq 0 7); do
|
||||
ACCEPTED_DATES="$ACCEPTED_DATES $(date -d @$(( NOW - i * 86400 )) +%Y-%m-%d)"
|
||||
done
|
||||
|
||||
log "=== Verificación de backups en Mega ==="
|
||||
log "Listando archivos en mega:k3s-backups/..."
|
||||
|
||||
FILES=$(rclone ls mega:k3s-backups/ --config /rclone/rclone.conf 2>&1)
|
||||
log "$FILES"
|
||||
|
||||
log "---"
|
||||
log "Fechas aceptadas (ventana de 8 días):$ACCEPTED_DATES"
|
||||
|
||||
for svc in $EXPECTED_SERVICES; do
|
||||
FOUND=0
|
||||
for d in $ACCEPTED_DATES; do
|
||||
if echo "$FILES" | grep -q "${svc}_${d}"; then
|
||||
FOUND=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$FOUND" -eq 1 ]; then
|
||||
log "[OK] $svc — backup reciente encontrado"
|
||||
else
|
||||
log "[WARN] $svc — sin backup en los últimos 8 días"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
log "---"
|
||||
TOTAL=$(echo "$FILES" | grep -c "tar.gz\|sql.gz" || true)
|
||||
log "Total archivos en Mega: $TOTAL"
|
||||
|
||||
if [ "$ERRORS" -gt 0 ]; then
|
||||
log "RESULTADO: $ERRORS servicio(s) sin backup reciente. Revisar."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "RESULTADO: Todos los backups verificados correctamente."
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: backup-scripts
|
||||
namespace: backup-system
|
||||
Reference in New Issue
Block a user