백업·복구
매일 밤 Postgres 덤프와 RustFS 미러를 받는 systemd 타이머, 그리고 되돌리는 방법
Geo-MLOps 의 모든 상태는 두 곳에 있습니다. Postgres(앱과 MLflow 가 함께 쓰는 DB)와 RustFS(데이터셋·이미지 레이어·모델 아티팩트·빌드 로그·엣지 업로드)입니다. 둘 다 Docker 볼륨에만 있어서, MLflow 실험 영구 삭제나 테넌트 삭제처럼 실수로 지운 것은 백업 없이는 되돌릴 수 없습니다. Compose 는 백업을 하지 않으므로, 소스에 함께 들어 있는 백업 스크립트와 systemd 타이머를 설치합니다.
무엇을 어떻게 받나
| 대상 | 방식 | 보존 |
|---|---|---|
| Postgres | 컨테이너 안의 pg_dump -Fc 로 BACKUP_DIR/postgres/mlflow-<UTC시각>.dump 에 저장. 받자마자 pg_restore --list 로 읽어 보고, 깨진 파일은 남기지 않음 | BACKUP_KEEP_DAYS(기본 14일)보다 오래된 덤프는 지움 |
| RustFS | 버킷마다 aws s3 sync 로 BACKUP_DIR/objects/<버킷>/ 에 복사 | 추가만 합니다(--delete 없음). 지운 객체도 미러에 남습니다. 공간이 모자라면 손으로 정리 |
- 매일 03:30(최대 15분 무작위 지연)에 돕니다. 서버가 꺼져 있던 밤의 백업은 다음 부팅 때 따라잡습니다.
- 낮은 우선순위(
Nice=10, I/O idle)로 돌아 학습·요청과 디스크를 다투지 않습니다. pg_dump는 Postgres 컨테이너 안의 것을, S3 복사는 AWS CLI 컨테이너를 씁니다. 서버에 따로 설치할 것이 없습니다.
설치 (서버에서 한 번)
-
스크립트와 유닛 파일을 설치합니다.
D=/opt/geo-mlops/deploy/backup sudo install -m 0755 $D/backup.sh /usr/local/sbin/geo-mlops-backup sudo install -m 0644 $D/geo-mlops-backup.service /etc/systemd/system/ sudo install -m 0644 $D/geo-mlops-backup.timer /etc/systemd/system/ -
기본값과 다르게 쓸 것이 있으면
/etc/geo-mlops/backup.env에 적습니다(없어도 됩니다).sudo tee /etc/geo-mlops/backup.env >/dev/null <<'ENV' BACKUP_DIR=/mnt/backup/geo-mlops BACKUP_KEEP_DAYS=14 ENV -
타이머를 켜고, 첫 백업을 지금 한 번 돌려 확인합니다.
sudo systemctl daemon-reload sudo systemctl enable --now geo-mlops-backup.timer sudo systemctl start geo-mlops-backup.service journalctl -u geo-mlops-backup.service -n 20 # 마지막 줄 "backup finished" systemctl list-timers geo-mlops-backup.timer # 다음 실행 시각
backup.env 로 바꿀 수 있는 값
| 변수 | 기본값 | 뜻 |
|---|---|---|
BACKUP_DIR | /var/backups/geo-mlops | 백업이 쌓일 곳 |
BACKUP_KEEP_DAYS | 14 | DB 덤프 보존 일수 |
BACKUP_BUCKETS | (비움 = 모든 버킷) | 공백으로 구분한 버킷 이름 |
BACKUP_SKIP_OBJECTS | 0 | 1 이면 DB 만 백업 |
PG_CONTAINER / PG_USER / PG_DB | geo-mlops-mlflow-postgres / mlflow / mlflow | Postgres 컨테이너와 계정 |
S3_ENDPOINT / S3_ACCESS_KEY / S3_SECRET_KEY | http://localhost:9000 / rustfsadmin / rustfsadmin | RustFS 접속 정보. Compose 의 계정을 바꿨다면 여기도 바꿉니다 |
AWS_CLI_IMAGE | amazon/aws-cli:2.34.63 | S3 복사에 쓸 이미지 |
복구
데이터베이스
앱을 멈춰 DB 를 쓰는 쪽이 없게 한 뒤 덤프를 되돌립니다.
docker stop geo-mlops-app
docker exec -i geo-mlops-mlflow-postgres \
pg_restore -U mlflow -d mlflow --clean --if-exists --no-owner \
< /var/backups/geo-mlops/postgres/mlflow-<UTC시각>.dump
docker start geo-mlops-app
객체
버킷 하나(또는 그 안의 접두사)를 미러에서 되올립니다. 미러는 추가만 하므로, 백업 시점 이후에 지운 객체도 되살아납니다. 필요한 접두사만 골라 올리세요.
docker run --rm --network host -v /var/backups/geo-mlops/objects:/backup \
-e AWS_ACCESS_KEY_ID=rustfsadmin -e AWS_SECRET_ACCESS_KEY=rustfsadmin \
-e AWS_DEFAULT_REGION=us-east-1 -e AWS_REQUEST_CHECKSUM_CALCULATION=when_required \
amazon/aws-cli:2.34.63 --endpoint-url http://localhost:9000 \
s3 sync /backup/datasets/<tenant_id>/<dataset_id>/ s3://datasets/<tenant_id>/<dataset_id>/
복구 연습 (분기마다)
복구가 되는지 모르는 백업은 백업이 아닙니다. 분기에 한 번, 운영 서버가 아닌 곳에서 덤프가 읽히는지 확인합니다.
BACKUP_DIR=/tmp/geo-backup-drill BACKUP_BUCKETS=build-logs /usr/local/sbin/geo-mlops-backup
docker exec -i geo-mlops-mlflow-postgres pg_restore --list \
< /tmp/geo-backup-drill/postgres/mlflow-*.dump | head
다음: 앞단 프록시 주의