Durable Analysis Pipeline과 검증된 이미지로 운영 경계를 닫기
Evidence 저장과 분석을 DB task로 분리하고 lease·retry·outbox를 적용한 뒤, CI를 통과한 이미지와 SBOM·취약점 게이트까지 연결한 마무리 과정을 정리했습니다.
Evidence 저장과 분석을 같은 요청에서 처리하던 문제
초기에는 Agent가 Evidence를 전송하면 API 요청 안에서 바로 RCA 분석을 수행했다. 기능이 늘어나고 선택적 LLM 호출, Incident correlation과 알림이 추가되면서 이 구조의 한계가 보였다.
- 분석이 길어지면 Agent 응답도 늦어진다.
- Platform이 중간에 재시작되면 저장과 분석 상태를 구분하기 어렵다.
- 여러 Instance가 같은 Evidence를 중복 처리할 수 있다.
- Report는 저장됐지만 Notification이 빠지는 부분 성공이 생길 수 있다.
- 실패 작업을 운영자가 확인하고 재시도하기 어렵다.
그래서 Evidence 수신과 RCA 분석을 DB 기반 Durable Task로 분리했다.
Durable Analysis Task 흐름
Evidence 수신
→ Evidence와 Analysis Task를 같은 Transaction으로 저장
→ Worker가 조건부 UPDATE로 Lease 획득
→ Rule-based와 선택적 LLM 분석
→ Incident·Report·Job·Notification Outbox 저장
→ Task Completed를 같은 Transaction으로 Commit
Evidence ID에는 Unique 제약을 둬 Evidence 하나당 Task가 하나만 생기도록 했다. Worker는 lease_owner, 만료 시각과 attempt_count를 함께 사용한다.
처리가 긴 경우 Lease의 1/3 주기로 Heartbeat를 갱신한다. Instance가 종료되면 갱신도 멈추고, Lease가 만료된 작업을 다른 Instance가 회수한다.
Stale Worker의 Commit 막기
가장 조심한 경우는 다음과 같다.
Worker A가 Lease 획득
→ 처리 지연
→ Lease 만료
→ Worker B가 같은 Task 회수
→ Worker A가 늦게 Commit 시도
완료 UPDATE에서 Lease Owner와 Attempt Count를 다시 확인한다. 값이 바뀌었으면 Incident를 포함한 Transaction 전체를 Rollback한다. 오래된 Worker가 새 결과를 덮어쓰는 것을 막는다.
분석 실패는 retry_wait로 전환하고 지수 Backoff 후 다시 시도한다. 최대 횟수를 넘으면 dead_letter로 이동한다. Web Console의 Pipeline 화면에서 상태와 오류를 확인하고 수동으로 Queue에 다시 넣을 수 있다.
Notification Outbox를 같은 Transaction에 넣기
Report 저장 후 Slack이나 Webhook을 바로 호출하면 외부 호출 성공 여부와 DB 상태가 갈릴 수 있다. 그래서 알림 요청도 Outbox Record로 먼저 저장한다.
Incident, Report, Job, Notification Outbox와 Task 완료는 하나의 Transaction 경계에 있다. 별도 Worker가 Outbox를 전달하고 재시도한다.
Commit 이후 Audit 또는 Metric 기록 실패는 완료된 분석을 다시 실행하지 않는다. 대신 전용 Metric과 경고 Log로 관측한다. 중복 Incident를 만드는 것보다 후처리 실패를 별도로 복구하는 편이 안전하다.
코드가 아니라 검증된 이미지까지 전달하기
운영 가능한 Pipeline이 완성된 뒤에는 어떤 Image가 이 계약을 실행하는지도 중요해졌다. Supply Chain Gate를 다음처럼 구성했다.
- Secret Scan
- Dependency Review
- Trivy Filesystem·Image Scan
- Repository와 Image SBOM
- Grype SBOM Scan
- Java·Python CodeQL
- Platform·Agent Image Build
수정 가능한 High와 Critical 취약점, 실제 Secret 탐지는 CI를 차단한다. Medium과 Low는 숨기지 않고 Artifact와 Code Scanning에 남겨 Triage한다.
main의 CI가 성공한 Commit만 edge와 sha-<commit> Image로 발행한다. 운영 배포에는 이동하는 edge보다 SHA Tag나 Digest를 사용한다. Release에서는 Multi-architecture Image, SBOM과 Keyless Cosign Signing을 추가한다.
마지막 검증 상태
현재 기준으로 Frontend, Agent, Spring Boot, PostgreSQL·MariaDB, Playwright, Helm, 3노드 Kind, Prometheus Operator 전달과 Image Build Gate를 통과했다. Security와 Edge Image 발행도 같은 Commit에서 확인했다.
하지만 남은 범위도 명확하다.
- 24시간 Production Fleet
- EKS·AKS·GKE·OpenShift 실제 Canary
- 더 많은 실제 장애 Corpus
- 충분한 LLM Burn-in 표본
이번 단계에서 배운 점
운영 플랫폼의 완성도는 기능 개수보다 실패 경계를 어떻게 닫았는지에 가깝다.
중복 분석을 막는 Lease와 Fence
부분 성공을 막는 Transaction과 Outbox
복구 가능한 Retry와 Dead Letter
검증을 통과한 Commit만 Image로 전달하는 CI
Artifact와 한계를 함께 남기는 문서
RCA 결과의 안전성뿐 아니라 그 결과를 만드는 Software Supply Chain까지 같은 기준으로 관리해야 한다는 점을 확인했다.
프로젝트 저장소: Kubernetes Cluster Infra RCA Platform