셸 점검 스크립트
90분 안팎
학습 목표
절대 경로·인용·시간 제한·종료 코드를 적용해 서비스와 용량 상태를 수집합니다.
개념
자동 점검은 반복 가능한 관측에서 시작합니다
운영 담당자가 매번 터미널에서 상태를 확인하면 바쁜 시간대에 확인이 빠지고 사람마다 판단 기준도 달라집니다. 작은 운영 실습실에서는 웹 앱의 서비스 상태, HTTP 응답 코드, 데이터가 있는 파일시스템의 블록과 inode 사용률을 같은 순서로 수집합니다. 점검은 앱을 재시작하거나 저장 파일을 고치지 않습니다. 자동 복구보다 먼저 관측이 실패했는지 대상이 실패했는지를 구분하는 것이 목표입니다.
이 모듈의 실행 공간
앞 모듈의 bcops 작업 계정, bcweb 앱 계정, bcapp 그룹과 192.168.56.10 실습망을 이어 사용합니다. ZIP을 새 디렉터리에 풀어 그 안에서 명령을 실행합니다. Python 3와 bash가 필요하며 로컬 검사는 명령과 전송 대역을 주입해 맥에서도 실행합니다. 실제 systemctl과 Linux df, HTTP 수신 및 timer 확인은 준비된 Linux VM에서 진행합니다. external 표시는 그 검증이 남았다는 뜻입니다. starter의 실패를 구현하고 solution과 비교하며 실제 VM 관측과 fixture 결과를 나누어 제출합니다.
셸은 실행 경계를 정합니다
collect.sh는 자신의 위치로 이동하고 Python 관측기를 실행하는 얇은 진입점입니다. dirname으로 구한 경로와 실행 파일 이름을 큰따옴표로 감싸 공백이 있어도 하나의 인자가 되게 합니다. exec는 셸을 관측기로 바꾸므로 종료 코드가 바로 호출자에게 전달됩니다. 비어 있는 PATH나 다른 작업 디렉터리에서 우연히 다른 파일을 실행하지 않도록 VM 서비스에는 절대 Python 경로와 작업 경로를 선언합니다.
경로와 인자의 역할을 나눕니다
Python 관측기는 systemctl, curl, df의 위치를 고정된 /usr/bin:/bin에서 찾고 절대 경로인지 검사합니다. 명령을 긴 문자열로 만들지 않고 인자 배열로 전달하므로 데이터 경로는 한 인자로 유지됩니다. shell=True를 사용하지 않아 URL이나 경로가 셸 연산자로 해석되지 않습니다. 이는 모든 외부 입력을 안전하게 만든다는 뜻이 아니며 대상 URL·유닛·데이터 경로도 코드에 정한 실습 범위로 제한합니다.
실행 계정은 관측 권한만 가집니다
bcops는 서비스 상태를 조회하고 데이터 경로의 파일시스템 정보를 읽으며 자기 evidence 경로에 기록합니다. 앱 데이터의 읽기·쓰기를 모두 허용할 필요는 없습니다. df는 조회할 경로와 그 부모에 필요한 접근 조건이 있어야 합니다. root로 테스트한 성공을 bcops의 성공으로 제출하지 않습니다. Permission denied가 보이면 명령 실행 파일, 부모 경로 탐색 권한, 결과 기록 위치를 나누어 확인합니다.
서비스 inactive도 수집한 값입니다
systemctl is-active의 stdout에는 active, inactive 또는 failed가 나올 수 있습니다. active의 종료 0과 inactive 또는 failed의 비정상 종료를 함께 확인합니다. inactive를 JSON에서 정상 서비스로 바꾸지 않지만 관측 실패로 취급하지도 않습니다. unknown, 잘못된 출력 또는 명령 실행 오류는 관측할 수 없었던 상태입니다. 관측기는 service=unknown과 errors를 남겨 다음 판정 단계가 정상이라고 오해하지 않게 합니다.
HTTP 수신과 업무 성공을 구별합니다
curl은 HTTP 500 응답을 받는 데 성공하면 종료 코드 0일 수 있습니다. 따라서 -w로 받은 응답 코드를 별도 http 값에 저장하고 판정 단계가 200인지 비교합니다. 본문은 /dev/null로 버려 업무 데이터나 오류 본문이 로그로 새지 않게 합니다. -sS는 진행률을 줄이되 명령의 오류를 감추지 않는 옵션입니다. 관측기는 원문 stderr를 기록하지 않고 HTTP나 TIMEOUT 같은 고정 코드로 바꿉니다.
연결과 전체 요청에 상한을 둡니다
curl에는 연결 대기 1초와 전체 요청 2초를 지정하고 --noproxy로 실습 대상에 직접 요청합니다. 종료 28은 시간 상한 관련 실패로 기록하며 000을 유효 HTTP 응답으로 읽지 않습니다. Python 명령 호출에는 별도의 4초 상한이 있습니다. 상한이 없으면 정기 점검이 계속 대기하고 다음 점검이 잠금 때문에 생략될 수 있습니다. 시간 초과는 대상의 확정 장애가 아니라 이번 시도에서 관측을 완료하지 못한 결과입니다.
출력 형식도 실행 환경입니다
LC_ALL=C로 명령 출력 환경을 고정하고 Linux df -P의 두 줄 출력에서 다섯 번째 사용률 필드를 읽습니다. inode에는 df -Pi를 사용합니다. 공백으로 나눈 숫자에서 퍼센트 표시를 제거한 뒤 0부터 100 사이인지 확인합니다. 헤더만 있거나 필드가 깨졌을 때 사용률 0으로 성공 처리하지 않습니다. 맥의 df 옵션은 다를 수 있으므로 대역 출력으로 파서를 검증하고 실제 명령은 Linux VM에서 관측합니다.
모르는 값에 0을 쓰는 이유를 읽습니다
관측기의 http·blocks·inodes 초기값은 0이지만 이것이 정상 판정이라는 뜻은 아닙니다. 해당 관측에 실패하면 errors가 함께 채워지고 판정기는 errors가 있는 입력을 UNKNOWN으로 처리합니다. 오류 배열을 버리고 숫자만 저장하면 손상 출력이 디스크 여유로 보입니다. 관측 JSON 전체를 하나의 계약으로 전달하고 표준 출력에는 JSON 한 개만 남겨 로그 문장이 파서 입력에 섞이지 않게 합니다.
명령 실패를 셸이 덮어쓰지 않게 합니다
set -eu만으로 모든 실패 계약이 자동 완성되지는 않습니다. 실패할 수 있는 점검은 조건문 안에서 호출하고 else의 첫 줄에서 $?를 변수에 담습니다. 그 뒤 echo나 cat을 실행하고 $?를 읽으면 마지막 출력 명령의 결과를 얻습니다. true를 붙여 실패를 없애면 예약 실행기가 장애를 알 수 없습니다. 따라하기는 작은 실패 명령으로 이 차이를 재현하고 실제 점검에는 기록한 원래 종료 코드를 반환합니다.
테스트 실패 이름을 수정 위치로 연결합니다
starter의 percentage는 101%도 받도록 경계 검사가 빠져 있습니다. test_percentage_boundaries의 ValueError not raised는 예외가 발생해야 하는 입력을 승인했다는 뜻입니다. 숫자 변환 성공만 확인하지 말고 유효 범위를 추가합니다. 다른 테스트는 inactive·HTTP 500의 의미, curl 28, 손상 df, 절대 경로와 비밀 제외를 확인합니다. TimeoutExpired는 대역으로 주입하므로 검증 중 실제 프로세스를 강제 종료하지 않습니다.
관측을 완료한 뒤 넘길 자료
제출할 자료에는 대상 유닛·URL·데이터 경로, 실행 계정, 정상과 관측 실패 JSON, 명령 종료 코드가 들어갑니다. demo.py collect는 고정 출력 대역을 파싱한 결과이며 VM 상태를 측정한 기록이 아닙니다. 실제 collect.sh 출력은 그 시각의 관측으로 따로 보관합니다. curl 옵션의 더 넓은 사용법은 서재로 보내고 이 레슨에서는 서비스와 HTTP 및 저장 사용률을 동일한 계약으로 수집하는 데 집중합니다.
요청 제한과 응답 코드 옵션은 curl 공식 설명, 명령 실행과 timeout 처리는 Python subprocess 문서에서 확인할 수 있습니다.
따라하기
실패 코드를 바로 보관
아래 명령은 의도적으로 종료 7을 반환하는 작은 셸 예제입니다.
if bash -c "exit 7"; then
printf "OK\n"
else
rc=$?
printf "CHECK_EXIT=%s\n" "$rc"
fi실행 결과
CHECK_EXIT=7
관측 계약을 고정 입력으로 확인
solution ZIP에서 명령 대역을 파싱합니다. 실제 VM 상태가 아닙니다.
python3 -B demo.py collect실행 결과
{"blocks":79,"errors":[],"http":200,"inodes":79,"service":"active"}
파서 경계 완성
starter의 percentage 범위 검사를 구현하고 여섯 관측 검사를 통과시킵니다. unittest 결과는 stderr에서 확인합니다.
bash check.shLinux VM에서 현재 관측
README의 주소·계정·도구를 확인한 VM에서 실행합니다. JSON errors와 종료 코드, 실제 시각을 보관합니다. 맥에서는 실행하지 않은 단계입니다.
bash collect.sh
rc=$?
printf "COLLECT_EXIT=%s\n" "$rc"확인 문제
실습
collect.py percentage의 누락된 0~100 검사를 구현합니다. bash check.sh는 절대 경로·인자·HTTP 500·시간 초과·손상 출력·경계와 비밀 제외를 검사합니다. 실제 관측은 README의 Linux VM 절차로 별도 제출합니다.
실행 명령
bash check.sh
기대 결과
6 tests, OK, 종료 0
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- 점검 스크립트가 실패를 알리는 방식을 설명합니다.