ML 도 DL 도 놓친 장애 — 르무엘 CPU 가 60% 에서 100% 로 가는 동안 이상 탐지기는 조용했다
홈랩 서버 6대의 모니터링 로그로 이상 탐지 모델 두 개를 학습시켰다. 머신러닝 쪽은 Isolation Forest, 딥러닝 쪽은 LSTM 오토인코더(LSTM-AE)다. 가짜 장애를 심어서 평가하니 LSTM-AE 가 92% 를 잡았다.
그런데 같은 기간, K3s 마스터 노드 르무엘의 CPU 는 60% 대에서 100% 까지 올라가 붙어 버렸고, 두 모델은 이걸 거의 이상으로 보지 않았다. 이 글은 그 한 장짜리 그림을 풀어서 설명한다.

결론부터 적으면 이렇다.
- 두 모델 모두 “지난 1시간이 평소와 다르게 생겼나” 만 본다. 며칠에 걸쳐 서서히 오른 뒤 100% 에 평평하게 붙은 상태는 1시간 창 안에서는 이상하게 보이지 않는다.
- 느린 악화는 다른 종류의 탐지기가 필요하다. 일 단위 기준선 비교와 기울기 탐지를 붙이자 9월 25일 22시에 처음 잡혔다. 오르기 시작한 지 이틀 넘게 지난 뒤다.
- 그 탐지기도 기준선이 따라 올라가면 다시 조용해진다. 오래 가는 문제는 결국 “일 평균 CPU 90% 이상” 같은 단순한 고정 규칙이 잡는다.
1. 데이터와 두 모델
- 데이터: 서버 모니터링 크론이 5분마다 남기는 로그. CPU %, iowait %, 코어당 load, 메모리 %, 디스크 % 다섯 지표. 기간은 2026-07-29 ~ 09-27 이고, 9월 9일까지를 학습, 9월 10일부터를 테스트로 썼다. 학습 창은 약 7만 2천 개(71,861개)다.
- Isolation Forest (ML): 서버별로 1시간 창의 요약 통계 20개를 특징으로 넣는다. 트리 200개. 학습 4초.
- LSTM-AE (DL): 서버 공통으로 1시간(12스텝) × 지표 5개를 인코더 LSTM 으로 압축했다가 디코더 LSTM 으로 복원한다. 복원이 안 될수록 이상하다. 학습 47초(CPU).
- 임계값: 학습 구간에서 “서버당 하루 2건만 넘도록” 퍼센타일로 맞췄다.
2. 그림 읽는 법 — 세 칸
맨 위: CPU 사용률. 회색은 1시간 평균, 빨간 선은 일 평균이다. 점선 오른쪽(9월 10일~)이 테스트 구간이다. 8월 내내 일 평균은 60~70% 사이를 오간다. 9월 중순에 70% 대로 올라서고, 9월 22일 무렵부터 가파르게 올라 9월 24일 이후 95~100% 에 붙는다. 회색 선이 100% 근처에서 거의 평평해진 게 보인다.
가운데: CPU 95% 이상인 시간의 비율(일 단위). 8월에는 5% 안팎, 즉 하루에 한 시간 남짓만 95% 를 넘었다. 9월 말에는 이 값이 100% 가 된다. 하루 24시간 내내 95% 이상이라는 뜻이다. 사람이 보면 이 칸이 가장 명확한 경보다.
맨 아래: 두 모델의 이상 점수 ÷ 임계값. 빨간 가로선 1 을 넘으면 경보다. 테스트 구간에만 그렸다.
- 파란 선(Isolation Forest)은 0.7~0.9 사이에서 거의 평평하다. CPU 가 100% 에 붙은 9월 말에도 1 을 넘지 않는다.
- 주황 선(LSTM-AE, 보기 좋게 5 에서 잘랐다)은 가끔 뾰족하게 튀는데, 튀는 시점이 과부하가 시작된 시점과 맞지 않는다. 9월 24일 이후, CPU 가 가장 높은 구간에서 오히려 점수가 0.5 아래로 내려간다.
즉 서버가 가장 나빠진 순간에 두 모델 모두 가장 조용했다.
3. 왜 놓쳤나
두 모델은 “평소와 모양이 다른 1시간”을 찾도록 만들었다. 짧은 급등, 메모리 계단, iowait 폭증 같은 모양의 이상에는 강하다. 실제로 가짜 장애를 심어서 평가했을 때 결과가 이랬다.
| 모델 | 탐지율 | 짧은 CPU 급등 | 메모리 계단 |
|---|---|---|---|
| Isolation Forest | 53% | 39% | 42% |
| LSTM-AE | 92% | 92% | 94% |
(테스트 구간에 6종류 가짜 이상을 서버당 12건씩, 3회 반복해서 심었다.)
하지만 르무엘의 과부하는 수준의 이상이다. 1시간 안에서는 “CPU 가 높고 평평하다”는 모양밖에 안 보이고, 오르는 과정은 며칠에 걸쳐 있어서 1시간 창에 담기지 않는다. 오토인코더 입장에서는 평평한 신호가 오히려 복원하기 쉽다. 가장 나쁜 상태가 가장 예측하기 쉬운 상태가 된 것이다. 그래서 점수가 내려갔다.
하나 더 있다. 학습 구간(8월~9월 9일)의 르무엘 평균 CPU 는 65%, 테스트 구간은 76% 였다. 분포가 이미 옮겨 가고 있었는데 임계값은 학습 구간 기준이다. 이 때문에 테스트 구간 경보 수가 서버·일당 13~27건으로, 목표치 2건보다 훨씬 많이 나왔다. 경보는 많은데 정작 큰 장애는 못 잡는, 가장 나쁜 조합이다.
4. 느린 악화용 탐지기를 따로 붙였다
1시간 창 모델을 고치는 대신, 다른 시간 단위를 보는 통계 탐지기 두 개를 붙였다.
- 기준선 비교: 최근 24시간 평균을 “1일 전~15일 전 24시간 평균들”의 중앙값·MAD 와 비교한다. z > 3 이 6시간 계속되면 경보(증가 방향만).
- 꾸준한 기울기: 최근 72시간 선형 회귀로 메모리 +6%p, 디스크 +4%p 이상 꾸준히(R² ≥ 0.6) 오르면 경보. 메모리 누수·디스크 차오름용이다.
가짜 드리프트(서버 6대 × 4회)로 평가한 결과:
| 설정 | 르무엘 첫 경보 | CPU +25%p/3일 | CPU +10%p/3일 | 메모리 +15%p/5일 | 디스크 +8%p/4일 |
|---|---|---|---|---|---|
| z>4 | 못 잡음 | 88% | 12% | 25% | 75% |
| z>3 + 기울기 (채택) | 09-25 22시 | 96% | 67% | 96% | 92% |
르무엘은 9월 25일 22시에 처음 잡힌다. 24시간 평균 CPU 가 이미 96% 안팎이던 때라, 오르기 시작한 9월 23일보다 이틀 이상 늦다. 느린 추세 탐지기의 탐지 지연은 가짜 데이터에서도 43~82시간이었다.
5. 그리고 그 탐지기도 곧 조용해졌다
르무엘 경보는 9월 25일 22시, 9월 26일 6~13시에 울리고 그 뒤로 멈췄다. CPU 는 여전히 100% 였다.
이유는 기준선이다. 높은 상태가 며칠 계속되면 그 값이 “지난 15일”에 섞여 들어가고, 기준선이 따라 올라간다. 그러면 100% 도 “평소”가 된다. 통계 탐지기는 변화를 잡지 상태를 잡지 않는다.
그래서 최종 구성은 세 겹이 됐다.
| 무엇을 잡나 | 탐지기 | 시간 단위 |
|---|---|---|
| 갑작스러운 모양 변화 (급등, 계단, iowait 폭증) | LSTM-AE / Isolation Forest | 1시간 |
| 며칠에 걸친 악화 (과부하 진행, 누수, 디스크) | 기준선 z-score + 기울기 | 1~15일 |
| 오래 지속되는 나쁜 상태 | 고정 규칙 (예: 일 평균 CPU 90% 이상) | 하루 |
가장 단순한 세 번째 줄이, 이 그림의 가운데 칸을 보고 사람이 바로 떠올리는 규칙이다. 딥러닝 모델을 만들고 나서야 그 규칙이 왜 필요한지 확인한 셈이다.
6. 실제 데이터에서 두 모델이 잘 잡은 것
공정하게 적자면, 모양의 이상에서는 두 모델이 제 몫을 했다.
- 둘 다 가장 이상하다고 본 시점은 이사갈 노드 2026-09-12 11:15~12:30 이다. iowait 최대 83%, 메모리 94%. 두 모델이 독립적으로 같은 구간을 골랐다.
- LSTM-AE 만 강하게 반응한 것: 루이스 노드 2026-09-19 13:10, 평소 3~4% 이던 CPU 가 55%.
한계
- 가짜 이상은 내가 설계한 패턴이다. LSTM-AE 의 우세는 “이 패턴들에서”의 결과이고, 실제 장애 분포와 다를 수 있다.
- 실제 데이터에는 장애 라벨이 없어서 정성 평가만 했다.
- 기울기 경보 중에는 리눅스 페이지 캐시처럼 정상적으로 메모리가 차오르는 경우가 섞였을 수 있다. 로그의 메모리 값이 캐시를 포함하는지 아직 확인하지 않았다.
- 르무엘 CPU 가 왜 100% 가 됐는지는 이 글의 범위가 아니다. 여기서는 탐지가 됐는가만 다뤘다.
References
- F. T. Liu, K. M. Ting, Z.-H. Zhou, “Isolation Forest”, ICDM 2008. https://doi.org/10.1109/ICDM.2008.17
- P. Malhotra et al., “LSTM-based Encoder-Decoder for Multi-sensor Anomaly Detection”, ICML 2016 Anomaly Detection Workshop, arXiv:1607.00148. https://arxiv.org/abs/1607.00148
- scikit-learn,
IsolationForest문서. https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html - 실험 코드·결과: 로컬 프로젝트
server-anomaly(src/detect.py,src/trend.py,results/summary.json,results/trend_summary.json)