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