Files
obsidian/infra/data/backup.md

9.0 KiB

title, updated, tags
title updated tags
백업 파이프라인 2026-04-20
infra
backup

Velero (K8s 표준 백업 도구)

네임스페이스 · 앱 단위 전체 복원을 위한 표준 백업 도구. Longhorn BackupTarget(볼륨 단위)과 공존 — 목적이 다름.

항목
Namespace velero
Chart vmware-tanzu/velero 12.0.0 (app v1.18.0)
Plugin velero/velero-plugin-for-aws:v1.14.0 (initContainer)
Features EnableCSI
BackupStorageLocation default → R2 버킷 velero-backup (ENAM), endpoint d8e5997eb4040f8b489f09095c0f623c.r2.cloudflarestorage.com
VolumeSnapshotLocation default (provider=csi)
VolumeSnapshotClass longhorn-snapshot (driver.longhorn.io, type=snap)
Credentials 시크릿 velero-cloud-credentials (namespace: velero). Vault secret/cloud/cloudflare/r2 재사용 (기존 longhorn-backup-r2와 동일 키)
클라이언트 brew install velero (macOS)

백업 스케줄 daily-full

항목
Cron 0 16 * * * UTC (KST 01:00)
TTL 720h (30일)
스코프 전체 네임스페이스 (*) + cluster-scoped
제외 네임스페이스 kube-system, kube-public, kube-node-lease, velero, longhorn-system, democratic-csi, metallb-system, cert-manager, monitoring, logging, external-secrets, nfs-provisioner, rabbitmq-system
볼륨 CSI 스냅샷 (Longhorn 네이티브 스냅샷으로 생성)

기존 Longhorn BackupTarget은 유지 (볼륨 단위 장애 복구용). Velero는 네임스페이스 단위 전체 복구용.

운영 명령

velero backup get -n velero
velero backup describe <name> -n velero --details
velero backup logs <name> -n velero
velero backup create adhoc-<name> --include-namespaces <ns> --snapshot-volumes -n velero --wait

velero schedule get -n velero
velero restore create --from-backup <name> -n velero

snapshot-controller (선결 인프라)

항목
snapshot-controller v8.5.0, Deployment (kube-system, replicas=2)
CRDs snapshot.storage.k8s.io/v1 — VolumeSnapshot, VolumeSnapshotContent, VolumeSnapshotClass

도입 이력: 2026-04-20-snapshot-controller-velero-prep · 2026-04-20-velero-install

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

라벨 기록이 꼬였을 때의 대응은 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, user nocodb, db nocodb
  • 출력: /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