Minecraft 서버와 백업 삭제 절차

마지막 백업 보존, Spot 복구 구성 제거, 삭제 보호 해제와 서버 destroy

서버 운영을 끝낼 때 아래 순서로 마지막 백업과 실제 리소스를 먼저 확인한다. VM을 삭제하면 자동 삭제 부팅 디스크와 그 안의 월드도 사라진다. Terraform state는 실제 리소스 삭제가 끝날 때까지 보존한다.

선수 조건

삭제할 프로젝트, 서버 루트와 선택형 복구 루트를 정확히 식별해야 한다. 06편의 격리 시험을 통과한 마지막 백업을 보존할 위치도 정한다.

위험 명령

아래의 terraform apply와 gcloud storage rm은 리소스나 데이터를 삭제한다. 변수와 저장한 계획을 직접 읽은 경우에만 실행한다. 로컬 검증에서는 삭제 명령을 실행하지 않았다.

Cloud Storage soft delete가 켜져 있으면 삭제한 객체와 버킷은 보존 기간 동안 복구할 수 있고 저장 비용도 남을 수 있다. live 객체가 목록에서 사라진 시점과 비용이 완전히 멈추는 시점은 다를 수 있다.

프로젝트, 백업 버킷과 state

서버 루트에서 프로젝트, 백업 버킷과 현재 state를 확인한다.

확인

cd "${HOME}/minecraft-one-root"

export PROJECT_ID="$(
  terraform output -raw minecraft_project_id
)"
export BACKUP_BUCKET="$(
  terraform output -raw backup_bucket_name
)"

printf 'Project: %s\nBackup bucket: %s\n' \
  "${PROJECT_ID}" \
  "${BACKUP_BUCKET}"
gcloud config get-value project
terraform state list

프로젝트 두 값이 다르거나 출력이 비면 멈춘다. state에는 Minecraft VM, 네트워크, 고정 IP, 서비스 계정과 백업 버킷이 보여야 한다.

마지막 백업

서버가 실행 중이고 자동 백업을 켰다면 마지막 백업을 만든다.

실행: 서버 삭제 직전

export MINECRAFT_INSTANCE="$(
  terraform output -raw minecraft_instance_name
)"
export MINECRAFT_ZONE="$(
  terraform output -raw minecraft_zone
)"

gcloud compute ssh "${MINECRAFT_INSTANCE}" \
  --zone="${MINECRAFT_ZONE}" \
  --command="sudo systemctl start minecraft-backup.service"

새 archive와 manifest를 찾아 06편의 minecraft-backup-verify를 실행한다. 성공한 객체의 전체 이름을 기록한다. 백업 버킷도 삭제한다면 먼저 두 파일을 Cloud Shell로 받는다.

timestamp를 세 번 입력하지 않도록 파일 이름을 변수에 한 번만 넣는다.

export LAST_BACKUP="minecraft-정확한-TIMESTAMP.tar.gz"

gcloud storage cp \
  "gs://${BACKUP_BUCKET}/backups/${LAST_BACKUP}" \
  .
gcloud storage cp \
  "gs://${BACKUP_BUCKET}/backups/${LAST_BACKUP}.sha256" \
  .
sha256sum --check "${LAST_BACKUP}.sha256"

OK를 확인하지 못하면 리소스를 삭제하지 않는다. Cloud Shell 홈 디렉터리만 장기 보관 장소로 사용하지 않는다. Cloud Shell의 더보기 메뉴에서 파일 다운로드를 선택해 archive와 manifest를 각각 내 컴퓨터로 옮긴다. 대화상자의 경로 칸에는 홈 디렉터리 기준 파일 이름을 넣는다. 예를 들어 minecraft-20260729T043000Z.tar.gz처럼 방금 받은 파일 이름 그대로다. 두 파일이 로컬 장기 보관 위치에 있고 로컬 SHA-256 검사도 OK인 것을 확인한 뒤에만 버킷 객체를 삭제한다.

Spot 복구 루트 삭제

09편을 적용하지 않았다면 이 절을 건너뛴다. 복구 루트를 먼저 없애야 서버 삭제 중에 늦게 도착한 선점 사건이 시작 요청을 보내지 않는다.

조건부 실행: 복구 루트를 적용한 경우

cd "${HOME}/minecraft-spot-recovery"
terraform plan -destroy -out=destroy-recovery.tfplan
terraform show destroy-recovery.tfplan

계획에는 함수, 소스 버킷, Pub/Sub topic, Logging sink, runtime과 trigger 서비스 계정과 관련 IAM만 나와야 한다. Minecraft VM, 디스크나 네트워크가 보이면 적용하지 않는다.

데이터 삭제: 복구 루트 제거

terraform apply destroy-recovery.tfplan
terraform state list

마지막 명령이 아무것도 출력하지 않아야 한다. 삭제 실패가 있으면 state를 건드리지 말고 새 destroy plan에서 남은 실제 리소스를 확인한다.

VM 삭제 보호 해제

서버 루트로 돌아와 terraform.tfvars의 한 값만 바꾼다.

cd "${HOME}/minecraft-one-root"
nano terraform.tfvars
deletion_protection = false

실행: 변경 계획만 만든다

terraform validate
terraform plan \
  -out=disable-deletion-protection.tfplan
terraform show disable-deletion-protection.tfplan

같은 VM의 deletion_protection 변경만 보여야 한다. 교체나 디스크 삭제가 보이면 적용하지 않는다.

실행: 삭제 보호 해제

terraform apply disable-deletion-protection.tfplan

이 단계는 다음 destroy가 VM을 삭제할 수 있도록 보호 속성만 바꾼다.

백업 버킷 보존 또는 삭제

백업 객체가 남아 있으면 force_destroy = false가 버킷 삭제를 막는다. 아래 두 경로 중 하나만 고른다.

백업 버킷을 계속 보존한다

실제 버킷과 객체를 남기고 Terraform state에서 버킷 리소스만 분리한다.

조건부 실행: Cloud Storage에 백업을 보존할 때

terraform state rm google_storage_bucket.backup

이 명령은 버킷을 삭제하지 않는다. 이후 Terraform도 이 버킷의 lifecycle을 관리하지 않는다. 버킷 이름, 보존 기한과 앞으로 삭제할 사람을 기록한다. Storage 비용은 계속 발생할 수 있다.

state에서 분리한 뒤에는 이 루트에서 plan -destroy 외의 일반 terraform plan을 실행하지 않는다. 구성 파일에는 버킷 정의가 남아 있어서 일반 plan은 같은 이름의 버킷을 새로 만들려고 하고, 적용하면 이름 충돌로 실패한다. 이 루트의 남은 절차는 삭제 계획뿐이다.

백업 버킷도 삭제한다

먼저 버킷의 soft delete 정책과 live, noncurrent 객체를 읽는다.

확인: 백업 버킷 보호 정책과 객체

gcloud storage buckets describe \
  "gs://${BACKUP_BUCKET}" \
  --format="default(soft_delete_policy)"

gcloud storage ls \
  --recursive \
  --all-versions \
  "gs://${BACKUP_BUCKET}/"

목록을 한 줄씩 검토한다. 아래 명령의 <정확한-객체-이름>에는 목록에 나온 archive 또는 manifest 한 개의 전체 경로를 넣는다. wildcard와 **는 쓰지 않는다.

데이터 삭제: 로컬 보존본 검증 뒤 객체별 반복

gcloud storage rm \
  --all-versions \
  "gs://${BACKUP_BUCKET}/<정확한-객체-이름>"

다시 목록을 읽어 아무 객체도 남지 않았는지 확인한다. 모르는 파일은 삭제하지 않고 소유자를 찾는다.

객체를 지웠을 때 soft delete가 켜져 있었다면 일반 목록에는 보이지 않는 사본이 남는다. 다음 **는 조회 명령에만 쓰며 삭제 명령에 복사하지 않는다.

확인: soft-deleted 객체

gcloud storage ls \
  "gs://${BACKUP_BUCKET}/**" \
  --soft-deleted \
  --full

출력이 있으면 각 항목의 삭제 시각과 hard delete 시각을 기록한다. 이 객체는 보존 기간이 끝날 때까지 영구 삭제할 수 없다. live와 noncurrent 객체가 비어 있으면 다음 Terraform destroy가 버킷을 삭제한다. soft delete 정책이 켜진 버킷은 삭제 뒤에도 soft-deleted 버킷으로 남을 수 있다.

서버 루트 destroy

실행: 삭제 계획만 만든다

terraform plan -destroy -out=destroy-server.tfplan
terraform show destroy-server.tfplan

VM과 자동 삭제 부팅 디스크, 고정 IP, 방화벽, 서브넷, VPC, 서버 서비스 계정이 삭제 대상이어야 한다. 보존 경로를 골랐다면 백업 버킷은 계획에 없어야 한다. 삭제 경로를 골랐다면 빈 백업 버킷도 삭제 대상이다.

데이터 삭제: 계획을 모두 읽은 뒤

terraform apply destroy-server.tfplan
terraform state list

마지막 명령이 아무것도 출력하지 않아야 한다. Error deleting...이 나오면 state부터 지우지 않는다. 오류를 해결하고 새 destroy plan으로 남은 대상만 확인한다.

완료 체크

  • 마지막 archive와 manifest를 보존했고 SHA-256을 확인했다.
  • 적용했다면 Spot 복구 루트를 먼저 삭제했다.
  • 삭제 보호 해제 계획에는 VM 속성 변경만 있었다.
  • 백업 버킷 보존 또는 객체별 삭제 중 한 경로만 실행했다.
  • 서버 루트의 terraform state list가 비었다.
  • soft-deleted 객체가 있다면 hard delete 시각과 그때까지 남을 수 있는 비용을 기록했다.

두 루트의 terraform state list가 비었으면 state와 남은 비용 정리에서 backend 객체와 프로젝트 전체의 잔여 리소스를 확인한다.

Comments

댓글

    이미지 확대