자동 업로드가 안 되는 것 같다는 신고를 받고 들여다봤습니다. 겉으로 보이는 것은 전부 정상이었습니다.
- 예약 작업은 시간에 맞춰 실행되고 있었습니다
- 컨테이너는 전부
Up상태였습니다 df -h에 외장 디스크 4.6T가 정상 용량으로 잡혔습니다
그런데 산출물이 이틀째 하나도 없었습니다.
죽은 마운트
커널 로그가 답을 갖고 있었습니다.
usb 4-1: USB disconnect, device number 2
EXT4-fs (sdb1): I/O error while writing superblock
Aborting journal on device sdb1-8.
usb 4-1: new SuperSpeed USB device number 3
USB 외장 디스크가 순간 끊겼다가 즉시 다시 붙었습니다. 커널은 옛 장치 노드를 오프라인 처리하고 새 노드로 재등록했는데, 마운트 지점은 여전히 죽은 옛 노드를 가리키고 있었습니다.
결과는 껍데기 마운트입니다. df는 마운트 테이블을 읽으니 멀쩡한 용량을 보여 주고, 실제로 그 경로에 접근하면 전부 I/O 에러가 납니다. 상태를 묻는 명령과 실제로 써 보는 것이 다른 답을 냅니다.
여기 얹혀 있던 작업 10개가 한꺼번에 죽었습니다. 특히 취약했던 하나는 설정 모듈이 import 시점에 출력 디렉터리를 만들고 있어서, 스크립트 첫 줄에서 크래시했습니다. 무엇을 만들지 정하기도 전에 죽은 겁니다.
왜 이틀이나 몰랐나
실패 알림이 없었기 때문입니다. 그런데 더 정확히 말하면, 애초에 실패를 세는 장치가 없었습니다.
이런 배치를 만들 때 흔히 성공 경로만 생각합니다. 로그는 쌓이고 있었고 트레이스백도 남아 있었지만, 로그는 누가 읽어야 정보가 됩니다. 매일 아침 로그를 열어 보는 사람은 없습니다.
그래서 감시 기준을 바꿨습니다. 작업이 성공했는지가 아니라, 산출물이 실제로 생겼는지를 봅니다.
- 기대한 시간대에 결과물이 0건이면 알린다
- 연속 실패가 임계치를 넘으면 알린다
- 알림이 안 오는 것이 정상임을 증명하기 위해, 주기적으로 감시 장치 자체가 살아 있다는 신호를 보낸다
마지막 항목이 중요합니다. "알림이 안 온다"는 두 가지를 뜻합니다. 다 잘 돌고 있거나, 감시기가 죽었거나. 둘을 구분할 수 없으면 감시기는 없는 것과 같습니다.
가져갈 것
- 상태 조회와 실제 동작은 다릅니다. 디스크가 살아 있는지 알고 싶으면 용량을 묻지 말고 파일을 하나 써 보는 게 확실합니다.
- 초록불은 아무것도 보장하지 않습니다. 프로세스가 떠 있는 것과 일을 하고 있는 것은 별개입니다.
- 성공이 아니라 산출물을 셉니다. "돌았다"가 아니라 "몇 개 만들어졌다"가 지표입니다.
- 하드웨어는 끊겼다 다시 붙습니다. 재부팅 없이 마운트만 다시 붙이는 절차를 미리 적어 두면 다음엔 몇 분입니다.