standard-snapshot 0 3 * * * → 0 18 * * * (UTC, = KST 03:00) standard-backup 0 4 * * * → 0 19 * * * (UTC, = KST 04:00) critical 6h 간격에 KST 03시 포함되어 변경 없음.
6.9 KiB
title, updated, tags
| title | updated | tags | ||
|---|---|---|---|---|
| 백업 파이프라인 | 2026-04-15 |
|
Longhorn PVC 백업 (K3s)
BackupTarget default → R2 버킷 longhorn-backup (시크릿 longhorn-backup-r2). RecurringJob 4종 (critical-snapshot 매시 UTC, critical-backup 6h UTC, standard-snapshot 0 18 * * * UTC = KST 03:00, standard-backup 0 19 * * * UTC = KST 04:00).
RecurringJob 그룹 볼륨 라벨 — 정확한 키 주의
Longhorn 컨트롤러가 인식하는 라벨 키는 recurring-job-group.longhorn.io/<group>=enabled (대시 포함). recurringjob-group.longhorn.io/... (대시 누락) 은 무효이며 컨트롤러가 볼륨을 찾지 못한다.
# 신규 볼륨을 critical 그룹에 등록
kubectl -n longhorn-system label volumes.longhorn.io <pvc-...> \
recurring-job-group.longhorn.io/critical=enabled --overwrite
# 라벨 검증 (선택자가 볼륨을 실제로 잡는지)
kubectl -n longhorn-system get volumes.longhorn.io \
-l recurring-job-group.longhorn.io/critical=enabled
라벨 기록이 꼬였을 때의 대응은 ../history/2026-04-15-longhorn-backup-label-typo 참고.
incus 백업 (inbest 데이터)
3단계 백업 파이프라인. 소스: incus-kr2 inbest 프로젝트 inbest-data 커스텀 볼륨.
1. rsync → NAS
- 호스트: incus-kr2
- 스크립트:
/usr/local/bin/backup-inbest.sh - systemd:
backup-inbest.timer/backup-inbest.service - 스케줄: 매일 03:00 (±5분)
- 소스:
/var/lib/incus/storage-pools/default/custom/inbest_inbest-data/ - 대상:
kaffa@192.168.205.100:/volume1/incus/inbest/ - 제외:
*/data/session/ - SSH 키:
/home/kaffa/.ssh/id_ed25519 - 옵션:
rsync -rlz --omit-dir-times --delete(Synology 퍼미션 호환)
2. btrfs 스냅샷 (NAS)
- rsync 완료 직후 자동 실행 (같은 스크립트)
- 스냅샷 경로:
/volume1/incus/.snapshots/incus-YYYYMMDD - 타입: 읽기 전용 (
btrfs subvolume snapshot -r) - 보관: 3일 초과 자동 삭제
- 용도: 논리적 복구 (실수 삭제/덮어쓰기), NAS 내부에서만 유효
3. R2 sync (NAS → Cloudflare R2)
- 호스트: Synology NAS (192.168.205.100)
- systemd:
r2-incus-backup.timer/r2-incus-backup.service - 스케줄: 매일 06:00 (±5분)
- 소스:
/volume1/incus/ - 대상: R2 버킷
incus-backup(APAC 리전) - 제외:
.snapshots/**,@eaDir/** - rclone: Docker (
rclone/rclone:latest), 설정/volume1/docker/rclone/rclone.conf - 성능: transfers 32, checkers 32, 첫 전체 업로드(7.97GB) 약 12분
- TimeoutStartSec: 3600 (1시간)
NAS 설정 메모
- NAS
/volume1/incus/inbest/소유자:kaffa:users(rsync 쓰기용) - btrfs subvolume:
/volume1/incus(ID 741) - 모든 백업 스크립트에 NAS 접근 불가 시 스킵/로컬 보관 로직 포함
- NFS 마운트는 반드시
soft,timeo=50,retrans=3사용 (hard 금지, nas-storage 참조)
복구 시나리오
| 상황 | 복구 방법 |
|---|---|
| 파일 실수 삭제/덮어쓰기 | NAS btrfs 스냅샷에서 복원 |
| NAS 장애 | R2에서 rclone copy로 복원 |
| kr2 장애 | NAS rsync 미러에서 복원 |
NocoDB PostgreSQL 백업
NocoDB가 사용하는 PostgreSQL(Incus 컨테이너) 백업. pg_dump → NAS.
1. pg_dump (kr2)
- 호스트: incus-kr2
- 스크립트:
/usr/local/bin/pg-backup.sh - systemd:
pg-backup.timer/pg-backup.service - 스케줄: 매일 03:00
- DB:
10.100.2.5(Incus 컨테이너 PostgreSQL) - 인증:
PGPASSWORD=nocodb, usernocodb, dbnocodb - 출력:
/mnt/nas-backup/daily/nocodb_YYYYMMDD_HHMMSS.dump(NAS NFS 마운트) - 보관: 30일 초과 자동 삭제
- NAS 마운트: 스크립트 내에서
soft,timeo=50,retrans=3으로 자동 마운트 - NAS 미접근 시: 10초 타임아웃 후 스킵
kine 백업 (Supabase PostgreSQL)
K3s datastore인 Supabase PostgreSQL의 kine 테이블 백업. pg_dump → NAS → R2 3단계.
1. pg_dump (kr2)
- 호스트: incus-kr2
- 스크립트:
/usr/local/bin/kine-backup.sh - systemd:
kine-backup.timer/kine-backup.service - 스케줄: 매일 03:30 (±5분)
- DB: Supabase Pooler (
aws-1-ap-southeast-1.pooler.supabase.com) - 인증: Vault
secret/cloud/supabase - 출력:
/opt/kine-backup/kine-YYYYMMDD.sql.gz - 보관: 7일 초과 자동 삭제
- 크기: ~9.3MB (gzip)
2. rsync → NAS (같은 스크립트)
- pg_dump 완료 직후 자동 실행 (같은 스크립트)
- 대상:
kaffa@192.168.205.100:/volume1/k3s-backup/kine/ - SSH 키:
/home/kaffa/.ssh/id_ed25519
3. R2 sync (기존 r2-backup.timer로 자동 포함)
NAS /volume1/k3s-backup/ → R2 k3s-backup 버킷 (매일 05:00)
복구 방법
# NAS 또는 R2에서 덤프 파일 가져온 후
gunzip kine-YYYYMMDD.sql.gz
psql "$DB_URL" < kine-YYYYMMDD.sql
etcd 스냅샷 백업 (비활성)
K3s가 kine(PostgreSQL)으로 전환되어 etcd 백업은 불필요. etcd-backup.timer, etcd-backup-sync.timer 비활성화됨. kine 백업이 대체.
1. etcd snapshot (hp2 etcd 컨테이너)
- 호스트: incus-hp2, etcd 컨테이너
- 스크립트:
/usr/local/bin/etcd-backup.sh - systemd:
etcd-backup.timer/etcd-backup.service - 스케줄: 매일 03:30 (±5분)
- 출력:
/backup/etcd-YYYYMMDD_HHMMSS.db(컨테이너) =/opt/etcd-backup/(호스트) - 보관: 7일 초과 자동 삭제
- 크기: ~65MB
2. rsync → NAS (hp2 호스트)
- 호스트: incus-hp2
- 스크립트:
/usr/local/bin/etcd-backup-sync.sh - systemd:
etcd-backup-sync.timer/etcd-backup-sync.service - 스케줄: 매일 04:00 (±5분)
- 소스:
/opt/etcd-backup/ - 대상:
kaffa@192.168.9.100:/volume1/k3s-backup/etcd/ - SSH 키:
/home/kaffa/.ssh/id_ed25519 - NAS IP: hp2에서는 192.168.9.100 사용 (kr2에서는 192.168.205.100)
3. R2 sync (기존 r2-backup.timer로 자동 포함)
NAS /volume1/k3s-backup/ → R2 k3s-backup 버킷 (매일 05:00)
OpenWrt 라우터 백업
- 호스트: openwrt-gw (root@100.66.60.66)
- 스크립트:
/usr/local/bin/backup-openwrt.sh - 스케줄: cron 매일 03:30
- 방식:
sysupgrade -b /tmp/backup-openwrt.tar.gz→ scp → NAS - 대상:
kaffa@192.168.9.100:/volume1/k3s-backup/openwrt/ - SSH 키:
/root/.ssh/id_ed25519(Dropbear, dbclient 또는ssh -i필요) - 보관: 7일 초과 자동 삭제
- 크기: ~18KB
- 포함:
/etc/전체 (haproxy.cfg, nftables.d/, config/firewall, config/network, crontabs/, ssh 키 등) - 복원:
sysupgrade -r backup.tar.gz
k3s 백업 (기존)
- 호스트: Synology NAS
- systemd:
r2-backup.timer/r2-backup.service - 스케줄: 매일 05:00 (±5분)
- 소스:
/volume1/k3s-backup/ - 대상: R2 버킷
k3s-backup(ENAM 리전) - rclone: Docker, transfers 4, checkers 8