페이저가 울리기 전 Kubernetes 클러스터를 복구하는 5-에이전트 AI 시스템 구축기
요약
Kubernetes 클러스터의 장애를 자율적으로 탐지, 진단, 복구하는 5-에이전트 AI 시스템인 NeuroScale Autopilot 구축 사례를 소개합니다. 단순한 명령어 추천을 넘어 지속적 탐지부터 안전한 실행 및 인간 에스컬레이션까지 포함하는 자율 운영 아키텍처를 다룹니다.
핵심 포인트
- 단순 자동 완성을 넘어선 진정한 자율 운영 DevOps 지향
- 탐지, 분석, 실행 등 역할을 분리한 5-에이전트 파이프라인 구조
- Kubernetes 이벤트를 기반으로 한 실시간 장애 대응 아키텍처
- 안전한 실행을 위한 서킷 브레이커 및 드라이 런 모드 적용
모든 온콜(on-call) 엔지니어가 겪는 순간이 있습니다.
새벽 2시입니다. Slack이 폭발하듯 울립니다. 프로덕션 환경에서 Pod들이 충돌(crashing)하고 있습니다. 당신은 반쯤 잠든 상태로 SSH 접속을 하여, 로그를 찌푸리며 바라보며, 정확히 어떤 런북(runbook)이 이 CrashLoopBackOff 패턴을 처리하는지 기억해내려 애씁니다. 이전에 수백 번은 붙여넣었을 명령어들을 붙여넣습니다. 문제를 해결합니다. 다시 잠자리에 듭니다. 그리고 다음 주에 똑같은 일을 반복합니다.
저는 이 반복되는 루프에 지쳤습니다. 그래서 이 루프를 영구적으로 닫아버릴 시스템을 구축했습니다.
NeuroScale Autopilot은 Kubernetes 클러스터를 감시하고, 무엇이 잘못되었는지 진단하며, 적절한 해결책을 찾아내고, 이를 안전하게 실행하며, 스스로 처리할 수 없는 상황에서만 당신을 깨우는 5-에이전트(5-agent) AI 파이프라인입니다.
제가 이것을 어떻게 구축했는지 그 아키텍처(architecture), 모델 선택, 트레이드오프(tradeoffs), 그리고 저를 놀라게 했던 순간들을 정확히 설명해 드리겠습니다.
오늘날 "DevOps를 위한 AI"의 문제점
대부분의 "AI 기반" DevOps 도구들은 미화된 채팅 인터페이스에 불과합니다. 자연어로 문제를 설명하면, LLM(Large Language Model)이 kubectl 명령어를 제공하고, 당신은 그것을 복사해서 붙여넣습니다. 그것은 자동화(automation)가 아닙니다. 단지 단계가 몇 개 더 추가된 자동 완성(autocomplete)일 뿐입니다.
진정한 자율 운영(autonomous operations)은 다음을 의미합니다:
- 지속적인 탐지 (Continuous detection) - 당신이 보고하는 것이 아니라 시스템이 문제를 찾아냄
- 문맥 인식 진단 (Context-aware diagnosis) - 단순히 "Pod가 충돌 중"이라고 하는 것이 아니라, 왜 그런지 확신을 가지고 진단함
- 구조화된 복구 (Structured remediation) - 막연한 느낌이 아닌 구체적인 단계
- 안전한 실행 (Safe execution) - 서킷 브레이커(circuit breakers), 드라이 런(dry-run) 모드, 롤백(rollback) 경로
- 예외 상황 시 인간에게 에스컬레이션 (Human escalation on edge cases) - 완전히 감독 없는 상태는 무모하기 때문
기존의 어떤 오픈 소스 도구도 이 다섯 가지를 모두 수행하지 못합니다. NeuroScale Autopilot은 수행합니다.
아키텍처: 다섯 개의 에이전트, 하나의 루프
Kubernetes Events
|
v
...
오케스트레이터(orchestrator)는 다섯 개의 에이전트 위에 위치하여 알람의 중복을 제거하고, 300초의 승인 타임아웃(approval timeout)을 강제합니다. 루프는 30초마다 실행됩니다. 대부분의 장애는 인간에게 도달하지 않습니다.
에이전트 1: 탐지기 (The Detector)
탐지기(Detector)는 의도적으로 단순하게 설계되었습니다. 탐지기의 역할은 생각하는 것이 아니라, 감시하고, 임계값(threshold)을 확인하고, 발화(fire)하는 것입니다.
탐지기는 네 가지 신호 유형을 모니터링합니다:
탐지기가 감시하는 것
signal_sources = [
"Kubernetes watch API를 통한 Pod 상태", # phase, restartCount, OOMKilled
...
탐지(detection)를 분석(analysis)과 분리하는 이유는 무엇일까요? 빠르고 저렴한 폴링(polling)은 심층적인 추론(deep reasoning)과는 다른 작업이기 때문입니다. 탐지기는 경고(alert) 객체를 발생시킨 후 즉시 역할을 마칩니다. 나머지 작업은 Qwen-Max가 처리합니다.
**경고 스키마 (Alert schema):**
@dataclass
class Alert:
id: str
...
오케스트레이터(Orchestrator)는 `(type, namespace, resource_name)`을 기준으로 중복을 제거합니다. 즉, 동일한 장애가 두 개의 복구 파이프라인(remediation pipelines)을 생성할 수 없습니다.
## 에이전트 2: 분석기 (The Analyzer) - Qwen-Max의 심층 추론
이 지점이 대부분의 "AI DevOps" 도구들이 멈추거나 모호해지는 구간입니다. 분석기는 전체 경고 컨텍스트(alert context)를 Qwen-Max로 보내고, 구조화된 진단 결과를 받아옵니다.
프롬프트(prompt)는 정교하게 설계되었습니다:
system_prompt = """당신은 숙련된 Kubernetes SRE입니다. 장애를 분석하고 다음을 포함한 JSON을 반환하세요:
- root_cause: 구체적인 기술적 설명
- confidence: 0.0-1.0
...
`auto_remediate` 플래그는 핵심적인 안전 장치(safety gate)입니다. Qwen-Max는 확신이 있고 리스크가 제한적인 경우에만 이를 `true`로 설정합니다. 심각한 리스크 레벨(critical risk level)은 예외 없이 항상 인간의 에스컬레이션(human escalation)으로 넘어갑니다.
여기서 제가 Qwen-Max를 높게 평가하는 이유는 다음과 같습니다: 모델이 생성하는 사고 사슬(chain-of-thought) 추론이 시니어 엔지니어가 읽기에 실제로 매우 명확하다는 점입니다. 모델은 다음과 같이 말합니다:
> _"컨테이너가 12분 동안 7번 OOMKilled 되었습니다. 메모리 제한(memory limit)은 128Mi입니다. 이것은 Java 서비스이므로 JVM 힙(heap) 설정이 잘못되었을 가능성이 높습니다. 높은 신뢰도(0.91). 메모리 제한을 256Mi로, 요청(requests)을 200Mi로 패치할 것을 권장합니다. 낮은 리스크 — 최악의 경우 동일한 제한 조건으로 재시작되는 것입니다."_
이것이 바로 운영 환경(production)을 건드리기 전에 확인하고 싶은 종류의 추론입니다.
## 에이전트 3: 플래너 (The Planner) - Qwen-Embedding을 활용한 런북(Runbooks) 기반 RAG
이 시스템을 대규모 환경에서도 실제로 유용하게 만드는 통찰은 다음과 같습니다: **어떤 장애에 대해서도 적절한 해결책은 이미 당신의 런북(runbooks) 어딘가에 존재한다는 것입니다.** 문제는 그것을 빠르고 신뢰할 수 있게 찾아내는 것입니다.
Planner는 `text-embedding-v3` (Qwen의 임베딩 모델)를 사용하여 다섯 개의 런북(runbooks)에 대한 의미론적 인덱스(semantic index)를 구축합니다:
| 런북 (Runbook) | 다루는 내용 |
| --- | --- |
| `crashloop-rollback.md` | CrashLoopBackOff: 마지막 정상 이미지로 롤백 |
| ... | |
쿼리 시점에는 다음과 같이 동작합니다:
1. Qwen-Max RCA 임베딩
query_embedding = qwen_embed(analyzer_result.root_cause + analyzer_result.reasoning)
...
의미론적 검색(semantic search)은 자연스러운 변형을 손쉽게 처리합니다. "메모리 압박으로 인해 Pod가 계속 재시작됨"과 "payment-service에서 OOMKill 루프 발생"은 모두 동일한 런북을 검색해냅니다. 취약한 키워드 매칭이나 유지보수가 필요한 규칙 엔진(rule engines)이 필요 없습니다.
## 에이전트 4: Executor (실행기) - 설계부터 안전하게
저는 다른 어떤 구성 요소보다 Executor에 더 많은 시간을 할애했습니다. 자율 실행(Autonomous execution)은 부주의할 경우 심각한 피해를 줄 수 있는 영역이기 때문입니다.
**세 가지 안전 계층 (safety layers):**
### 계층 1 - 기본값으로 Dry Run 설정
DRY_RUN=true # 명시적으로 이 값을 바꾸지 않는 한 클러스터에 아무런 영향도 주지 않음
### 계층 2 - 서킷 브레이커 (Circuit Breaker)
class CircuitBreaker:
max_failures = 3 # 3회 연속 실패 시 -> OPEN
reset_seconds = 300 # 5분 후 -> 재시도 (HALF_OPEN)
...
`kubectl` 명령이 실패하기 시작하면 (네트워크 파티션, RBAC 설정 오류 등 무엇이든), 브레이커가 열리며 모든 실행 시도를 중단합니다. 시스템은 고장 난 클러스터를 계속 두드리는 대신 인간의 검토 단계로 에스컬레이션(escalation)합니다.
### 계층 3 - 액션 화이트리스트 (Action Whitelist)
ALLOWED_ACTIONS = {
"patch_resources": patch_deployment_resources, # 메모리/CPU 제한만 허용
"rollback": execute_argocd_rollback, # ArgoCD 히스토리 롤백
...
Executor는 이 화이트리스트를 벗어나는 어떤 작업도 수행할 수 없습니다. 만약 Qwen-Max가 우리가 지원하지 않는 액션 유형을 어떻게든 환각(hallucinate)하여 생성하더라도, 시스템은 에스컬레이션 단계로 넘어갑니다.
## 에이전트 5: Escalation Agent (에스컬레이션 에이전트) - Qwen-Turbo + Human-in-the-Loop
인간의 개입이 필요할 때, Escalation Agent는 두 가지 일을 수행합니다:
1. **요약 (Summarize)** - Qwen-Turbo를 사용하여 전체 장애 컨텍스트(경고 + 근본 원인 분석 (RCA) + 복구 계획)를 간결하고 읽기 쉬운 Slack 메시지로 압축합니다. 가공되지 않은 JSON 덤프나 LLM의 장황한 설명은 배제합니다.
2. **대기 (Wait)** - 고유 토큰이 포함된 승인 요청을 보낸 후, 응답이 올 때까지 최대 300초 동안 대기합니다. 응답이 없으면 자동으로 거부됩니다. 시스템은 이를 로그로 기록하고 다음 단계로 넘어갑니다. 안전이 최우선입니다.
slack_message = {
"text": f"🚨 {alert.severity.upper()} 장애에 대한 승인이 필요합니다",
"blocks": [
...
Qwen-Turbo의 요약은 진정으로 간결합니다. 15가지의 서로 다른 장애 시나리오에서 테스트해 본 결과, 출력물은 항상 새벽 2시에 제가 보고 싶어 하는 내용이었습니다. 즉, 무엇이 고장 났는지, 왜 발생했는지, 시스템이 무엇을 하려 하는지, 그리고 제가 응답하지 않을 경우 어떤 일이 발생하는지에 대한 내용입니다.
## MCP 서버: 에이전트를 외부 AI에 노출하기
MCP (Model Context Protocol) 서버는 NeuroScale Autopilot을 조합 가능하게(composable) 만드는 핵심 요소입니다. 8개의 FastAPI 도구(tools)가 MCP를 지원하는 모든 AI 클라이언트에 전체 시스템을 노출합니다:
@app.post("/tools/get_pod_status")
async def get_pod_status(namespace: str, pod_name: str) -> PodStatus: ...
...
이는 Claude, GPT 또는 MCP 호환 에이전트가 NeuroScale Autopilot을 쿼리하고 제어할 수 있음을 의미합니다. 단 몇 시간 만에 그 위에 자연어 기반의 운영(ops) 인터페이스를 구축할 수도 있습니다.
## Alibaba Cloud ECS 통합
kubectl을 넘어, Executor는 클라우드 계층의 복구를 위해 네이티브 Alibaba Cloud ECS 클라이언트를 보유하고 있습니다:
class ECSClient:
"""aliyunsdkcore를 통한 네이티브 Alibaba Cloud ECS 클라이언트"""
...
Kubernetes 계층의 수정만으로 충분하지 않을 때(예: 노드 자체가 비정상적인 경우), 시스템은 ECS까지 접근할 수 있습니다. 이것이 바로 "클라우드 네이티브 (cloud-native)"라는 말이 실제로 의미를 갖는 수준입니다.
## 중요한 수치들
| 지표 | 값 |
| --- | --- |
| 테스트 스위트 (Test suite) | 17/17 통과 |
| ... | |
## 나를 놀라게 한 점
**임베딩 기반의 런북 (Runbook) 검색 성능이 놀라울 정도로 뛰어납니다.** 저는 파인튜닝 (Fine-tuning)이나 최소한 더 큰 인덱스 (Index)가 필요할 것이라고 예상했습니다. `text-embedding-v3`는 의도적으로 모호하게 작성된 장애 상황 설명을 포함하여, 제가 던진 모든 테스트 케이스에서 첫 번째 시도만에 정확한 런북을 찾아냈습니다.
**Qwen-Max의 리스크 평가 (Risk assessment) 방식은 올바른 방향으로 보수적입니다.** 처음에는 `auto_remediate` 임계값 (Threshold)을 대폭 조정해야 할 것이라고 생각했습니다. 하지만 실제로 사용해 보니, 모호함이 조금이라도 있을 때는 에스컬레이션 (Escalation, 상위 보고)하는 쪽을 택했습니다. 이는 프로덕션 (Production) 환경에서 정확히 요구되는 동작입니다.
**서킷 브레이커 (Circuit breaker)가 가장 무서운 실패 모드 (Failure mode)를 방지합니다.** 초기 테스트 중에 `kubectl` 설정이 잘못되어 모든 실행 시도가 실패하는 시나리오가 있었습니다. 서킷 브레이커가 없었다면 시스템은 동일한 실패 명령을 수백 번이나 실행했을 것입니다. 하지만 서킷 브레이커 덕분에 세 번의 실패 후 실행을 중단하고, 에스컬레이션을 수행한 뒤 대기했습니다. 이것이 자동화 도구와 자동화 재앙의 차이입니다.
## 다음에 구축할 것들
- **실제 Prometheus 연동** - 현재 버전은 모의 메트릭 프로바이더 (Mock metrics provider)를 사용합니다. 실제 PromQL 클라이언트를 도입하는 것이 명확한 다음 단계입니다.
- **런북 자동 생성** - Qwen-Max에게 과거의 장애 해결 사례로부터 새로운 런북을 생성하도록 요청합니다. 시스템이 학습함에 따라 인덱스가 성장하게 됩니다.
- **멀티 클러스터 (Multi-cluster) 지원** - 현재 아키텍처는 단일 클러스터 기준이지만, 환경 간 (dev/staging/prod) 연합 (Federation) 기능을 추가하는 것은 간단합니다.
- **Grafana 플러그인** - 에이전트 상태와 장애 이력을 네이티브 Grafana 패널로 시각화합니다.
- **SRE 데이터를 활용한 Qwen 커스텀 파인튜닝 (Fine-tune)** - 실제 장애 사후 분석 (Post-mortem) 데이터를 사용하여 도메인 특화 파인튜닝을 진행하면, 근본 원인 분석 (RCA, Root Cause Analysis)의 품질이 '우수함'에서 '독보적임' 수준으로 올라갈 것입니다.
## 시도해 보기
git clone https://github.com/sodiq-code/neuroscale-autopilot.git
cd neuroscale-autopilot
cp .env.example .env
...
에이전트는 드라이 런 (Dry-run) 모드로 시작됩니다. `DRY_RUN=false`로 설정하기 전까지는 클러스터에 아무런 영향을 주지 않습니다. 로그를 지켜보세요. 첫 1분 이내에 시뮬레이션된 장애에 대해 전체 파이프라인 (Pipeline)이 작동하는 것을 볼 수 있습니다.
- **데모 영상 (2:44):** [https://youtu.be/ARVD_QFKXGw](https://youtu.be/ARVD_QFKXGw)
- **전체 소스 코드:** [https://github.com/sodiq-code/neuroscale-autopilot](https://github.com/sodiq-code/neuroscale-autopilot)
## 마치며
새벽 2시에 울리는 페이저 (Pager)는 자연의 법칙이 아닙니다. 그것은 자동화 (Automation)의 실패입니다.
사람을 깨우는 모든 장애 (Incident)는 시스템이 처리했어야 할 장애입니다. 사람이 불필요하기 때문이 아니라, 사람의 판단은 비용이 많이 들고, 새벽 2시에는 판단력이 저하되며, 이미 해결책이 알려진 문제에 낭비되기 때문입니다.
NeuroScale Autopilot은 알려진 해결책들을 처리합니다. 사람은 그 외의 것들을 처리합니다. 그것이 실제로 확장 가능한 (Scalable) 분업 방식입니다.
_Qwen Cloud Global AI Hackathon - Track 4: Autopilot Agent를 위해 제작되었습니다._
_Sodiq Jimoh - DevOps / Cloud Engineer_
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기