728x90

1. 왜 지금 이 얘기가 나오나

요즘 옵저버빌리티 벤더들 데모를 보면 흐름이 다 비슷하다. 경보가 뜨면 AI가 알아서 관련 메트릭·로그·트레이스를 훑고, 최근 배포 내역과 연결하고, "○○ 서비스의 커넥션 풀 고갈로 보입니다, 3시간 전 배포 커밋 abc123이 유력합니다"라고 슬랙에 카드 하나를 던진다. 심하면 롤백 버튼까지 같이 붙여준다.

실무자 입장에서 이건 솔직히 매력적이다. 새벽 3시에 페이저 울리고, 눈 비비며 Grafana 대시보드 12개를 순회하고, 배포 채널 스크롤 올려가며 "누가 뭘 올렸지" 찾는 그 20분이 통째로 사라지니까. MTTR 그래프는 예쁘게 내려간다.

그런데 이번에 공유된 글이 찌르는 지점은 여기다. 그 20분은 낭비가 아니라 학습 시간이었다는 것. 대시보드를 헤매는 동안 엔지니어는 "아, 이 서비스는 DB 커넥션이 이렇게 흐르는구나", "이 큐가 밀리면 저쪽 API가 먼저 죽는구나"를 몸으로 익힌다. AI가 그 구간을 대신 걸어주면, 결과는 얻지만 지도는 안 남는다.

그리고 결국 AI가 못 푸는 장애 — 처음 보는 형태, 여러 시스템이 얽힌 것, 데이터 정합성이 깨진 것 — 만 사람에게 넘어온다. 그때 넘겨받는 사람이 시스템 감각이 없는 상태라면? 그게 이 글의 문제 제기다. 참고로 원문 전문을 확보하지 못해 세부 논거나 인용된 사례는 원문 확인이 필요하다.

2. 자동화의 아이러니: 40년 전에 이미 나온 얘기

이 현상은 새로운 게 아니다. 인간공학 쪽에서 Lisanne Bainbridge가 1983년에 쓴 "Ironies of Automation"이라는 유명한 논문이 있다. 핵심 주장 두 가지가 지금 AI SRE 상황에 그대로 꽂힌다.

  • 아이러니 1: 자동화는 쉬운 일부터 가져간다. 그래서 사람에게는 자동화가 못 하는, 가장 어려운 일만 남는다.
  • 아이러니 2: 평소에 손을 안 쓰면 기술이 녹슨다. 그런데 정작 사람이 개입해야 하는 순간은 시스템이 최악으로 망가진 순간이다.

항공 쪽 비유가 제일 와닿는다. 오토파일럿이 순항을 다 해주는 조종사는 수동 조작 감각이 무뎌진다. 그리고 오토파일럿이 해제되는 순간은 대체로 기상이 최악이거나 센서가 이상할 때다. 즉 가장 어려운 조건에서, 가장 준비 안 된 사람이 조종간을 잡는다.

온콜에 대입하면 이렇다. AI SRE가 P3~P4 수준 반복 장애(디스크 풀, 파드 OOMKilled, 특정 배포 후 5xx 증가)를 다 처리한다. 주니어는 1년 동안 온콜을 서도 실제로 손을 댄 장애가 서너 건뿐이다. 그러다 어느 날 리전 단위 네트워크 파티션이 터지고 AI가 "관련 신호가 여러 서비스에 분산되어 단일 원인을 특정할 수 없습니다"를 뱉는다. 이때 조종간을 잡을 사람이 없다.

더 고약한 건 조직 차원의 지식이 문서가 아니라 AI 컨텍스트 안에만 쌓인다는 점이다. 예전엔 장애 하나 겪으면 위키에 런북이 늘고, 사람 머릿속에 아키텍처 그림이 갱신됐다. 지금은 그 지식이 벤더 SaaS의 임베딩 인덱스 안에 들어간다. 계약이 끝나거나 모델이 바뀌면 조직에 뭐가 남는지 냉정하게 봐야 한다.

3. 실무 관점: 뭘 맡기고 뭘 쥐고 있을 건가

맡겨도 되는 것 / 쥐고 있어야 하는 것

5년 굴려보면서 정리한 기준은 "되돌릴 수 있냐"와 "판단이 필요하냐" 두 축이다.

  • AI에 맡겨도 되는 것: 컨텍스트 수집. 관련 대시보드 링크 모으기, 최근 30분 배포·설정 변경 목록, 동일 알럿 과거 발생 이력, 관련 서비스 의존성 그래프. 이건 사람이 해도 기계적인 작업이고 실수만 늘어난다.
  • AI가 초안만 내고 사람이 결정할 것: 원인 가설. "이게 원인입니다"가 아니라 "가설 3개와 각각의 근거·반증 방법"을 내게 만들어야 한다. 단일 정답을 주는 순간 사람은 검증을 안 한다.
  • 사람이 쥐고 있어야 하는 것: 상태를 변경하는 모든 액션. 롤백, 스케일 조정, 트래픽 차단, DB 작업. 특히 되돌릴 수 없는 것(데이터 삭제, 마이그레이션, DNS TTL 긴 변경)은 무조건 사람.

여기서 흔한 오해 하나. "그럼 자동 롤백도 하지 말라는 거냐?" 아니다. 자동 롤백은 해도 된다. 다만 조건이 명시적으로 코드에 박혀 있고 사람이 그 조건을 읽을 수 있어야 한다. LLM이 상황 봐서 판단해서 롤백하는 것과, 카나리 에러율 임계치 초과 시 롤백하는 규칙은 완전히 다른 얘기다. 후자는 사람이 규칙을 이해하고 튜닝하지만, 전자는 왜 롤백됐는지 아무도 모른다.

실행 가능한 예제 1: AI가 손대지 못할 영역을 RBAC로 못 박기

AI 에이전트에 쿠버네티스 접근을 줄 때, "일단 편의상 cluster-admin" 하고 나중에 줄이겠다는 계획은 100% 안 지켜진다. 처음부터 읽기 전용으로 시작하는 게 맞다.

# ai-sre-readonly.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ai-sre-investigator
rules:
- apiGroups: ["", "apps", "batch"]
  resources: ["pods", "pods/log", "events", "deployments", "replicasets", "jobs"]
  verbs: ["get", "list", "watch"]      # create/delete/patch 없음
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods", "nodes"]
  verbs: ["get", "list"]

적용하고 실제로 막히는지 확인한다. kubectl auth can-i는 이럴 때 제일 빠르다.

$ kubectl auth can-i get pods/log \
    --as=system:serviceaccount:observability:ai-sre -n prod
yes

$ kubectl auth can-i delete pods \
    --as=system:serviceaccount:observability:ai-sre -n prod
no

$ kubectl auth can-i patch deployments \
    --as=system:serviceaccount:observability:ai-sre -n prod
no

이 세 줄이 "AI는 조사만 하고 손은 사람이 댄다"는 정책의 실체다. 문서에 써놓는 것보다 이게 훨씬 강력하다.

실행 가능한 예제 2: 온콜이 손으로 밟는 조사 경로 남기기

AI가 다 해주더라도, 신규 입사자가 손으로 따라갈 수 있는 최소 경로는 스크립트로 유지해야 한다. 우리 팀은 이런 걸 ops/drill/ 밑에 둔다.

#!/usr/bin/env bash
# ops/drill/trace-5xx.sh  — 5xx 급증 시 사람이 밟는 최소 경로
set -euo pipefail
SVC="$1"; NS="${NS:-prod}"

echo "== 1) 최근 배포 =="
kubectl -n "$NS" rollout history deploy/"$SVC" | tail -3

echo "== 2) 재시작/OOM 파드 =="
kubectl -n "$NS" get pods -l app="$SVC" \
  -o custom-columns='POD:.metadata.name,RS:.status.containerStatuses[0].restartCount,REASON:.status.containerStatuses[0].lastState.terminated.reason'

echo "== 3) 최근 5분 에러율 (PromQL) =="
curl -sG "$PROM_URL/api/v1/query" \
  --data-urlencode "query=sum(rate(http_requests_total{service=\"$SVC\",code=~\"5..\"}[5m]))
    / sum(rate(http_requests_total{service=\"$SVC\"}[5m]))" \
  | jq -r '.data.result[0].value[1] // "no data"'
$ NS=prod ./ops/drill/trace-5xx.sh checkout-api
== 1) 최근 배포 ==
REVISION  CHANGE-CAUSE
41        image: checkout-api:1.22.3
42        image: checkout-api:1.23.0
== 2) 재시작/OOM 파드 ==
POD                              RS   REASON
checkout-api-7c9f4d8b6-2xk4t     3    OOMKilled
checkout-api-7c9f4d8b6-9jm2p     0    
== 3) 최근 5분 에러율 (PromQL) ==
0.0731

핵심은 스크립트 자체가 아니라 "5xx가 뜨면 배포 → 파드 상태 → 에러율 순으로 본다"는 사고 순서를 코드로 박제한다는 점이다. AI가 답을 먼저 줘도, 온콜은 이 순서를 밟아 교차 검증하게 만든다.

흔한 함정

함정 1: 권한을 줄였더니 AI가 "원인 불명"만 뱉는다. 위 RBAC를 적용하고 나서 십중팔구 이런 걸 만난다.

Error from server (Forbidden): events is forbidden: User
"system:serviceaccount:observability:ai-sre" cannot list resource "events"
in API group "" in the namespace "kube-system"

ClusterRole은 만들었는데 특정 네임스페이스에 RoleBinding이 안 걸렸거나, ClusterRoleBinding이 아니라 네임스페이스 한정 바인딩을 걸어놨을 때 나온다. 여기서 귀찮다고 cluster-admin을 붙이는 순간 앞의 설계가 다 무너진다. 필요한 네임스페이스를 열거해서 명시적으로 여는 게 맞다.

함정 2: 그럴듯한 오답. LLM 기반 분석은 근거가 부족해도 자신 있게 결론을 낸다. 실제로 겪은 패턴은 이렇다 — DB 응답이 느려진 진짜 원인은 배치 잡이 테이블 락을 잡은 건데, AI는 같은 시각에 나간 무관한 프론트엔드 배포를 범인으로 지목한다. 시간적 상관관계만 보고 인과로 단정한 것이다. 온콜이 시스템 감각이 있으면 "프론트 배포가 왜 DB를 느리게 해?"라고 되묻지만, 감각이 없으면 그대로 롤백하고 30분을 날린다.

대응은 하나뿐이다. AI 출력에 신뢰도와 반증 방법을 같이 쓰게 강제하는 것. 프롬프트/템플릿 레벨에서 "가설, 지지 근거, 이 가설이 틀렸다면 관측될 신호"를 세 칸으로 나눠 출력하게 한다. 세 번째 칸이 없으면 검증이 안 된다.

함정 3: 알럿 다이어트를 AI가 대신하게 두는 것. 시끄러운 알럿 100개를 AI가 잘 요약해주니까 알럿 정리를 안 하게 된다. 이건 부채를 이자만 내며 굴리는 거다. AI 도입 전에 알럿을 SLO 기반으로 줄이는 작업이 먼저다. 안 그러면 AI는 노이즈를 학습해서 노이즈를 요약해준다.

함정 4: 포스트모템이 AI 요약본으로 대체되는 것. 이게 제일 조용히 진행된다. AI가 타임라인을 자동 생성해주니 사람이 쓰는 부분이 "액션 아이템" 세 줄로 줄어든다. 포스트모템의 가치는 문서가 아니라 여러 명이 모여서 "왜 이게 안 잡혔지"를 따지는 30분에 있는데, 그 자리가 사라진다.

학습이 남는 온콜을 만드는 실무 장치

  • AI 결론 지연 공개(delayed reveal): 훈련 목적 세션에서는 AI 분석 결과를 5~10분 뒤에 공개한다. 온콜이 먼저 자기 가설을 슬랙에 적고, 그다음 AI 답과 비교한다. 이 diff가 그대로 학습 자료다.
  • 섀도 온콜: 주니어가 실제 페이저를 받되, 시니어가 뒤에 붙는다. AI가 이미 답을 냈어도 주니어는 위 trace-5xx.sh 같은 경로를 직접 밟는다. 복구는 빠르게, 학습은 별도로 분리하는 게 핵심.
  • 런북은 절차가 아니라 모델을 담는다: "1. 파드 재시작 2. 확인" 같은 런북은 AI가 대체하면 그만이다. 대신 "이 서비스는 커넥션 풀 크기가 N이고, 업스트림 타임아웃이 M초라 M초를 넘기면 앞단에서 먼저 터진다" 같은 시스템의 작동 원리를 적어야 사람에게 남는다.
  • 게임데이: AI 보조를 꺼놓고 하는 장애 훈련을 분기 1회라도 넣는다. 오토파일럿 끄고 수동 착륙 연습하는 것과 같은 이유다.
  • 지표를 MTTR 하나로 두지 않기: MTTR만 보면 AI 의존도를 올리는 게 항상 정답이 된다. "사람이 직접 조사한 인시던트 비율", "온콜 1인당 신규 유형 장애 경험 건수" 같은 걸 같이 본다. 조직마다 정의는 달라야 하니 그대로 베끼지 말고 팀 상황에 맞춰라.

단계별 도입 순서

한 번에 다 하려다 망하는 걸 여러 번 봤다. 순서는 이렇게 잡는 게 안전하다.

  1. 0단계: 알럿 정리와 서비스 소유권 명확화. AI 붙이기 전에 끝내야 한다.
  2. 1단계: 읽기 전용 컨텍스트 수집만. 알럿에 관련 링크·배포 이력을 자동으로 붙이는 수준.
  3. 2단계: 가설 제안. 단 복수 가설 + 반증 방법 형식 강제.
  4. 3단계: 명시적 규칙 기반 자동 조치(카나리 롤백 등). LLM 판단이 아니라 규칙.
  5. <
728x90

+ Recent posts