워치독은 살아 있었지만 복구할 대상이 사라졌다
금요일 밤, 다섯 대 중 한 대의 텔레그램 봇이 조용해졌다. 워치독은 살아 있었다. 2분마다 상태를 확인했고, 실패 코드도 꼬박꼬박 남겼다. 그런데 봇은 돌아오지 않았다. 나중에 보니 프로세스가 죽은 것보다 더 아래층의 문제가 생겨 있었다. 워치독이 재시작해야 할 서비스 등록 파일 자체가 사라져 있었다.
7초 사이에 사라진 바닥
시스템 기록을 시간순으로 놓고 보니 장면은 선명했다.
밤 10시 35분 43초까지 브릿지는 정상 로그를 남겼다. 7초 뒤 서비스가 정지됐다. 보통이라면 여기까지는 흔한 장애다. 프로세스가 비정상 종료됐거나, 설치 과정에서 잠깐 내려갔을 수 있다. 워치독이 다시 올리면 된다.
그런데 이번에는 서비스 등록 파일도 함께 없어졌다.
리눅스에서 서비스 프로세스를 다시 시작하려면 “이 프로그램을 어떤 명령으로, 어떤 환경변수로, 어느 사용자 권한에서 띄울지” 적힌 유닛 파일이 필요하다. 프로세스는 배우이고, 유닛 파일은 무대 지시서에 가깝다. 배우가 쓰러지면 지시서를 보고 다시 올릴 수 있다. 지시서까지 사라지면 감독이 살아 있어도 공연을 재개할 수 없다.
워치독은 2분마다 재시작 명령을 보냈다. 운영체제는 매번 “그런 서비스가 없다”고 답했다. 워치독은 실패를 감지했지만, 사라진 정의를 복원할 재료는 갖고 있지 않았다. 실패 코드는 계속 쌓였고 봇은 17분 동안 내려가 있었다. 그 사이 들어온 질문 하나는 큐에서 천 초 넘게 기다렸다.
감시 장치가 죽은 게 아니었다. 감시 장치가 할 수 있는 일의 범위 밖에서 바닥이 빠진 것이었다.
재시작과 재설치는 다른 일이다
운영 자동화를 만들 때 나는 자주 복구를 한 단어로 뭉뚱그렸다.
“죽으면 살린다.”
하지만 실제 복구에는 층이 있다.
- 프로세스만 죽었으면 재시작하면 된다.
- 설정이 깨졌으면 정본 설정을 다시 배치해야 한다.
- 서비스 등록이 사라졌으면 재설치해야 한다.
- 실행 파일이나 의존성이 사라졌으면 설치부터 다시 해야 한다.
- 자격증명이 만료됐으면 사람의 승인이 필요할 수 있다.
재시작은 가장 얕은 복구다. 프로세스보다 아래층이 멀쩡하다는 가정 위에서만 작동한다. 이번 워치독에는 “프로세스가 내려갔다”와 “서비스 정의가 없다”가 같은 재시작 실패로 보였지만, 필요한 행동은 완전히 달랐다.
좋은 감시 장치는 상태를 단순히 정상과 비정상으로 나누지 않는다. 무엇이 사라졌는지를 구분한다. 프로세스가 없는지, 등록 파일이 없는지, 실행 명령이 없는지, 설정을 읽지 못하는지. 진단이 달라야 복구도 달라진다.
이웃 기계의 정본이 살렸다
당시 복구는 의외로 단순했다. 같은 역할을 하는 이웃 노드에 정상 유닛 파일이 있었다. 그 파일을 가져와 노드 이름만 맞게 바꾸고, 서비스 관리자에게 다시 읽힌 뒤 시작했다. 봇은 곧 살아났고, 워치독도 정상 상태로 돌아왔다. 큐에 갇혀 있던 질문도 배출됐다.
17분 안에 끝낼 수 있었던 이유는 복구 명령이 영리해서가 아니었다. 비교할 수 있는 정본이 다른 곳에 있었기 때문이다.
이 경험 뒤에는 유닛 파일을 어느 기계의 수동 설정으로만 두지 않고 저장소의 템플릿으로 만들었다. 노드마다 달라지는 값은 별도 변수로 분리했다. 워치독도 유닛 부재를 평범한 재시작 실패로 뭉개지 않고, “서비스 정의가 사라졌다”고 구체적으로 알려주도록 고쳤다.
복구 능력은 명령의 개수보다 정본의 위치에서 나온다. 다시 만들 수 있는 재료가 저장소에 있으면 재설치가 가능하다. 한 기계 안에만 있던 수동 설정이면, 그 기계에서 사라지는 순간 기억까지 함께 사라진다.
배운 것
감시 장치는 자신이 감시하는 대상보다 한 층 아래의 가정을 먹고 산다. 프로세스 워치독은 서비스 정의가 있다는 가정, 서비스 워치독은 실행 파일과 설정이 있다는 가정, 배포 감시는 배포할 정본이 있다는 가정 위에 서 있다.
그 바닥이 사라지면 “다시 시작”은 답이 아니다.
그래서 복구 설계에는 세 가지가 같이 있어야 한다. 어떤 층이 깨졌는지 구분하는 진단, 다시 만들 수 있는 정본, 자동 복구 범위를 벗어났을 때 사람에게 정확히 넘기는 경보. 하나라도 없으면 워치독은 살아 있으면서도 아무것도 살리지 못한다.
그날 밤 봇을 살린 건 2분 타이머가 아니었다. 다른 기계에 남아 있던 정본과, 재시작이 아니라 재설치가 필요하다는 구분이었다.
복구 명령보다 먼저 준비해야 할 것은, 사라진 것을 다시 만들 수 있는 정본이다.
— 강대종 / @ssamssae