Skip to content
Published on

AIOps 기반 이상 탐지 자동화: ML 알림과 Kubernetes 이벤트 상관 분석 가이드

Authors
  • Name
    Twitter
AIOps Anomaly Detection

들어가며: 임계값 알림의 한계

새벽 4시, Slack에 알림이 쏟아진다. CPU 사용률이 80%를 넘었다는 경고 50건, 메모리 사용률 경고 30건, 디스크 I/O 경고 20건. 하지만 실제로 장애가 발생한 서비스는 단 하나뿐이다. 나머지 99건은 배포 직후의 일시적 스파이크이거나, 야간 배치 작업으로 인한 정상적인 리소스 증가였다. 이것이 정적 임계값(Static Threshold) 기반 알림의 현실이다.

전통적인 모니터링 시스템은 "CPU > 80%이면 알림", "응답 시간 > 500ms이면 경고"처럼 고정된 임계값에 의존한다. 이 방식은 단순하고 이해하기 쉽지만, 현대의 복잡한 분산 시스템에서는 치명적인 한계를 드러낸다.

계절성(Seasonality)을 반영하지 못한다. 이커머스 서비스의 트래픽은 점심시간과 퇴근 후에 급증하고, 새벽에는 급감한다. 월말에는 결제 트래픽이 폭증하고, 프로모션 기간에는 평소의 10배가 넘는 요청이 들어온다. 고정 임계값은 이런 자연스러운 패턴 변화를 이상으로 오탐(False Positive)한다.

Slow Burn 장애를 놓친다. 메모리 릭처럼 서서히 진행되는 문제는 임계값에 도달하기 전까지 감지되지 않는다. 매일 0.1%씩 증가하는 메모리 사용률은 80% 임계값에 도달하는 데 수개월이 걸리지만, 실제 장애는 그보다 훨씬 이전에 예방해야 한다.

상관관계를 파악하지 못한다. Pod 재시작, 노드 메모리 압박, 네트워크 지연 증가가 동시에 발생했다면, 이 세 가지가 하나의 근본 원인(Root Cause)에서 비롯된 것인지 각각 독립적인 문제인지 판단할 수 없다. 결과적으로 온콜 엔지니어는 수십 개의 알림을 하나하나 확인하며 근본 원인을 추적해야 한다.

AIOps(Artificial Intelligence for IT Operations)는 머신러닝을 활용하여 이러한 한계를 구조적으로 해결한다. 시계열 데이터의 정상 패턴을 학습하고, 패턴에서 벗어나는 이상을 자동으로 감지하며, 여러 이벤트를 상관 분석하여 근본 원인을 추론한다.

AIOps 개념과 성숙도 모델

AIOps는 Gartner가 2017년에 처음 정의한 개념으로, IT 운영에 인공지능과 머신러닝을 적용하여 모니터링, 이벤트 상관 분석, 자동 대응을 수행하는 것을 의미한다. 2026년 현재, AIOps는 단순한 알림 자동화를 넘어 자율 운영(Autonomous Operations)을 향해 진화하고 있다.

AIOps 성숙도는 다음 5단계로 나뉜다.

단계수준설명대표 기술
Level 0수동 모니터링고정 임계값, 수동 알림 확인Nagios, Zabbix
Level 1규칙 기반 자동화정적 규칙에 따른 알림 라우팅Prometheus Alertmanager
Level 2ML 기반 이상 탐지동적 베이스라인, 이상 탐지Datadog AIOps, Dynatrace Davis
Level 3상관 분석/근본 원인이벤트 클러스터링, RCA 자동화Moogsoft, BigPanda
Level 4자율 치유자동 스케일링, 자동 롤백Robusta + 자동 Playbook

대부분의 조직은 Level 1에 머물러 있으며, Level 2로의 전환이 가장 높은 ROI를 제공한다. 이 글에서는 Level 2~3 수준의 ML 기반 이상 탐지와 이벤트 상관 분석 구현에 집중한다.

ML 기반 이상 탐지 알고리즘 비교

이상 탐지에 활용되는 주요 ML 알고리즘은 각각의 강점과 한계가 뚜렷하다. 운영 환경의 데이터 특성에 따라 적합한 알고리즘을 선택해야 한다.

알고리즘 비교표

알고리즘유형강점약점적합 사례
Isolation Forest비지도/트리 기반고차원 데이터, 빠른 학습시계열 패턴 미반영CPU/메모리 다차원 메트릭
Prophet시계열 예측계절성/트렌드 자동 분해학습 데이터 최소 2주 필요트래픽, 응답 시간
DBSCAN밀도 기반 클러스터링임의 형태 클러스터 감지파라미터 민감도 높음로그 패턴 그룹핑
LSTM딥러닝/RNN복잡한 시계열 패턴 학습GPU 필요, 학습 시간 긺다변량 시계열
One-Class SVM비지도/커널비선형 경계 모델링대규모 데이터에 느림소규모 고품질 메트릭

Isolation Forest: 다차원 메트릭 이상 탐지

Isolation Forest는 정상 데이터보다 이상 데이터가 더 쉽게 "고립(isolate)"된다는 직관에 기반한다. 랜덤 트리를 구성할 때 이상 데이터는 루트에 가까운 깊이에서 분리되고, 정상 데이터는 더 깊은 곳에서 분리된다.

import numpy as np
import pandas as pd
from sklearn.ensemble import IsolationForest
from prometheus_api_client import PrometheusConnect

# Prometheus에서 메트릭 수집
prom = PrometheusConnect(url="http://prometheus:9090", disable_ssl=True)

# 최근 24시간 CPU, 메모리, 네트워크 메트릭 수집
metrics = {}
for metric_name in ['node_cpu_seconds_total', 'node_memory_MemAvailable_bytes', 'node_network_receive_bytes_total']:
    result = prom.custom_query_range(
        query=f'rate({metric_name}[5m])',
        start_time=pd.Timestamp.now() - pd.Timedelta(hours=24),
        end_time=pd.Timestamp.now(),
        step='60s'
    )
    metrics[metric_name] = [float(v[1]) for v in result[0]['values']]

# 다차원 feature 행렬 구성
df = pd.DataFrame(metrics)
df = df.dropna()

# Isolation Forest 학습 및 예측
model = IsolationForest(
    n_estimators=200,         # 트리 개수 (기본 100, 정밀도 향상을 위해 200)
    contamination=0.01,       # 이상치 비율 예상 (1%)
    max_samples='auto',
    random_state=42
)
model.fit(df)

# 예측: -1이면 이상, 1이면 정상
predictions = model.predict(df)
anomaly_scores = model.decision_function(df)

# 이상 탐지 결과 출력
anomalies = df[predictions == -1]
print(f"총 {len(df)}개 샘플 중 {len(anomalies)}개 이상 탐지")
print(f"이상 점수 범위: {anomaly_scores.min():.4f} ~ {anomaly_scores.max():.4f}")

# 이상 탐지 결과를 Prometheus Pushgateway로 전송
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway

registry = CollectorRegistry()
anomaly_gauge = Gauge('aiops_anomaly_score', 'Anomaly score from Isolation Forest',
                      ['metric_group'], registry=registry)
anomaly_gauge.labels(metric_group='node_resources').set(anomaly_scores[-1])
push_to_gateway('pushgateway:9091', job='aiops_anomaly_detection', registry=registry)

이 코드에서 contamination 파라미터는 전체 데이터에서 이상치가 차지하는 비율을 지정한다. 프로덕션 환경에서는 일반적으로 0.5%~2% 사이의 값을 설정한다. 너무 높으면 오탐이 증가하고, 너무 낮으면 실제 이상을 놓칠 수 있다. 운영 초기에는 0.01(1%)로 시작하여 알림 품질을 관찰하며 점진적으로 조정하는 것이 좋다.

Prophet: 시계열 이상 탐지

Facebook(현 Meta)이 개발한 Prophet은 시계열 데이터의 트렌드, 계절성, 휴일 효과를 자동으로 분해하여 예측 모델을 생성한다. 실측값이 예측 구간을 벗어나면 이상으로 판단한다.

from prophet import Prophet
import pandas as pd
from prometheus_api_client import PrometheusConnect

# Prometheus에서 최근 14일 HTTP 요청 수 수집
prom = PrometheusConnect(url="http://prometheus:9090", disable_ssl=True)
result = prom.custom_query_range(
    query='sum(rate(http_requests_total[5m]))',
    start_time=pd.Timestamp.now() - pd.Timedelta(days=14),
    end_time=pd.Timestamp.now(),
    step='300s'
)

# Prophet 입력 형식으로 변환 (ds, y 컬럼 필수)
df = pd.DataFrame({
    'ds': [pd.Timestamp(v[0], unit='s') for v in result[0]['values']],
    'y': [float(v[1]) for v in result[0]['values']]
})

# Prophet 모델 학습
model = Prophet(
    changepoint_prior_scale=0.05,    # 트렌드 변화 민감도 (낮을수록 보수적)
    seasonality_prior_scale=10.0,    # 계절성 강도
    interval_width=0.99,             # 예측 구간 너비 (99% 신뢰 구간)
    daily_seasonality=True,
    weekly_seasonality=True,
)

# 한국 공휴일 추가 (트래픽 패턴 변화 반영)
model.add_country_holidays(country_name='KR')
model.fit(df)

# 동일 기간 예측 수행
forecast = model.predict(df)

# 이상 탐지: 실측값이 예측 구간(yhat_lower, yhat_upper)을 벗어나면 이상
df_merged = df.merge(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']], on='ds')
df_merged['is_anomaly'] = (
    (df_merged['y'] < df_merged['yhat_lower']) |
    (df_merged['y'] > df_merged['yhat_upper'])
)

anomalies = df_merged[df_merged['is_anomaly']]
print(f"Prophet 이상 탐지 결과: {len(anomalies)}건의 이상 감지")

# 이상 발생 시 상세 정보 출력
for _, row in anomalies.iterrows():
    deviation = abs(row['y'] - row['yhat']) / row['yhat'] * 100
    direction = "급증" if row['y'] > row['yhat_upper'] else "급감"
    print(f"  [{row['ds']}] 트래픽 {direction}: "
          f"실측={row['y']:.1f}, 예측={row['yhat']:.1f}, "
          f"편차={deviation:.1f}%")

Prophet의 interval_width 파라미터는 이상 탐지의 민감도를 직접 결정한다. 0.95(95% 신뢰 구간)로 설정하면 더 많은 이상을 감지하지만 오탐도 증가하고, 0.99(99%)로 설정하면 확실한 이상만 감지한다. 프로덕션에서는 0.99로 시작하여 필요에 따라 낮추는 것을 권장한다.

DBSCAN: 로그 패턴 클러스터링

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)은 밀도 기반 클러스터링 알고리즘으로, 데이터 포인트가 밀집된 영역을 클러스터로 인식하고, 어떤 클러스터에도 속하지 않는 포인트를 노이즈(이상)로 분류한다. 로그 패턴이나 메트릭 조합의 이상 그룹을 식별하는 데 유효하다.

Prometheus 메트릭 기반 이상 탐지 구현

Prometheus에서 수집한 메트릭을 활용하여 이상 탐지 파이프라인을 구축하는 방법을 살펴본다. 핵심은 Prometheus API로 데이터를 수집하고, ML 모델로 분석한 뒤, 결과를 다시 Prometheus 생태계로 돌려보내 Alertmanager와 연동하는 것이다.

Prometheus Alerting Rules와 ML 결합

전통적인 Prometheus alerting rule과 ML 기반 이상 탐지를 함께 운영하면, 단순 임계값 초과는 기존 규칙이 처리하고, 복잡한 패턴 이상은 ML 모델이 담당하는 2계층 알림 체계를 구축할 수 있다.

# prometheus-rules.yaml
# 전통적 임계값 알림과 ML 이상 탐지 알림을 동시 운용
groups:
  - name: traditional_threshold_alerts
    rules:
      # Level 1: 고정 임계값 알림 (즉각 대응 필요)
      - alert: HighCPUUsageCritical
        expr: |
          100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 95
        for: 5m
        labels:
          severity: critical
          alert_type: threshold
        annotations:
          summary: 'CPU 사용률 95% 초과 ({{ $labels.instance }})'
          description: '{{ $labels.instance }}의 CPU 사용률이 {{ $value | printf "%.1f" }}%입니다.'

      # Level 1: 메모리 임계값 알림
      - alert: HighMemoryUsageCritical
        expr: |
          (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 90
        for: 10m
        labels:
          severity: critical
          alert_type: threshold
        annotations:
          summary: '메모리 사용률 90% 초과 ({{ $labels.instance }})'

  - name: aiops_ml_anomaly_alerts
    rules:
      # Level 2: ML 기반 이상 탐지 알림 (Pushgateway에서 수집)
      - alert: MLAnomalyDetected
        expr: |
          aiops_anomaly_score < -0.5
        for: 3m
        labels:
          severity: warning
          alert_type: ml_anomaly
        annotations:
          summary: 'ML 이상 탐지: {{ $labels.metric_group }}에서 비정상 패턴 감지'
          description: |
            Isolation Forest 이상 점수: {{ $value | printf "%.4f" }}
            점수가 -0.5 미만이면 통계적으로 유의미한 이상입니다.
            대시보드: http://grafana:3000/d/aiops-anomaly

      # Level 2: Prophet 기반 트래픽 이상 탐지
      - alert: TrafficAnomalyDetected
        expr: |
          aiops_prophet_anomaly_flag == 1
        for: 5m
        labels:
          severity: warning
          alert_type: prophet_anomaly
        annotations:
          summary: 'Prophet 예측 벗어남: 트래픽 이상 패턴 감지'
          description: |
            실측값이 99% 예측 구간을 벗어났습니다.
            편차: {{ $labels.deviation_pct }}%

이 구성에서 중요한 것은 for 절의 설정이다. ML 이상 탐지 알림의 for: 3m은 이상 점수가 3분 이상 지속될 때만 알림을 발생시킨다. 이를 통해 일시적인 스파이크로 인한 오탐을 줄인다.

Kubernetes 이벤트 상관 분석

Kubernetes 환경에서는 Pod 재시작, OOMKill, 노드 압박, 디플로이먼트 롤아웃 등 다양한 이벤트가 동시다발적으로 발생한다. 개별 이벤트만 보면 원인을 파악하기 어렵지만, 시간 축으로 정렬하여 상관 분석하면 근본 원인을 빠르게 찾을 수 있다.

kubectl 기반 이벤트 상관 분석 스크립트

다음 스크립트는 특정 시간 범위 내의 Kubernetes 이벤트를 수집하고, 네임스페이스와 이벤트 유형별로 상관 분석하여 근본 원인 후보를 추출한다.

#!/bin/bash
# k8s-event-correlation.sh
# Kubernetes 이벤트 상관 분석 스크립트
# 사용법: ./k8s-event-correlation.sh [namespace] [minutes]

NAMESPACE=${1:-"default"}
MINUTES=${2:-30}
SINCE=$(date -u -d "${MINUTES} minutes ago" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || \
        date -u -v-${MINUTES}M +"%Y-%m-%dT%H:%M:%SZ")

echo "========================================"
echo " K8s 이벤트 상관 분석 보고서"
echo " 네임스페이스: ${NAMESPACE}"
echo " 분석 범위: 최근 ${MINUTES}분"
echo " 시작 시각: ${SINCE}"
echo "========================================"

# 1단계: Warning 이벤트 수집 및 빈도 분석
echo ""
echo "[1/4] Warning 이벤트 빈도 분석"
echo "----------------------------------------"
kubectl get events -n "${NAMESPACE}" \
  --field-selector type=Warning \
  --sort-by='.lastTimestamp' \
  -o custom-columns='TIME:.lastTimestamp,TYPE:.type,REASON:.reason,OBJECT:.involvedObject.name,MESSAGE:.message' \
  | tail -50

# 2단계: OOMKilled Pod 탐지
echo ""
echo "[2/4] OOMKilled Pod 탐지"
echo "----------------------------------------"
kubectl get pods -n "${NAMESPACE}" -o json | \
  jq -r '.items[] |
    select(.status.containerStatuses[]?.lastState.terminated.reason == "OOMKilled") |
    "\(.metadata.name) | 재시작: \(.status.containerStatuses[0].restartCount) | 마지막 OOM: \(.status.containerStatuses[0].lastState.terminated.finishedAt)"'

# 3단계: 노드 상태 분석 (메모리/디스크 압박)
echo ""
echo "[3/4] 노드 Condition 분석"
echo "----------------------------------------"
kubectl get nodes -o json | \
  jq -r '.items[] |
    .metadata.name as $node |
    .status.conditions[] |
    select(.type != "Ready" and .status == "True") |
    "\($node) | \(.type): \(.message)"'

# 4단계: 최근 디플로이먼트 변경 이력
echo ""
echo "[4/4] 최근 디플로이먼트 롤아웃 이력"
echo "----------------------------------------"
for deploy in $(kubectl get deployments -n "${NAMESPACE}" -o name); do
  echo "--- ${deploy} ---"
  kubectl rollout history "${deploy}" -n "${NAMESPACE}" | tail -5
done

# 상관 분석 요약
echo ""
echo "========================================"
echo " 상관 분석 요약"
echo "========================================"
echo ""

# OOMKill과 노드 메모리 압박의 상관관계 체크
OOM_COUNT=$(kubectl get pods -n "${NAMESPACE}" -o json | \
  jq '[.items[] | select(.status.containerStatuses[]?.lastState.terminated.reason == "OOMKilled")] | length')
NODE_PRESSURE=$(kubectl get nodes -o json | \
  jq '[.items[] | .status.conditions[] | select(.type == "MemoryPressure" and .status == "True")] | length')

if [ "$OOM_COUNT" -gt 0 ] && [ "$NODE_PRESSURE" -gt 0 ]; then
  echo "[높은 상관] OOMKill(${OOM_COUNT}건)과 노드 메모리 압박(${NODE_PRESSURE}건) 동시 발생"
  echo "  -> 근본 원인 후보: 노드 메모리 부족 또는 리소스 limits 과다 설정"
elif [ "$OOM_COUNT" -gt 0 ]; then
  echo "[중간 상관] OOMKill(${OOM_COUNT}건) 발생, 노드 압박 없음"
  echo "  -> 근본 원인 후보: 컨테이너 메모리 limits 부족 또는 메모리 릭"
fi

echo ""
echo "분석 완료. 상세 조사가 필요하면 Grafana 대시보드를 확인하세요."

이 스크립트는 4가지 관점에서 이벤트를 수집한 뒤 상관관계를 자동으로 판단한다. OOMKill이 발생한 Pod와 노드 메모리 압박이 동시에 존재하면, 개별 컨테이너의 문제가 아니라 노드 수준의 리소스 부족이 근본 원인일 가능성이 높다고 판단하는 것이다.

Robusta를 활용한 자동 상관 분석

Robusta는 Kubernetes 네이티브 AIOps 플랫폼으로, Prometheus Alertmanager의 알림을 받아 자동으로 컨텍스트를 수집하고 상관 분석을 수행한다.

# robusta-playbook.yaml
# Robusta Playbook: Kubernetes 이벤트 자동 상관 분석
customPlaybooks:
  # OOMKill 발생 시 자동 분석
  - triggers:
      - on_pod_oom_killed:
          namespace_prefix: 'production'
    actions:
      # 1. OOMKilled Pod의 메모리 사용 그래프 수집
      - resource_babysitter:
          fields_to_monitor: ['status.containerStatuses']
      # 2. Prometheus에서 관련 메트릭 수집
      - prometheus_enricher:
          prometheus_url: 'http://prometheus:9090'
          query: |
            container_memory_working_set_bytes{
              pod="{{ $pod_name }}",
              namespace="{{ $namespace }}"
            }
          duration_minutes: 60
      # 3. 동일 노드의 다른 Pod 상태 확인
      - node_running_pods_enricher: {}
      # 4. Slack으로 분석 결과 전송
      - slack_sender:
          slack_channel: '#k8s-alerts'
          message: |
            :rotating_light: OOMKill 상관 분석 보고서
            Pod: {{ $pod_name }}
            네임스페이스: {{ $namespace }}
            노드: {{ $node }}
            메모리 사용 추이 및 동일 노드 Pod 상태가 첨부됩니다.

  # CPU Throttling 발생 시 자동 분석
  - triggers:
      - on_prometheus_alert:
          alert_name: CPUThrottlingHigh
          status: 'firing'
    actions:
      - cpu_throttling_analysis: {}
      - prometheus_enricher:
          prometheus_url: 'http://prometheus:9090'
          query: |
            rate(container_cpu_cfs_throttled_periods_total{
              pod="{{ $pod_name }}"
            }[5m])
          duration_minutes: 30
      - slack_sender:
          slack_channel: '#k8s-alerts'

  # 디플로이먼트 변경 후 에러율 증가 시 자동 상관 분석
  - triggers:
      - on_deployment_update:
          namespace_prefix: 'production'
    actions:
      - deployment_status_enricher: {}
      - prometheus_enricher:
          prometheus_url: 'http://prometheus:9090'
          query: |
            sum(rate(http_requests_total{status=~"5.."}[5m])) /
            sum(rate(http_requests_total[5m])) * 100
          duration_minutes: 15

Robusta의 Playbook은 특정 Kubernetes 이벤트를 트리거로 하여 자동으로 상관 분석 액션을 실행한다. OOMKill이 발생하면 해당 Pod의 메모리 사용 추이, 동일 노드의 다른 Pod 상태, 관련 Prometheus 메트릭을 자동으로 수집하여 Slack으로 전송한다.

알림 노이즈 감소 전략

AIOps 도입의 핵심 목표 중 하나는 알림 노이즈 감소다. PagerDuty의 2025년 State of Digital Operations 보고서에 따르면, 운영 팀이 받는 알림의 약 70%가 조치 불필요(non-actionable)한 노이즈다. 이를 줄이기 위한 전략을 살펴본다.

알림 그룹핑(Alert Grouping)

동일 근본 원인에서 파생된 알림들을 하나의 그룹으로 묶으면 알림 수를 대폭 줄일 수 있다. Alertmanager의 group_bygroup_wait 설정이 이를 담당한다.

시간 기반 그룹핑: group_wait를 30초~1분으로 설정하여 짧은 시간 내 발생한 동일 유형의 알림을 묶는다.

토폴로지 기반 그룹핑: 서비스 의존성 그래프를 활용하여, 상위 서비스 장애로 인한 하위 서비스 알림을 억제한다. API Gateway가 다운되면 수십 개 마이크로서비스의 알림을 개별 전송하는 대신, "API Gateway 다운 - 영향받는 서비스 23개"로 요약한다.

ML 기반 그룹핑: 알림의 시간적 근접성, 영향받는 리소스의 토폴로지 유사성, 알림 메시지의 텍스트 유사도를 종합하여 자동으로 그룹핑한다.

중복 제거(Deduplication)

동일한 알림이 반복 발생하는 경우, 최초 1건만 전송하고 이후에는 카운트만 증가시킨다. Alertmanager의 repeat_interval을 적절히 설정하되, ML 모델의 이상 탐지 결과는 지속적으로 업데이트되므로 repeat_interval을 너무 길게 잡지 않아야 한다.

적응형 임계값(Adaptive Threshold)

고정 임계값 대신, 과거 데이터로부터 학습한 동적 임계값을 사용한다. 예를 들어 평일 오전 10시의 정상 CPU 사용률 범위와 일요일 새벽 3시의 정상 범위는 다르다. 동적 임계값은 이를 반영하여 각 시점별로 적절한 임계값을 자동 설정한다.

오픈소스 AIOps 도구 비교

도구라이선스핵심 기능Kubernetes 통합가격 모델특장점
RobustaOSS + Commercial알림 강화, 자동 분석, Playbook네이티브Free + Pro(연락)K8s 네이티브, Prometheus 통합
Datadog AIOps상용Watchdog 이상 탐지, RCAAgent 기반$23/host/mo~넓은 통합 생태계, 자동 베이스라인
Dynatrace Davis상용인과 분석 AI, 자동 RCAOneAgent$21/host/mo~토폴로지 인식 AI, 자동 의존성 매핑
Moogsoft상용이벤트 클러스터링, 노이즈 감소Webhook연락 필요알림 70% 감소 주장, 상관 분석 특화
Grafana MLOSS + Cloud예측/이상 탐지, SiftPrometheusFree + CloudGrafana 생태계 통합, 비용 효율적

각 도구의 적용 시나리오는 다음과 같다.

  • Robusta: Kubernetes 중심 환경에서 Prometheus를 이미 사용 중이고, 오픈소스를 선호하는 팀
  • Datadog AIOps: 멀티 클라우드 환경에서 APM, 로그, 인프라를 통합 모니터링하는 팀
  • Dynatrace Davis: 복잡한 마이크로서비스 의존성이 있고, 자동 RCA가 필수인 엔터프라이즈 팀
  • Moogsoft: 대량의 알림이 발생하고, 알림 노이즈 감소가 최우선 과제인 대규모 운영 팀
  • Grafana ML: Grafana 스택을 이미 운영 중이고, 점진적으로 ML 기반 분석을 도입하려는 팀

실패 사례와 복구 절차

AIOps 도입 과정에서 흔히 발생하는 실패 사례와 이를 복구하는 절차를 정리한다.

실패 사례 1: 학습 데이터 부족으로 인한 과다 오탐

상황: 새로 구축한 서비스에 Prophet 모델을 적용했으나, 학습 데이터가 3일치뿐이어서 하루에 100건 이상의 오탐이 발생했다. 온콜 팀이 ML 알림 전체를 음소거하면서 실제 장애까지 놓치는 사고가 발생했다.

원인 분석: Prophet은 계절성 패턴을 정확히 학습하려면 최소 2주(주간 계절성 기준)의 데이터가 필요하다. 3일치 데이터로는 주말/평일 패턴 차이를 학습할 수 없어, 토요일 트래픽 감소를 이상으로 판단했다.

복구 절차:

  1. ML 알림을 즉시 별도 Slack 채널로 분리 (알림 음소거 대신 분리)
  2. 최소 14일 이상의 학습 데이터 확보 후 모델 재학습
  3. Shadow Mode 도입: ML 알림을 실제 전송하지 않고 기록만 하면서 정확도 측정
  4. 정밀도(Precision)가 90% 이상일 때 실제 알림으로 전환
  5. interval_width를 0.95에서 0.99로 상향하여 민감도 조절

실패 사례 2: Isolation Forest의 차원 폭주(Curse of Dimensionality)

상황: 100개 이상의 메트릭을 동시에 Isolation Forest에 입력했으나, 모델이 의미 있는 이상을 거의 감지하지 못했다. 고차원 공간에서 모든 데이터가 "고립"되기 쉬워져 이상 점수의 분별력이 떨어졌다.

원인 분석: Isolation Forest는 피처 수가 증가할수록 트리의 분할 효율이 저하된다. 불필요한 피처(노이즈 메트릭)가 많을수록 실제 이상 패턴이 희석된다.

복구 절차:

  1. PCA(주성분 분석)를 적용하여 피처를 10~20개로 축소
  2. 도메인 지식을 활용하여 상관관계가 높은 메트릭을 사전 선별
  3. 서비스별로 독립적인 Isolation Forest 모델을 구축 (전체 클러스터 단일 모델 지양)
  4. max_features 파라미터를 조정하여 각 트리가 사용하는 피처 수 제한

실패 사례 3: 모델 드리프트(Model Drift) 미감지

상황: 6개월 전에 학습한 모델이 서비스 아키텍처 변경(모놀리스에서 마이크로서비스 전환) 이후에도 동일하게 적용되어, 정상적인 마이크로서비스 통신 패턴을 전부 이상으로 감지했다.

원인 분석: ML 모델은 학습 시점의 데이터 분포를 기반으로 작동한다. 서비스 아키텍처가 변경되면 메트릭의 분포 자체가 바뀌므로, 기존 모델이 무효화된다.

복구 절차:

  1. 모델 재학습 자동화 파이프라인 구축 (주 1회 또는 데이터 분포 변화 감지 시)
  2. KL Divergence 또는 PSI(Population Stability Index)로 데이터 분포 변화 모니터링
  3. CI/CD 파이프라인에 모델 검증 단계 추가: 새 모델의 정밀도/재현율이 기준 이하이면 배포 차단
  4. 아키텍처 변경 이벤트를 모델 재학습 트리거로 연동

실패 사례 4: 상관 분석 오판으로 인한 잘못된 자동 대응

상황: Robusta Playbook에서 "에러율 증가 + 최근 디플로이먼트 변경"을 감지하면 자동 롤백하도록 설정했으나, 실제로는 외부 API 장애로 인한 에러율 증가임에도 디플로이먼트를 불필요하게 롤백하여 서비스 중단이 2배로 늘어났다.

원인 분석: 시간적 상관관계(temporal correlation)가 인과관계(causation)를 의미하지는 않는다. 디플로이먼트 직후 에러가 발생했지만, 실제 원인은 동시간대에 발생한 외부 API 장애였다.

복구 절차:

  1. 자동 롤백 조건에 "외부 의존성 건전성 확인" 단계 추가
  2. 자동 롤백 대신 "롤백 권고" 알림으로 변경 (사람의 최종 판단 포함)
  3. Canary 배포 전략을 도입하여 전체 롤백 위험 감소
  4. 롤백 실행 전 Dry-run 모드에서 영향도 분석 실행

운영 시 주의사항 체크리스트

AIOps 기반 이상 탐지 시스템을 프로덕션에 도입할 때 반드시 확인해야 할 사항을 정리한다.

모델 학습 및 배포:

  • 학습 데이터가 최소 2주 이상 확보되었는가
  • Shadow Mode에서 최소 1주일 이상 검증을 완료했는가
  • 모델 재학습 자동화 파이프라인이 구축되었는가
  • 모델 드리프트 모니터링 메트릭이 설정되었는가
  • A/B 테스트로 새 모델과 기존 모델의 성능을 비교했는가

알림 품질 관리:

  • 오탐율(False Positive Rate)이 10% 이하인가
  • 미탐율(False Negative Rate)을 별도로 측정하고 있는가
  • 알림 그룹핑과 중복 제거 정책이 설정되었는가
  • 알림 수신자의 피드백을 수집하는 메커니즘이 있는가
  • 알림 채널이 적절히 분리되어 있는가 (critical/warning/info)

Kubernetes 통합:

  • RBAC 권한이 최소 권한 원칙에 맞게 설정되었는가
  • Robusta/분석 에이전트의 리소스 requests/limits가 설정되었는가
  • 이벤트 상관 분석에 필요한 kube-state-metrics가 배포되었는가
  • 네임스페이스별 분석 범위가 적절히 제한되었는가

보안 및 컴플라이언스:

  • Prometheus API 접근에 인증/인가가 적용되었는가
  • ML 모델의 입력 데이터에 민감 정보(PII)가 포함되지 않는가
  • 이상 탐지 결과 로그의 보존 기간이 정책에 부합하는가

운영 절차:

  • 자동 대응 액션에 사람의 승인 단계가 포함되어 있는가
  • 자동 대응 실패 시 폴백(fallback) 절차가 정의되어 있는가
  • 모델 성능 대시보드가 구축되어 있는가 (정밀도, 재현율, F1 Score)
  • 정기적 모델 리뷰 회의(월 1회)가 스케줄링되어 있는가

마치며

AIOps 기반 이상 탐지는 "AI가 모든 것을 알아서 해준다"는 환상이 아니라, 운영 팀의 판단력을 증강하는 도구다. 고정 임계값으로는 감지할 수 없는 Slow Burn 장애를 조기에 발견하고, 수십 개의 알림을 하나의 근본 원인으로 압축하며, 반복적인 분석 작업을 자동화하여 엔지니어가 실제 문제 해결에 집중할 수 있게 해준다.

다만, AIOps 도입은 기술적 구현보다 운영 문화의 변화가 더 중요하다. Shadow Mode를 통한 점진적 도입, 지속적인 모델 성능 모니터링, 그리고 알림 품질에 대한 팀 차원의 피드백 루프를 구축하는 것이 성공의 핵심이다. Isolation Forest와 Prophet으로 시작하여 작은 범위에서 효과를 검증하고, 점진적으로 범위를 확대해 나가는 것을 강력히 권장한다.

참고자료