KubeTokenWatch 구축하기: 클러스터를 디버깅하고 자체 비용을 추적하는 AI 에이전트
요약
Kubernetes 클러스터의 문제를 진단하고 해결 방법을 제시하는 동시에, AI 에이전트의 LLM 호출 비용을 실시간으로 추적하는 KubeTokenWatch를 소개합니다. OpenTelemetry와 SigNoz를 활용하여 에이전트의 운영 효율성과 비용 가시성을 동시에 확보합니다.
핵심 포인트
- Kubernetes 이벤트를 스캔하여 다양한 리소스의 오류를 자동 진단
- Llama 3.3 70B 모델을 사용하여 문제 원인 분석 및 수정 가이드 제공
- OpenTelemetry를 통해 LLM 호출별 토큰 사용량 및 달러 비용 추적
- SigNoz 대시보드를 통한 비용 급증 알림 및 시각화 기능 구현
KubeTokenWatch 구축하기: 클러스터를 디버깅하고 자체 비용을 추적하는 AI 에이전트
Agents of SigNoz Hackathon (SigNoz x WeMakeDevs)를 위해 작성됨
아이디어
저는 Agents of SigNoz Hackathon을 위해 단순히 SigNoz를 사용하기 위한 데모가 아니라, 실제로 문제를 해결할 수 있는 무언가를 만들고 싶었습니다. 그래서 나열된 프로젝트 아이디어 중 하나인 #11658 — LLM cost tracer를 선택하여 KubeTokenWatch를 구축했습니다. 이는 Kubernetes 네임스페이스를 스캔하여 고장 난 부분을 찾아내고, 무엇이 잘못되었는지와 어떻게 수정해야 하는지를 정확히 알려주며, 그 과정에서 발생하는 모든 비용을 추적하는 AI 에이전트입니다.
Repo: github.com/iamridoydey/KubeTokenWatch
문제점
사실 두 가지 문제가 있습니다:
- 무언가가 왜 실패했는지 파악하기 위해 다양한 객체 유형에 걸쳐 가공되지 않은
kubectl describe출력을 읽는 것은, 특히 압박을 받는 상황에서는 매우 느립니다. - AI 에이전트는 끊임없이 LLM 호출을 수행하지만, 단일 요청이 실제로 얼마의 비용을 발생시키는지 실시간으로 확인할 수 있는 사람은 아무도 없습니다.
저는 이 두 가지를 동시에 해결하고 싶었습니다.
기능
에이전트에게 네임스페이스를 제공하면, 에이전트는 pods, deployments, statefulsets, daemonsets, jobs, PVCs 등 건강하지 않은 상태의 모든 것을 스캔합니다. 가능한 모든 리소스 유형에 대해 체크 로직을 하드코딩하는 대신(Kubernetes에는 30개 이상의 내장 Kind와 무제한의 커스텀 리소스가 있습니다), 저는 kubectl get events나 K9s와 같은 도구들이 사용하는 것과 동일한 트릭을 사용했습니다. Kubernetes는 어떤 객체에서든 문제가 발생할 때마다 Warning 이벤트를 방출합니다. 단 한 번의 API 호출로 이 모든 것을 가져올 수 있으므로, 제가 명시적으로 코딩하지 않은 리소스 Kind에 대해서도 스캔이 작동합니다.
이 실제 데이터는 LLM (무료로 실행되는 Groq의 Llama 3.3 70B)으로 전달되며, LLM은 단순히 문제에 대한 설명을 제공하는 것에 그치지 않고 무엇이 잘못되었는지 설명하고 짧은 번호 매기기 방식의 수정 목록을 제공합니다.
두 번째 절반은 비용 추적 (cost tracing)입니다. 에이전트가 수행하는 모든 LLM 호출은 OpenTelemetry 인스트루멘테이션 (instrumentation)으로 감싸져 있으며, 사용된 모델, 사용자, 토큰 수, 그리고 해당 호출의 실제 달러 비용이 태그로 지정됩니다. 이 모든 데이터는 자체 호스팅되는 SigNoz 인스턴스로 전송되며, 저는 이곳에 대시보드와 예산 급증 알림 (budget-spike alert)을 구축했습니다.
이는 두 가지 방식으로 사용할 수 있습니다. 터미널에서 실행하는 CLI 방식과 HTTP API 방식이며, 두 방식 모두 내부적으로는 정확히 동일한 핵심 로직을 공유합니다.
아키텍처 (Architecture)
CLI (cli.py) ─┐
├──▶ agent.py (shared core)
API (app.py) ─┘ │
...
cli.py와 app.py는 얇은 래퍼 (wrapper)일 뿐이며, 모든 실제 로직은 agent.py에 한 번만 존재하므로 두 인터페이스 사이에 중복된 코드가 없습니다.
실제로 SigNoz를 사용한 방법
저는 단순히 데이터를 SigNoz로 보내는 것에 그치지 않았습니다. 네 가지 신호 (signal) 유형을 모두 사용했습니다.
- 트레이스 (Traces) — 모든 LLM 호출은 모델, 사용자, 토큰, 비용이 태그된 스팬 (span)이 됩니다.
- 메트릭 (Metrics) — 실행된 총 진단 횟수, 누적 비용, 총 도구 호출 (tool calls)에 대한 카운터입니다.
- 로그 (Logs) — "진단 시작" 및 "LLM 호출 완료"와 같이 읽기 쉬운 일반 이벤트로, SigNoz의 로그 탭으로 전송됩니다.
- 대시보드 + 알림 (Dashboards + alerts) — SigNoz의 쿼리 빌더 (query builder)로 구축된 대시보드를 통해 시간에 따른 비용, 토큰 사용량, 사용자/네임스페이스별 비용을 보여주며, 단일 진단 비용이 임계값을 초과할 때 작동하는 실시간 알림 규칙을 설정했습니다.
진행 과정에서 실제로 겪은 문제들
이 부분에 대해서는 솔직해지고 싶습니다. 모든 것이 한 번에 잘 작동한 척하는 것보다 훨씬 유용하다고 생각하기 때문입니다.
처음에 사용한 모델은 도구 호출 (tool calling)을 안정적으로 수행하지 못했습니다. 처음에는 저렴하고 빠르기 때문에 Groq의 llama-3.1-8b-instant를 사용했지만, 간혹 잘못된 형식의 함수 호출 (function-call) 구문을 생성하여 tool_use_failed 에러를 발생시켰습니다. 그래서 Groq에서 여전히 무료로 제공되는 llama-3.3-70b-versatile로 교체하였고, 그 이후로는 안정적으로 작동하고 있습니다.
CLI에서 메트릭(Metrics)이 조용히 실패했습니다. 제 CLI는 실행 후 결과를 출력하고 종료되는 수명이 짧은 프로세스입니다. OpenTelemetry 카운터(Counters)는 기본적으로 누적(cumulative) 값을 보고하도록 설정되어 있어, 새로운 프로세스가 시작될 때마다 카운터는 항상 0부터 시작합니다. 이로 인해 별도의 실행 간에 SigNoz에는 변화가 없는 평탄한 시퀀스로 나타났고, 에이전트가 분명히 작동하고 있음에도 불구하고 제 "진단 실행(diagnoses run)" 패널은 0에 머물러 있었습니다. 해결 방법은 메트릭 익스포터(metrics exporter)를 **델타 시간성 (delta temporality)**으로 전환하여, 각 익스포트가 누적 합계가 아닌 마지막 이후 변경된 사항을 보고하도록 하고, CLI 프로세스가 종료되기 전에 모든 텔레메트리(telemetry)를 명시적으로 플러시(flush)하는 것이었습니다.
SigNoz의 쿼리 빌더(query builder)에서 "Increase"와 "Sum"의 차이 때문에 한동안 혼란스러웠습니다. 카운터(Counter) 유형의 메트릭은 집계(aggregation) 옵션으로 Increase 또는 Rate만 제공하며, 원시 Sum은 제공하지 않습니다. 누적된 카운터 값을 직접 합산하면 보통 중복 계산(double-counts)이 발생하기 때문입니다. 왜 그러한 제한이 존재하는지 이해하고 나니 나머지는 이해가 되었습니다.
남은 과제 / 다음에 추가할 사항
- 클러스터 전반의 스캔을 위한
--all-namespaces플래그 - 서비스(Services) 및 인그레스(Ingresses)에 대한 상태 확인 (일치하는 엔드포인트가 없는 경우 등)
- 한도 초과 시 실제로 추가 요청을 차단하는 사용자별 일일 예산 상한선
제작 방식에 대한 노트
코드 작성, 디버깅, 설계 결정에 대한 논의 과정 전반에서 AI의 도움(Anthropic의 Claude)을 받았습니다. 하지만 리소스 유형을 하드코딩하는 대신 이벤트 기반 탐색(event-based discovery)을 사용하는 것, 프로젝트를 두 개의 진입점을 가진 공유 코어로 분리하는 것, 실제 신뢰성 버그를 발견한 후 모델을 교체하는 것과 같은 모든 실제 요구 사항, 트레이드오프(tradeoff), 그리고 아키텍처 선택은 제가 직접 결정하고, 실제 클러스터에서, 의도적으로 발생시킨 실제 장애를 대상으로 직접 테스트한 것들입니다.
직접 시도해 보세요
전체 설정 지침, 프로젝트 구조 및 코드는 리포지토리(repo)에 있습니다:
👉 github.com/iamridoydey/KubeTokenWatch
WeMakeDevs와 SigNoz가 주관하는 Agents of SigNoz Hackathon을 위해 구축되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기