백업 및 복구
백업 및 복구¶
학습 목표¶
이 문서를 통해 다음을 학습합니다:
- rsync를 활용한 효율적인 백업
- Borg Backup으로 중복 제거 백업
- 시스템 이미지 백업과 복구
- 재해복구(DR) 전략 수립
난이도: ⭐⭐⭐⭐ (고급)
목차¶
1. 백업 전략 개요¶
3-2-1 백업 규칙¶
┌─────────────────────────────────────────────────────────────┐
│ 3-2-1 백업 규칙 │
├─────────────────────────────────────────────────────────────┤
│ 3: 데이터 사본 3개 유지 │
│ └── 원본 + 백업 2개 │
│ │
│ 2: 서로 다른 2종류의 저장 매체 │
│ └── 로컬 디스크 + 외장 디스크 또는 NAS │
│ │
│ 1: 1개는 오프사이트 (원격지) │
│ └── 클라우드 또는 물리적 원격지 │
└─────────────────────────────────────────────────────────────┘
백업 유형¶
| 유형 | 설명 | 장점 | 단점 |
|---|---|---|---|
| 전체 백업 | 모든 데이터 복사 | 복구 간단 | 시간/용량 많이 소요 |
| 증분 백업 | 마지막 백업 이후 변경분만 | 빠르고 용량 적음 | 복구 시 체인 필요 |
| 차등 백업 | 마지막 전체 백업 이후 변경분 | 증분보다 복구 간단 | 증분보다 용량 큼 |
| 스냅샷 | 특정 시점의 파일시스템 상태 | 즉시 생성 | 저장소 의존적 |
RTO와 RPO¶
┌─────────────────────────────────────────────────────────────┐
│ RPO (Recovery Point Objective) │
│ = 허용 가능한 데이터 손실 시간 │
│ = 마지막 백업 이후 얼마나 데이터를 잃어도 되는가? │
│ │
│ RTO (Recovery Time Objective) │
│ = 서비스 복구까지 허용 가능한 시간 │
│ = 장애 발생 후 얼마 내에 복구해야 하는가? │
└─────────────────────────────────────────────────────────────┘
타임라인:
──────────────────────────────────────────────────────────────
마지막 백업 장애 발생 복구 완료
│ │ │
│◄─────── RPO ──────►│◄────── RTO ──────►│
│ (데이터 손실) │ (다운타임) │
2. rsync 고급 사용법¶
기본 문법¶
rsync [옵션] 원본 대상
# 로컬 복사
rsync -av /source/ /backup/
# 원격 복사 (SSH)
rsync -av /source/ user@server:/backup/
rsync -av user@server:/source/ /backup/
주요 옵션¶
# 기본 옵션 조합
rsync -avz --progress /source/ /backup/
# 상세 옵션
-a, --archive # 아카이브 모드 (-rlptgoD와 동일)
-v, --verbose # 상세 출력
-z, --compress # 전송 중 압축
-P # --progress --partial 조합
--progress # 진행 상황 표시
--partial # 부분 전송 파일 유지
# 삭제 옵션
--delete # 대상에만 있는 파일 삭제
--delete-before # 전송 전 삭제
--delete-after # 전송 후 삭제
--delete-excluded # 제외된 파일도 삭제
# 동기화 정밀 옵션
-c, --checksum # 체크섬으로 비교 (느림)
-u, --update # 대상이 더 새로우면 건너뛰기
--ignore-existing # 존재하는 파일 건너뛰기
제외 패턴¶
# 특정 패턴 제외
rsync -av --exclude='*.log' --exclude='cache/' /source/ /backup/
# 제외 파일 사용
rsync -av --exclude-from='exclude.txt' /source/ /backup/
# exclude.txt 예시
*.log
*.tmp
*.cache
.git/
node_modules/
__pycache__/
.DS_Store
Thumbs.db
증분 백업 스크립트¶
#!/bin/bash
# incremental-backup.sh
# 설정
SOURCE="/data"
BACKUP_BASE="/backup"
LATEST_LINK="$BACKUP_BASE/latest"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_PATH="$BACKUP_BASE/$DATE"
# 이전 백업이 있으면 하드링크 사용
if [ -d "$LATEST_LINK" ]; then
LINK_DEST="--link-dest=$LATEST_LINK"
else
LINK_DEST=""
fi
# rsync 실행
rsync -av --delete \
$LINK_DEST \
--exclude='*.tmp' \
--exclude='cache/' \
"$SOURCE/" \
"$BACKUP_PATH/"
# 최신 링크 업데이트
rm -f "$LATEST_LINK"
ln -s "$BACKUP_PATH" "$LATEST_LINK"
# 30일 이상 된 백업 삭제
find "$BACKUP_BASE" -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
echo "Backup completed: $BACKUP_PATH"
SSH 키 설정 (원격 백업용)¶
# 백업 전용 키 생성
ssh-keygen -t ed25519 -f ~/.ssh/backup_key -N ""
# 원격 서버에 키 복사
ssh-copy-id -i ~/.ssh/backup_key.pub user@backup-server
# 자동화를 위한 config 설정
cat >> ~/.ssh/config << EOF
Host backup-server
HostName 192.168.1.100
User backupuser
IdentityFile ~/.ssh/backup_key
StrictHostKeyChecking no
EOF
# 원격 백업 실행
rsync -avz -e "ssh -i ~/.ssh/backup_key" /data/ backup-server:/backup/
대역폭 제한¶
# 10MB/s로 제한
rsync -av --bwlimit=10000 /source/ /backup/
# 업무 시간 외에만 빠른 속도
if [ $(date +%H) -ge 18 ] || [ $(date +%H) -lt 8 ]; then
BWLIMIT=""
else
BWLIMIT="--bwlimit=5000"
fi
rsync -av $BWLIMIT /source/ /backup/
3. Borg Backup¶
Borg 소개¶
Borg Backup은 중복 제거, 압축, 암호화를 지원하는 백업 프로그램입니다.
# 설치
# Ubuntu/Debian
sudo apt install borgbackup
# RHEL/CentOS
sudo yum install epel-release
sudo yum install borgbackup
# pip로 설치
pip install borgbackup
저장소 초기화¶
# 로컬 저장소 생성
borg init --encryption=repokey /backup/borg-repo
# 원격 저장소 생성
borg init --encryption=repokey user@server:/backup/borg-repo
# 암호화 옵션
# none - 암호화 없음
# repokey - 저장소에 키 저장 (권장)
# keyfile - 로컬 파일에 키 저장
# repokey-blake2 - 더 빠른 해시
백업 생성¶
# 기본 백업
borg create /backup/borg-repo::backup-{now} /data
# 옵션 사용
borg create \
--verbose \
--progress \
--stats \
--compression lz4 \
--exclude '*.tmp' \
--exclude 'cache/' \
/backup/borg-repo::backup-{now:%Y-%m-%d_%H-%M} \
/home \
/etc \
/var/www
압축 옵션¶
| 옵션 | 설명 | 속도 | 압축률 |
|---|---|---|---|
none |
압축 없음 | 가장 빠름 | 없음 |
lz4 |
빠른 압축 | 빠름 | 낮음 |
zstd |
균형잡힌 압축 | 보통 | 중간 |
zlib |
gzip 호환 | 느림 | 높음 |
lzma |
최대 압축 | 매우 느림 | 최고 |
백업 관리¶
# 백업 목록
borg list /backup/borg-repo
# 백업 상세 정보
borg info /backup/borg-repo::backup-2024-01-15
# 백업 내용 확인
borg list /backup/borg-repo::backup-2024-01-15
# 특정 경로만 확인
borg list /backup/borg-repo::backup-2024-01-15 /home/user/
# 백업 비교
borg diff /backup/borg-repo::backup-2024-01-14 backup-2024-01-15
복구¶
# 전체 복구
cd /restore
borg extract /backup/borg-repo::backup-2024-01-15
# 특정 파일/디렉토리 복구
borg extract /backup/borg-repo::backup-2024-01-15 home/user/documents
# 원래 경로로 복구
cd /
borg extract /backup/borg-repo::backup-2024-01-15 etc/nginx/
# 특정 시점으로 마운트 (FUSE)
mkdir /mnt/borg
borg mount /backup/borg-repo::backup-2024-01-15 /mnt/borg
# 파일 탐색 후
borg umount /mnt/borg
보존 정책 (Pruning)¶
# 자동 정리
borg prune \
--keep-hourly=24 \
--keep-daily=7 \
--keep-weekly=4 \
--keep-monthly=12 \
--keep-yearly=2 \
/backup/borg-repo
# 드라이런 (실제 삭제 안 함)
borg prune --dry-run --list \
--keep-daily=7 \
/backup/borg-repo
Borg 백업 스크립트¶
#!/bin/bash
# borg-backup.sh
# 환경 변수 설정
export BORG_REPO="user@backup-server:/backup/borg-repo"
export BORG_PASSPHRASE="your-secure-passphrase"
# 로그 파일
LOG_FILE="/var/log/borg-backup.log"
# 백업 함수
backup() {
echo "Starting backup: $(date)" >> "$LOG_FILE"
borg create \
--verbose \
--filter AME \
--list \
--stats \
--compression lz4 \
--exclude-caches \
--exclude '/home/*/.cache' \
--exclude '/var/tmp/*' \
--exclude '/var/cache/*' \
::'{hostname}-{now:%Y-%m-%d_%H:%M}' \
/etc \
/home \
/var/www \
/var/lib/mysql \
2>> "$LOG_FILE"
backup_exit=$?
echo "Backup finished with exit code: $backup_exit" >> "$LOG_FILE"
}
# 정리 함수
prune() {
echo "Starting prune: $(date)" >> "$LOG_FILE"
borg prune \
--list \
--keep-hourly=24 \
--keep-daily=7 \
--keep-weekly=4 \
--keep-monthly=6 \
2>> "$LOG_FILE"
echo "Prune finished" >> "$LOG_FILE"
}
# 저장소 정합성 검사 (주간)
check() {
if [ $(date +%u) -eq 7 ]; then
echo "Starting check: $(date)" >> "$LOG_FILE"
borg check 2>> "$LOG_FILE"
echo "Check finished" >> "$LOG_FILE"
fi
}
# 실행
backup
prune
check
# 알림 (실패 시)
if [ $backup_exit -ne 0 ]; then
echo "Backup failed!" | mail -s "Borg Backup Alert" admin@example.com
fi
4. tar/cpio 백업¶
tar 백업¶
# 기본 압축 백업
tar -czvf backup.tar.gz /data
# 증분 백업 (snapshot 사용)
tar --create \
--gzip \
--listed-incremental=/backup/snapshot.snar \
--file=/backup/backup-$(date +%Y%m%d).tar.gz \
/data
# 복원
tar --extract \
--gzip \
--listed-incremental=/dev/null \
--file=/backup/backup-20240115.tar.gz \
-C /restore
# 제외 패턴
tar -czvf backup.tar.gz \
--exclude='*.log' \
--exclude='cache' \
/data
cpio 백업¶
# 백업 생성
find /data -print | cpio -ov > backup.cpio
# 압축 백업
find /data -print | cpio -ov | gzip > backup.cpio.gz
# 복원
cpio -iv < backup.cpio
# 압축 파일 복원
gunzip -c backup.cpio.gz | cpio -iv
# 특정 파일만 복원
cpio -iv "*.conf" < backup.cpio
5. 시스템 이미지 백업¶
dd를 이용한 디스크 이미지¶
# 전체 디스크 백업
sudo dd if=/dev/sda of=/backup/disk.img bs=4M status=progress
# 압축과 함께
sudo dd if=/dev/sda bs=4M status=progress | gzip > /backup/disk.img.gz
# 복원
sudo dd if=/backup/disk.img of=/dev/sda bs=4M status=progress
# 압축된 이미지 복원
gunzip -c /backup/disk.img.gz | sudo dd of=/dev/sda bs=4M status=progress
# 파티션만 백업
sudo dd if=/dev/sda1 of=/backup/partition.img bs=4M status=progress
Clonezilla¶
# Clonezilla Live USB 생성 후
# 디스크 이미지 생성 (명령줄)
/usr/sbin/ocs-sr -q2 -c -j2 -z1 -i 4096 -sfsck -senc -p true \
savedisk img_name sda
# 복원
/usr/sbin/ocs-sr -g auto -e1 auto -e2 -r -j2 -c -scr -p true \
restoredisk img_name sda
LVM 스냅샷 백업¶
# 스냅샷 생성
sudo lvcreate -L 10G -s -n data-snap /dev/vg0/data
# 스냅샷 마운트
sudo mkdir /mnt/snapshot
sudo mount -o ro /dev/vg0/data-snap /mnt/snapshot
# 백업 수행
rsync -av /mnt/snapshot/ /backup/data/
# 정리
sudo umount /mnt/snapshot
sudo lvremove /dev/vg0/data-snap
6. 재해복구 전략¶
DR 계획 구성요소¶
┌─────────────────────────────────────────────────────────────┐
│ 재해복구 계획 │
├─────────────────────────────────────────────────────────────┤
│ 1. 리스크 평가 │
│ - 잠재적 위협 식별 │
│ - 비즈니스 영향 분석 │
│ │
│ 2. 복구 목표 설정 │
│ - RTO/RPO 정의 │
│ - 우선순위 결정 │
│ │
│ 3. 백업 전략 │
│ - 백업 유형 및 주기 │
│ - 저장 위치 (온사이트/오프사이트) │
│ │
│ 4. 복구 절차 │
│ - 단계별 복구 가이드 │
│ - 연락처 및 역할 │
│ │
│ 5. 테스트 및 유지보수 │
│ - 정기적 복구 테스트 │
│ - 문서 업데이트 │
└─────────────────────────────────────────────────────────────┘
복구 체크리스트¶
#!/bin/bash
# disaster-recovery-checklist.sh
echo "=== 재해복구 체크리스트 ==="
# 1. 하드웨어 상태 확인
echo "[1] 하드웨어 상태 확인"
lsblk
free -h
cat /proc/cpuinfo | grep "model name" | head -1
# 2. 네트워크 연결 확인
echo "[2] 네트워크 연결"
ip addr show
ping -c 3 8.8.8.8
# 3. 백업 저장소 접근 확인
echo "[3] 백업 저장소 접근"
# 로컬 백업
ls -la /backup/
# 원격 백업
ssh backup-server "ls -la /backup/"
# 4. 백업 무결성 검증
echo "[4] 백업 무결성"
# Borg 검증
borg check /backup/borg-repo
# 5. 복구 테스트 (샘플)
echo "[5] 샘플 파일 복구 테스트"
mkdir -p /tmp/recovery-test
borg extract /backup/borg-repo::latest etc/hostname -C /tmp/recovery-test
diff /etc/hostname /tmp/recovery-test/etc/hostname
echo "=== 체크리스트 완료 ==="
베어메탈 복구 절차¶
# 1. 부팅 미디어로 부팅 (Ubuntu Live USB 등)
# 2. 네트워크 설정
ip addr add 192.168.1.100/24 dev eth0
ip route add default via 192.168.1.1
# 3. 디스크 파티셔닝
parted /dev/sda mklabel gpt
parted /dev/sda mkpart primary ext4 1MiB 512MiB # /boot
parted /dev/sda mkpart primary ext4 512MiB 100% # /
mkfs.ext4 /dev/sda1
mkfs.ext4 /dev/sda2
# 4. 마운트
mount /dev/sda2 /mnt
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot
# 5. 백업에서 복원
# rsync 사용
rsync -av backup-server:/backup/latest/ /mnt/
# 또는 Borg 사용
borg extract backup-server:/backup/borg-repo::latest -C /mnt
# 6. chroot로 부트로더 설치
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
chroot /mnt
grub-install /dev/sda
update-grub
exit
# 7. 정리 및 재부팅
umount -R /mnt
reboot
7. 자동화 및 모니터링¶
systemd 타이머를 이용한 자동화¶
# /etc/systemd/system/backup.service
[Unit]
Description=Daily Backup Service
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=root
Nice=19
IOSchedulingClass=idle
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.target
# 타이머 활성화
sudo systemctl enable --now backup.timer
# 상태 확인
systemctl list-timers --all | grep backup
백업 모니터링 스크립트¶
#!/bin/bash
# backup-monitor.sh
BACKUP_DIR="/backup"
MAX_AGE_HOURS=26
ALERT_EMAIL="admin@example.com"
LOGFILE="/var/log/backup-monitor.log"
check_backup_age() {
local newest=$(find "$BACKUP_DIR" -maxdepth 1 -type d -name "20*" | sort -r | head -1)
if [ -z "$newest" ]; then
echo "ERROR: No backup found" | tee -a "$LOGFILE"
return 1
fi
local age_seconds=$(($(date +%s) - $(stat -c %Y "$newest")))
local age_hours=$((age_seconds / 3600))
if [ $age_hours -gt $MAX_AGE_HOURS ]; then
echo "WARNING: Latest backup is $age_hours hours old" | tee -a "$LOGFILE"
return 1
fi
echo "OK: Latest backup is $age_hours hours old ($newest)" | tee -a "$LOGFILE"
return 0
}
check_backup_size() {
local today=$(find "$BACKUP_DIR" -maxdepth 1 -type d -name "$(date +%Y-%m-%d)*" | head -1)
local yesterday=$(find "$BACKUP_DIR" -maxdepth 1 -type d -name "$(date -d yesterday +%Y-%m-%d)*" | head -1)
if [ -n "$today" ] && [ -n "$yesterday" ]; then
local size_today=$(du -s "$today" | awk '{print $1}')
local size_yesterday=$(du -s "$yesterday" | awk '{print $1}')
# 50% 이상 차이나면 경고
local diff=$((size_today - size_yesterday))
local threshold=$((size_yesterday / 2))
if [ ${diff#-} -gt $threshold ]; then
echo "WARNING: Significant size change: $size_yesterday -> $size_today" | tee -a "$LOGFILE"
return 1
fi
fi
return 0
}
check_disk_space() {
local usage=$(df "$BACKUP_DIR" | awk 'NR==2 {print $5}' | tr -d '%')
if [ $usage -gt 90 ]; then
echo "CRITICAL: Backup disk usage at ${usage}%" | tee -a "$LOGFILE"
return 1
elif [ $usage -gt 80 ]; then
echo "WARNING: Backup disk usage at ${usage}%" | tee -a "$LOGFILE"
return 1
fi
echo "OK: Backup disk usage at ${usage}%" | tee -a "$LOGFILE"
return 0
}
# 메인 실행
echo "=== Backup Monitor: $(date) ===" >> "$LOGFILE"
ERRORS=0
check_backup_age || ((ERRORS++))
check_backup_size || ((ERRORS++))
check_disk_space || ((ERRORS++))
if [ $ERRORS -gt 0 ]; then
tail -20 "$LOGFILE" | mail -s "Backup Monitor Alert" "$ALERT_EMAIL"
fi
exit $ERRORS
Prometheus 메트릭 수집¶
#!/bin/bash
# backup-metrics.sh (node_exporter textfile collector용)
METRICS_FILE="/var/lib/node_exporter/textfile_collector/backup.prom"
BACKUP_DIR="/backup"
# 최신 백업 시간
newest=$(find "$BACKUP_DIR" -maxdepth 1 -type d -name "20*" | sort -r | head -1)
if [ -n "$newest" ]; then
backup_timestamp=$(stat -c %Y "$newest")
echo "backup_last_success_timestamp $backup_timestamp" > "$METRICS_FILE"
fi
# 백업 크기
backup_size=$(du -sb "$newest" 2>/dev/null | awk '{print $1}')
echo "backup_size_bytes $backup_size" >> "$METRICS_FILE"
# 디스크 사용량
disk_usage=$(df "$BACKUP_DIR" | awk 'NR==2 {print $3}')
disk_total=$(df "$BACKUP_DIR" | awk 'NR==2 {print $2}')
echo "backup_disk_used_bytes $((disk_usage * 1024))" >> "$METRICS_FILE"
echo "backup_disk_total_bytes $((disk_total * 1024))" >> "$METRICS_FILE"
연습 문제¶
문제 1: rsync 증분 백업¶
하드링크를 이용한 rsync 증분 백업 스크립트를 작성하세요:
- 원본: /home/user
- 백업 위치: /backup/home
- 일일 백업, 최신 백업을 latest 심볼릭 링크로 연결
- 30일 이상 된 백업 자동 삭제
문제 2: Borg 복구¶
Borg 저장소에서 특정 날짜의 백업 중 /etc/nginx/ 디렉토리만 복구하는 명령을 작성하세요.
문제 3: DR 테스트¶
분기별 재해복구 테스트 절차를 작성하세요. 포함해야 할 항목: - 백업 무결성 검증 - 샘플 데이터 복구 테스트 - 전체 시스템 복구 테스트 (가능하면)
정답¶
문제 1 정답¶
#!/bin/bash
SOURCE="/home/user"
BACKUP_BASE="/backup/home"
DATE=$(date +%Y-%m-%d)
BACKUP_PATH="$BACKUP_BASE/$DATE"
LATEST="$BACKUP_BASE/latest"
# 하드링크 옵션
if [ -d "$LATEST" ]; then
LINK="--link-dest=$LATEST"
else
LINK=""
fi
# 백업 실행
rsync -av --delete $LINK "$SOURCE/" "$BACKUP_PATH/"
# 최신 링크 업데이트
rm -f "$LATEST"
ln -s "$BACKUP_PATH" "$LATEST"
# 30일 이상 된 백업 삭제
find "$BACKUP_BASE" -maxdepth 1 -type d -name "20*" -mtime +30 -exec rm -rf {} \;
문제 2 정답¶
# 백업 목록 확인
borg list /backup/borg-repo
# 특정 날짜 백업에서 nginx 설정 복구
borg extract /backup/borg-repo::backup-2024-01-15 etc/nginx
# 다른 경로로 복구
mkdir /tmp/restore
cd /tmp/restore
borg extract /backup/borg-repo::backup-2024-01-15 etc/nginx
문제 3 정답¶
# 분기별 DR 테스트 절차
## 1. 백업 무결성 검증 (매 분기)
- [ ] Borg check 실행: `borg check /backup/borg-repo`
- [ ] 백업 목록 검토: `borg list /backup/borg-repo`
- [ ] 최근 백업 상세 확인: `borg info /backup/borg-repo::latest`
## 2. 샘플 데이터 복구 테스트 (매 분기)
- [ ] 테스트 디렉토리 생성
- [ ] 설정 파일 복구 테스트 (/etc/)
- [ ] 데이터 파일 복구 테스트 (/var/www/)
- [ ] 복구된 파일 무결성 확인 (diff 또는 checksum)
## 3. 전체 시스템 복구 테스트 (반기)
- [ ] 테스트 VM 또는 물리 서버 준비
- [ ] 베어메탈 복구 절차 실행
- [ ] 부팅 확인
- [ ] 서비스 정상 동작 확인
- [ ] 데이터 무결성 검증
## 4. 문서화 및 개선
- [ ] 테스트 결과 문서화
- [ ] 발견된 문제점 기록
- [ ] 절차 개선 사항 반영
- [ ] RTO/RPO 달성 여부 확인
다음 단계¶
- 20_Kernel_Management.md - 커널 컴파일, 모듈, GRUB 설정
참고 자료¶
- rsync Manual
- Borg Backup Documentation
- Clonezilla
man rsync,man tar,man dd,man borg