Back

K8s 알림 트리아지 자동화

시작은 불편함이었다. 뭔가 안 되면 k8s를 직접 들여다봐야 아는 구조였다. 테스트환경에서 뭔가 느리거나, 빌드가 안 돌거나, Pod이 죽어 있거나 — 누군가 “이거 왜 안 돼요?”라고 물어보면 그때서야 kubectl을 치고 상태를 확인했다. 문제가 터지고 나서야 인지하는 게 반복됐다.

클러스터에 Alertmanager가 돌고 있었지만 아무도 receiver에 자기 메일을 등록하지 않고 있었다. 2월 중순에 내 이메일을 receiver에 등록했다.

등록하자마자 알림이 쏟아졌다. 연휴 동안 쌓여 있던 것들. 그때부터 Alertmanager 메일이 오면 처리하는 게 루틴이 됐다. 대부분 KubePodNotReady, 가끔 KubePersistentVolumeFillingUp이나 CrashLoopBackOff. 알림이 오면 하는 건 매번 비슷했다.

  1. 알림에서 네임스페이스, Pod 이름, alert 종류 확인
  2. kubectl get podkubectl describe podkubectl logs
  3. 관련 리소스(Deployment, DaemonSet, PVC 등) 확인
  4. 원인 파악 후 조치

이걸 2월에 세 번, 3월 초에 한 번 더 했다.

반복에서 보인 것

네 건을 돌아보면 진단 과정 자체는 거의 같았는데, 매번 미묘하게 다른 순서로 했다.

  • 첫 번째: PV filling 알림이라 PVC 상태부터 봤고, 같이 온 PodNotReady는 나중에 봤다
  • 두 번째: KubeAPIDown이 5개 동시에 떠서 타겟 API부터 봤다. 결국 디스크 Full이었다
  • 세 번째: 로그부터 봤다. pip timeout이 찍혀 있길래 바로 내부 패키지 저장소 확인으로 넘어갔다
  • 네 번째: describe부터 봤다. CI/CD 빌드 Pod라 owner reference 추적이 먼저였다

결과적으로 네 건 다 해결했지만, 순서가 컨디션에 따라 달라지니까 빠뜨리는 게 생겼다. 첫 번째에서 빌드 Pod 누적 문제를 놓쳤다가 네 번째에 다시 만났다. 세 번째에서는 저장소 리소스 상태를 나중에야 확인했다.

스킬로 순서를 강제하기

Claude Code에는 커스텀 스킬이라는 게 있다. .claude/commands/ 디렉토리에 마크다운 파일을 넣으면, 프롬프트에 진단 절차를 정의해둘 수 있다. /alert라고 치면 해당 절차가 실행된다.

구조를 이렇게 잡았다:

  1. Alertmanager JSON 파싱 → alert 종류와 대상 리소스 추출
  2. 카테고리 분류 (Node / Pod / Storage / GPU 등)
  3. 카테고리별 kubectl 명령어를 정해진 순서로 실행
  4. 구조화된 진단 리포트 출력

핵심은 3번이다. Pod 알림이면 무조건 get poddescribeeventslogsowner reference 순서로 돌린다. 사람이 직접 치면 “어차피 로그가 답이겠지” 하고 건너뛰는 단계가 있는데, 스킬은 건너뛰지 않는다.

실전 적용

만들고 30분 만에 첫 알림이 왔다. KubePodNotReady — 누군가 kubectl debug node로 디버깅하다 남긴 고아 Pod. 스킬이 owner reference가 없다는 걸 바로 잡아냈다.

같은 날 두 번째 알림. CI/CD 빌드 Pod에서 내부 레지스트리 이미지 누락. 스킬이 5단계 컨테이너를 순서대로 확인해서 마지막 이미지 빌드 단계의 매니페스트 에러까지 한 번에 도달했다.

며칠 뒤에는 GPU 모니터링 익스포터 CrashLoopBackOff 알림을 처리했다. 스킬이 DaemonSet 상태 → Pod 로그 → 노드 GPU 드라이버 버전까지 순서대로 확인했고, 모니터링 도구와 GPU 드라이버 간 버전 불일치를 잡아냈다. 여기서 재시작 횟수가 기간 대비 이상하다는 걸 발견하고 노드 재시작 타임라인까지 역추적할 수 있었다.

자동화의 가치가 속도만은 아니었다

kubectl 치는 시간을 아낀 건 부수적이었다. 진짜 가치는 두 가지였다.

일관성. 알림이 오면 항상 같은 순서로 같은 항목을 확인한다. 사람이 직접 하면 “이번엔 로그가 핵심이겠지” 하고 다른 단계를 건너뛰는데, 스킬은 그렇게 하지 않는다. 첫 번째에서 놓쳤던 빌드 Pod 누적 문제 같은 건 스킬이 owner reference를 매번 확인했다면 첫 번에 잡았을 것이다.

진단 기록. 스킬이 출력하는 리포트가 그 자체로 기록이 된다. 누가 언제 어떤 알림을 어떤 순서로 확인했는지가 대화 로그에 남는다. 수동으로 kubectl을 치면 터미널 히스토리에 명령어만 남지, 어떤 맥락에서 왜 그 명령어를 쳤는지는 사라진다.

판단 기준

“이걸 자동화할 만한가?”를 판단한 기준은 단순했다.

  • 같은 종류의 작업을 3번 이상 반복했는가 → 한 달 반 동안 4번
  • 매번 같은 도구(kubectl)로 비슷한 명령어를 치는가 → 그렇다
  • 순서가 사람마다, 또는 같은 사람이라도 날마다 달라지는가 → 그렇다
  • 자동화 비용이 수동 작업 3회 미만인가 → 스킬 파일 하나 작성하는 데 30분

세 번째가 결정적이었다. 속도가 아니라 일관성이 부족하다는 게 자동화의 트리거였다.