복원한 서비스 검증
100분 안팎
학습 목표
복원 경로를 사용하는 별도 실습 유닛에서 HTTP 데이터와 복구 소요 시간을 확인합니다.
개념
파일 검증에서 서비스 검증으로 넘어갑니다
복원 파일의 해시가 모두 맞아도 서비스가 이전 DATA_FILE을 읽으면 복구를 확인한 것이 아닙니다. health가 200이어도 items 조회가 빈 값이면 사용자 데이터는 돌아오지 않은 상태입니다. 이번 레슨은 복원 경로를 가리키는 별도 유닛을 만들고 bcweb 계정으로 실행해 /items의 전체 JSON을 백업 시점 기대값과 비교합니다. 파일·계정·서비스·시간의 관측을 한 보고서로 연결합니다.
기동 설정은 복원한 설정의 사본과 분리합니다
복원된 service.env는 백업 당시 원본 경로와 실습망 주소를 그대로 가진 채 해시 검증에 사용합니다. 이 파일을 즉시 편집하면 복구한 원형의 증거가 달라집니다. 대신 recovery.env를 별도로 만들고 DATA_FILE만 복원 경로로, BIND_ADDRESS를 127.0.0.1로, RUN_SECONDS를 5로 지정합니다. 설정을 바꾼 이유와 원본 설정 보존 여부를 함께 기록합니다.
별도 유닛은 실행 조건을 명시합니다
bootcamp-systems-recovery.service는 User=bcweb, Group=bcapp, 복원 경로의 WorkingDirectory와 ExecStart, 별도 EnvironmentFile, Restart=no를 가집니다. 설치 전에 systemd-analyze verify로 유닛 구조를 검사합니다. 같은 이름의 /run 또는 /etc 유닛이 이미 있으면 덮어쓰지 않고 먼저 상태를 조사합니다. 파일 이름만 다르고 실제 작업 경로가 원본이라면 격리 복원이라는 목표를 달성하지 못합니다.
원본 서비스와 포트 경합을 피합니다
기존 20초 서비스가 inactive인지 확인하고 자연 종료 뒤 검사를 시작합니다. 원본 앱은 18080 포트를 사용하며 복원 앱도 같은 포트를 쓰지만 루프백에만 바인딩합니다. 같은 시각에 다른 프로세스가 포트를 점유할 수 있으므로 Address already in use가 나오면 journal의 원인을 확인합니다. 포트를 얻기 위해 다른 프로세스를 종료하지 않습니다. 별도 실습 유닛의 유한 수명과 비재시작 조건을 유지합니다.
서비스 계정의 실제 접근을 검사합니다
기동 전에 sudo -u bcweb test로 복원 items.json의 읽기와 쓰기 권한을 확인합니다. root가 읽었다는 사실은 bcweb의 권한을 증명하지 않습니다. 파일별 UID/GID·모드 검사는 내용 검증과 함께 실시하고 그룹 탐색 권한이 있는 부모 경로까지 점검합니다. 이 실습의 HTTP는 조회만 하므로 쓰기 가능성은 계정 권한 검사로 보완합니다. 별도 임시 쓰기나 앱 업데이트 회귀가 필요한 환경은 검사 계약을 추가합니다.
기동 성공과 준비 상태를 나눕니다
systemctl start가 끝난 시각에 앱이 바로 HTTP를 받는다고 가정하지 않습니다. 검사기는 짧은 간격으로 최대 스무 번 요청하고 각 요청에 제한 시간을 둡니다. HTTP 200을 받은 뒤 JSON을 읽고 기대 값과 비교합니다. 응답이 끝내 없으면 recovery HTTP unavailable로 실패하며 journal과 유닛 상태를 확인합니다. 무한 재시도는 RTO 위반을 숨길 수 있으므로 반복 상한과 전체 복구 시간을 함께 기록합니다.
조회는 백업 시점의 업무 값과 비교합니다
expected_items는 선택한 묶음의 JSON 전체 값입니다. count뿐 아니라 items의 원소·순서 등 저장된 구조를 비교합니다. health의 status ok를 대신 보내면 DATA_MISMATCH입니다. 빈 배열도 백업에서 빈 배열이었다면 정상일 수 있지만 백업에서 값이 있었는데 복원 뒤 비면 실패입니다. 예상 값과 실제 응답을 같이 남겨 담당자가 단순 200과 데이터 복구 성공을 구분할 수 있게 합니다.
실제 소요 시간은 단조 시계로 잽니다
elapsed_seconds는 복원 시작부터 권한 조정·기동·HTTP 내용 확인까지 time.monotonic의 차이로 측정합니다. 사람이 읽는 시작·종료 시각은 UTC 기록으로 따로 남깁니다. 벽시계가 조정될 수 있으므로 소요 시간과 달력 시각의 역할을 나눕니다. 이번 VM 검사는 작은 데이터에 RTO 30초를 적용합니다. 교육 과제의 기준이며 실제 서비스의 RTO를 이 숫자로 정하라는 지시는 아닙니다.
손실 목표와 실제 유실은 다른 값입니다
RPO는 복구 가능한 데이터 시점에 대한 목표이고 실제 유실은 그 뒤 반영되지 못한 변경입니다. 이번 검사는 작성자가 종료한 상태를 계속 유지하므로 실습 중 미반영 쓰기는 0건입니다. backup_window_seconds는 검사 시작과 복원 시작 사이의 관측 간격이며 지속 쓰기 서비스의 유실 건수로 환산하지 않습니다. 별도 정책에서는 장애 시각과 마지막 유효 데이터 시점의 차이를 계산하고 백업 실패 시 더 오래된 기준을 선택한 이유를 적습니다.
판정 함수를 시간 경계까지 확인합니다
evaluate_recovery는 데이터가 다르면 DATA_MISMATCH, 데이터가 같지만 소요가 목표를 넘으면 RTO_MISSED, 그다음 백업 간격이 목표를 넘으면 RPO_MISSED를 반환합니다. 정확히 같은 값은 이번 계약에서 목표 이내입니다. 음수·NaN·무한대와 논리값은 유효 시간으로 받지 않습니다. 여러 문제가 있으면 첫 판정만 반환하는 함수이므로 보고서에는 원래 수치도 남겨 나머지 위반을 사람이 확인하게 합니다.
고정 입력 예제와 실측을 구분합니다
demo.py recovery는 HTTP 요청 없이 기대 JSON과 고정 시간값을 함수에 전달합니다. 출력 PASS와 세 실패 상태는 판단 로직의 증거이며 실제 복구 시간이 10초라는 뜻이 아닙니다. VM check.sh가 별도 유닛과 소켓을 사용해 실제 elapsed_seconds와 응답을 evidence/recovery.json에 기록합니다. 소켓이 제한된 맥에서는 check-local.sh의 네 검사를 완료하고 VM 결과는 external PENDING으로 남깁니다.
완료 뒤 파일과 원본을 다시 확인합니다
HTTP 비교 후 복원 파일의 해시·모드·소유자를 다시 검사합니다. 기동 중 다른 코드나 파일이 바뀌었는지 잡기 위한 확인입니다. 원본 다섯 파일의 기동 전·후 해시도 비교해 복원 실습이 기존 data나 설치 유닛을 덮어쓰지 않았음을 남깁니다. 실제 서비스 계정의 데이터 변경 시험이 필요하면 새 테스트 데이터와 기대 변화량을 정해야 하며 기존 값을 임의로 바꾸지 않습니다.
정리는 자연 종료 확인 뒤에 합니다
복원 유닛은 5초 뒤 자연 종료하고 검사기는 최대 30초 기다립니다. inactive를 확인한 경우에만 자기 /run 유닛과 전용 /tmp 경로를 정리합니다. 종료 확인이 실패하면 경로와 유닛을 보존하고 상태를 조사하도록 실패합니다. stop이나 kill로 강제로 끝내고 성공이라고 보고하지 않습니다. 포트와 유닛을 남기지 않는 정상 정리도 제출 기준에 포함합니다.
복구 보고서는 다음 담당자의 판단 자료입니다
recovery.md에는 백업 시점·선택 이유·RPO/RTO·실제 소요·유실 범위·조회 결과·권한 확인·원본 보존·잔여 작업을 씁니다. 생성된 수치만 붙이지 말고 작은 닫힌 데이터 실습이라는 제한과 지속 쓰기 환경에서 필요한 추가 확인을 설명합니다. 미션은 앞 모듈 용량 evidence까지 이어 보존합니다. 파일 백업 자동화의 다른 구현은 더 읽기로 연결하고 이 레슨의 완료는 실제 실행 경로와 업무 응답이 일치한다는 증거로 판단합니다.
따라하기
내용·시간 목표의 판정 재현
solution ZIP에서 고정 관측 입력을 판정합니다. 실제 HTTP나 실측 10초를 의미하지 않습니다.
python3 -B demo.py recovery실행 결과
PASS DATA_MISMATCH RTO_MISSED RPO_MISSED
단조 시계의 차이를 구하는 방법
짧은 계산 구간을 실제로 측정하고 음수가 아닌지만 출력합니다. 시간값을 특정 수치로 꾸미지 않습니다.
import time
start = time.monotonic()
sum(range(100))
elapsed = time.monotonic() - start
print("NONNEGATIVE", elapsed >= 0)실행 결과
NONNEGATIVE True
데이터 판정의 로컬 회귀
starter의 evaluate_recovery에서 누락된 데이터 비교를 구현합니다. solution은 stderr에 네 검사와 OK를 표시합니다.
bash check-local.shVM에서 별도 유닛과 HTTP 검증
README의 계정·설치·자연 종료·포트 조건을 확인한 systemd Linux VM에서 sudo -v 후 실행합니다. evidence/recovery.json과 recovery.md의 실측·조회값·목표 판정, 원본 보존 및 자연 종료 뒤 유닛 정리를 확인합니다. 맥에서는 이 단계가 external PENDING입니다.
sudo -v
bash check.sh확인 문제
실습
evaluate_recovery의 TODO를 구현하고 bash check-local.sh로 네 검사를 통과시킵니다. 준비된 Linux VM에서 bash check.sh를 실행해 복원 경로를 사용하는 별도 systemd 유닛의 실제 HTTP JSON과 목표를 검증합니다. README의 선행 조건과 관리자 작업을 먼저 확인합니다. check.sh의 검사는 vm_check.py에 있으며 원본을 바꾸지 않고 실측을 evidence로 남깁니다. 5초 자연 종료를 확인하고 자기 유닛만 정리합니다.
실행 명령
bash check.sh
기대 결과
로컬 4 tests와 VM의 해시·UID/GID·모드·bcweb 접근·HTTP /items·복구 목표·원본 보존·자연 종료 정리 검사 통과
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- 백업 결과를 신뢰하기 위한 확인 방법을 설명합니다.