Devin.KR

증상과 가설 구분

90분 안팎

학습 목표

권한 오류·이름 해석 실패·inode 부족 중 제공된 장애를 관측 근거로 좁힙니다.

개념

먼저 영향과 관측 위치를 고정합니다

웹 화면이 열리지 않는다는 연락만으로 서버 전체를 재기동하면 원래 증거가 사라지고 다른 서비스까지 영향을 받을 수 있습니다. 첫 대응은 사용자가 실패한 요청, 실패를 본 시각, 영향을 받는 범위, 마지막 정상 관측을 적는 일입니다. 실습실에서는 /health와 /items를 나누고 이름으로 접근한 요청인지 IP로 접근한 요청인지 기록합니다. 같은 증상이라도 실패한 경계가 다르면 다음 조회가 달라집니다.

이번 모듈의 실습 환경

Python 3와 bash를 준비하고 레슨 ZIP을 각각 새 개인 폴더에 풉니다. 로컬 검사는 합성 관측 JSON과 임시 파일을 사용하여 계정이나 방화벽을 바꾸지 않습니다. 미션은 m09 solution 전체를 previous/에 보존합니다. 실제 Linux VM·HTTP·서비스 계정·timer 검증은 external이며 실행하지 않았으면 PENDING으로 씁니다. 기존 장기 프로세스를 종료하거나 운영 환경에 장애를 주입하는 작업은 없습니다.

증상은 사실이고 가설은 설명입니다

EACCES를 보았다는 문장은 관측입니다. 서비스 계정이 파일을 읽을 수 없다는 것은 별도 실행 계정의 확인 결과입니다. 소유자가 바뀌어서 장애가 났다는 문장은 원인 가설입니다. 파일 모드뿐 아니라 소유 그룹과 상위 디렉터리 탐색 권한도 확인해야 가설을 좁힐 수 있습니다. 관측과 가설을 두 칸에 나누면 추측이 후속 담당자에게 확정 사실처럼 전달되는 일을 줄일 수 있습니다.

권한 오류의 비교 대상

제공된 permission 사건은 error=EACCES이고 service_read=false입니다. 이 조합은 권한 경계를 우선 조사할 근거이지 곧바로 chmod 777을 실행할 근거가 아닙니다. 실제 VM에서는 bcweb의 소속과 파일·부모 경로의 권한을 확인하고 그 계정의 읽기를 검사합니다. 관리자 계정이 읽는 데 성공했다는 결과는 서비스 계정 읽기 성공과 다릅니다. 필요한 그룹과 읽기·탐색 권한만 복구하는 계획을 작성합니다.

이름 조회와 앱 응답을 분리합니다

name 사건에서는 resolve=NXDOMAIN인 동시에 direct_http=200입니다. 이름을 주소로 바꾸는 경계와 주소에 직접 요청하는 경계를 비교한 결과입니다. 이 실습의 직접 요청은 같은 앱을 가리킨다고 입력 계약에 가정합니다. 실제 HTTP 가상 호스트나 TLS에서는 IP 요청만으로 동일 대상을 확인하기 어려우므로 Host·인증서·포트도 대조합니다. 직접 요청 성공을 모든 이름 조회와 모든 사용자 경로의 정상으로 확대하지 않습니다.

inode 부족을 용량 부족과 구분합니다

inode 사건은 파일 생성의 ENOSPC, 양의 bytes_free, 0인 inodes_free를 함께 제공합니다. 바이트 공간만 남아 있어도 새 파일 메타데이터를 할당하지 못할 수 있습니다. 실제 VM에서는 생성 대상의 같은 파일시스템에 대해 바이트와 inode를 확인하고 마운트가 맞는지도 봅니다. 호스트 전체의 여유 공간이나 다른 볼륨의 inode 결과를 가져오면 근거가 어긋납니다. 작은 파일 누적 경로와 보존 정책을 조사한 뒤 정리 범위를 검토합니다.

빈 관측을 정상으로 바꾸지 않습니다

observed=false이면 나머지 필드가 그럴듯해도 UNKNOWN입니다. 조회 명령이 권한 부족으로 실패했는데 결과 숫자를 0으로 저장하면 inode 고갈처럼 보일 수 있습니다. 실제 수집기는 조회 성공 여부와 값, 실행 대상과 시각을 함께 전달해야 합니다. UNKNOWN은 아무 문제도 없다는 뜻이 아니라 지금 자료로 장애 종류를 확정할 수 없다는 뜻입니다. 다음 담당자에게 필요한 추가 조회를 구체적으로 남깁니다.

복합 상황에서는 판단을 보류합니다

바이트와 inode가 모두 0이면 이번 단일 원인 판정기는 INODE라고 확정하지 않습니다. 이름 조회가 실패하고 직접 HTTP도 503이면 이름 문제 외 앱 장애도 남아 있습니다. diagnose는 정해진 세 조합에만 분류를 반환하며 나머지는 UNKNOWN입니다. 분류기를 과도하게 확장해 가장 먼저 맞는 문자열 하나로 원인을 결정하지 않습니다. 실무에서는 여러 독립 장애가 동시에 있을 수 있으므로 각 경계의 실패를 따로 기록합니다.

변경 전에 보존할 최소 증거

사건 식별자, 관측 시각과 시간대, 대상 경로나 주소, 실행 계정, 명령의 종료 코드, 필요한 오류 문구를 남깁니다. 환경 변수 전체나 인증 키를 기록하지 않습니다. 현재 설정의 사본과 해시는 접근 통제된 위치에 보관하고 기존 변경 기록을 연결합니다. 로그를 정리하거나 파일을 삭제하는 조치는 보존 이후에 검토합니다. 기록은 다음 가설을 검증하는 데 필요한 만큼 좁혀 수집합니다.

가설마다 반증 가능한 조회를 고릅니다

권한 가설이면 해당 실행 계정 읽기와 부모 경로 탐색을 확인합니다. 이름 가설이면 실습 이름 조회와 동일 앱 직접 경로를 비교합니다. inode 가설이면 생성 대상 마운트의 inode와 바이트를 확인합니다. 어느 명령을 실행하면 좋겠다는 목록보다 어떤 결과가 나오면 가설을 유지하거나 버릴지 먼저 씁니다. 재기동처럼 여러 조건을 한꺼번에 바꾸는 조치보다 하나의 경계를 확인하는 조회가 설명하기 쉽습니다.

실패 알림과 원인 판정을 분리합니다

앞 모듈의 점검 스크립트가 비정상 종료를 알렸다고 해서 권한·이름·inode 중 어느 원인인지 자동으로 알 수 있는 것은 아닙니다. 알림의 대상과 점검 시점을 이번 관측과 연결합니다. 스크립트 자체 실행 실패와 서비스 실패도 구별합니다. 알림 파일이 오래된 상태라면 현재 실패 증거로 쓰지 않습니다. 실패 통지가 도착하는 경로와 서비스의 업무 상태는 각각 확인하는 책임이 있습니다.

진단 함수를 완성하는 순서

triage.py는 행 하나를 받아 고정 문자열을 반환합니다. 조회 성공을 먼저 검사한 뒤 권한, 이름, 저장 공간 조합을 읽습니다. starter는 inode 조합도 UNKNOWN으로 반환하므로 test_inode가 기대 INODE와 실제 UNKNOWN의 차이를 보여 줍니다. 해당 분기만 구현하고 모호한 상황을 UNKNOWN으로 두는 테스트를 유지합니다. 입력 자료를 바꾸거나 반환 문자열을 모든 사건에 똑같이 쓰면 다른 경계 사례가 실패합니다.

오류 메시지는 실패한 층을 보여 줍니다

JSONDecodeError가 나오면 진단 규칙 전에 입력 파일의 쉼표·따옴표·인코딩을 확인합니다. FileNotFoundError는 진단 대상 장애가 아니라 관측 파일 경로 문제일 수 있습니다. AssertionError는 어떤 입력 조합의 분류 계약이 깨졌는지 테스트 이름과 기대 값을 함께 읽습니다. UNKNOWN 출력은 실행 실패와 다르며 함수가 정상 실행되어 판단 보류를 반환한 결과입니다. 셸 종료 코드와 출력의 의미를 섞지 않습니다.

조치와 종료 기준을 미리 적습니다

원인이 좁혀졌다면 수정할 대상, 필요한 권한, 사전 사본, 조치 후 재조회, 중단 기준을 적습니다. 공유 경로를 정리하거나 이름 설정을 바꾸기 전에 다른 담당자의 소유 범위를 확인합니다. 복구 완료는 원인 분류 성공과 다릅니다. 다음 레슨에서는 사건 시점을 정리하고 이어서 업무 응답·데이터·권한·점검 경로를 재검증합니다. journalctl의 상세 필터 조합은 더 읽기로 연결하고 여기서는 관측 근거의 선택을 연습합니다.

따라하기

제공된 관측 판정

solution 폴더에서 합성 관측 네 건을 판정합니다. 실제 OS 조회 출력이 아닙니다.

python3 -B triage.py observations.json

실행 결과

permission PERMISSION
name NAME
inode INODE
missing UNKNOWN

관측 누락 구분

조회 성공 여부가 false인 입력은 자료가 있어도 판단 보류입니다.

row={"observed":False,"inodes_free":0}
print("UNKNOWN" if row["observed"] is not True else "INSPECT")

실행 결과

UNKNOWN

분류 TODO 완성

starter의 triage.py inode 분기를 구현하고 다섯 테스트를 통과합니다. test_ambiguous는 복합 상황 판단 보류를 확인합니다.

bash check.sh

확인 문제

실습

triage.py의 inode 판정을 완성합니다. 제공 합성 관측을 읽어 PERMISSION·NAME·INODE 또는 UNKNOWN을 반환합니다. 관측 실패와 복합 장애를 정상이나 단일 원인으로 바꾸지 않습니다. 테스트 입력은 호스트 실측이 아닙니다.

시작 코드·테스트 내려받기

실행 명령

bash check.sh

기대 결과

5 tests OK, 종료 0

모범 답안모범 답안 내려받기

더 읽기

면접 질문

  • 파일 권한 때문에 서비스가 실패하는 상황을 설명합니다.
  • 디스크 용량이 남았는데 파일 생성이 실패한 원인을 설명합니다.