Kyunghoon

Infrastructure · Systems · Reliability

Kyunghoon Kim — Portfolio

Kubernetes 장애 분석, 클라우드 자원 관리, VM 자동화 프로젝트에서 해결한 문제와 검증 결과를 정리했습니다.

01 / 2026

Agent-based Kubernetes RCA

장애 원인 분석과 근거 검증

LLM Agent가 Kubernetes 데이터를 조회해 장애 원인을 조사하고, 별도 검증 단계에서 그 결론이 수집한 기록으로 뒷받침되는지 확인하는 도구입니다. 근거가 부족하면 원인을 단정하지 않고 판단을 유보합니다. 조사 결과는 운영자가 검토할 수 있는 보고서로 남깁니다.

구현
리소스 관계·상태 이력 저장, 조사 대상 점수화, Agent 가설 비교, 보고서 근거 검증
기술
Kubernetes · Python · Neo4j · PostgreSQL · Prometheus · Loki · OpenTelemetry

왜 리소스 관계와 당시 상태를 함께 저장했나

서비스에 오류가 나타나도 원인은 연결된 Pod의 종료, 참조하는 ConfigMap의 누락, 배포 변경 등에 있을 수 있습니다. 로그나 메트릭을 따로 보면 어느 리소스의 어떤 상태가 같은 장애에 해당하는지 연결하기 어렵습니다. 조사 중 Pod가 재생성되면 현재 상태만으로는 장애 당시 상황을 확인하기도 어렵습니다.

그래서 리소스를 노드로, 소유·참조·배치 관계를 연결선으로 표현한 그래프(StateGraph)를 구성했습니다. 상태와 관계에는 유효 시간 구간과 근거 기록의 식별자를 남깁니다. 관계를 따라 조사할 대상을 찾고 이력을 보존하기 위해 Neo4j를 사용하고, 장애 접수·작업 큐·증거·보고서는 PostgreSQL에 저장하도록 역할을 나눴습니다.

조사 순서를 정한 뒤, 장애 시간대의 관계와 근거를 고정해 Agent에 전달
  1. 장애 접수·증거 수집
  2. KRCA 서비스 후보 점수화
  3. StateGraph 관계 탐색
  4. 조사 자료 고정
  5. Agent 가설 비교
  6. 근거 검증·보고

조사 대상 선정부터 원인 검증까지

  • 검증한 관측 기록으로 그래프 구성. 수집한 데이터의 대상·시간대·출처를 확인한 뒤, Deployment–ReplicaSet–Pod의 소유 관계나 Pod의 ConfigMap 참조 관계로 변환합니다. Kubernetes 리소스는 UID로 구분해 이름이 같아도 재생성된 Pod를 이전 Pod와 혼동하지 않도록 했습니다.
  • 점수는 먼저 조사할 서비스를 정하는 데 사용. KRCA 방식의 API 호출 관계 분석을 적용해 오류율의 상관관계와 응답 지연의 이상 정도·변동 기여도·상관관계를 점수화합니다. 상위 서비스 주변을 그래프 탐색의 시작점으로 삼되, 지표가 부족하면 알림이 발생한 리소스에서 조사를 시작합니다. 이 점수 자체가 장애 원인이나 원인일 확률을 뜻하지는 않습니다.
  • Agent가 본 자료를 고정. 장애 시간대와 탐색 깊이·리소스 수를 제한하고, 선택된 관계·상태·증거와 수집 실패·누락 정보를 하나의 조사 자료(Frozen Context)로 저장합니다. 이후 클러스터 상태가 바뀌어도 어떤 자료로 결론을 내렸는지 확인할 수 있습니다.
  • Agent의 가설과 최종 판정을 분리. LLM에는 선택된 증거를 조회하며 원인 가설의 순위, 지지·반박 근거, 추가로 필요한 정보를 정리하도록 맡겼습니다. 설명이 그럴듯하다는 이유만으로 원인을 인정하지 않도록 별도 검증 단계(Evidence Gate)가 인용한 증거와 원인별 필수 조건을 검사합니다. 근거가 부족하면 판단을 유보하고, 시스템 변경은 수행하지 않습니다.
그래프 스냅샷·점수 계산·OOM 진단 예시

그래프에는 매번 전체 상태를 복사하는 대신, 같은 상태가 이어지면 기존 시간 구간을 연장하고 상태가 바뀌면 이전 구간을 닫아 새 구간을 만듭니다. 리소스 간 관계도 존재했던 기간을 기록합니다. 이 그래프에서 장애 시간대에 해당하는 일부를 선택해 고정한 것이 Agent가 읽는 조사 스냅샷입니다.

KRCA 오류율 점수에는 통계적 유의성 검사를 통과한 양의 상관관계를 사용합니다. 지연 점수는 이상 정도·변동 기여도·양의 상관관계의 가중합이며, 두 점수 중 큰 값으로 호출 경로의 탐색 여부와 서비스 후보 순서를 정합니다. 이는 Agent가 작성하는 가설 순위·신뢰도와 별개이고, 어느 쪽도 점수만으로 원인을 확정하지 않습니다.

통제된 OOM 실험에서는 같은 Pod UID에 연결된 Kubernetes의 OOMKilled·종료 코드 137, Prometheus의 재시작 증가, Loki의 커널 메모리 부족 기록을 함께 확인했습니다. Agent가 인용한 기록을 보고서에서 추적할 수 있도록 했습니다. 이 근거로 확인한 것은 메모리 제한에 의한 종료이며, 애플리케이션 내부의 메모리 누수까지 밝혀낸 것은 아닙니다.

증거를 찾았는데도 보고서가 거절되는 이유

Agent의 설명이 그럴듯해도 증거가 다른 Pod의 기록이거나 조사 범위를 벗어나면 신뢰하기 어렵습니다. 반대로 증거가 충분해도 Agent와 검증 계층의 판정 기준이 다르면 유효한 보고서가 거절될 수 있습니다.

모델·도구·검증 계층 사이의 오류 수정

최초 20회 실험 중 장애 원인 또는 판단 유보가 사전에 정한 기준과 일치한 것은 9회였습니다. 실행 기록을 확인하니 Agent가 긴 증거 식별자(Evidence ID)를 잘못 옮겨 적거나, 과거 이벤트가 조사에 섞이는 문제가 있었습니다. 필수 정보가 모두 수집됐는지 확인하는 기준도 검증 단계에만 있고 Agent에는 전달되지 않았습니다.

  • 긴 식별자를 다시 쓰지 않도록 변경. Agent에는 E1 같은 짧은 번호를 제공하고, 도구가 이를 원래 증거 식별자와 연결하도록 했습니다.
  • Agent와 검증 단계에 같은 기준 적용. 조사 대상 리소스와 장애 발생 시간대에 해당하는 이벤트만 사용하도록 제한했습니다. 수집 실패나 필수 정보 누락 시 결론을 내릴 수 있는 기준도 Agent에 전달했습니다. 평가 코드에서는 근거 없는 가설을 원인으로 세던 조건을 수정했습니다.
  • 작업을 넘긴 이전 worker의 저장 차단. 작업 처리 권한을 잃은 worker가 뒤늦게 결과를 저장하지 못하도록, 권한 확인과 결과 저장을 하나의 트랜잭션에서 처리했습니다. 중단된 작업의 복구와 저장 실패 시 변경 취소를 PostgreSQL 통합 테스트로 검증했습니다.

실험 결과 / 수정 전후 각 20회

사전 평가 기준과 일치한 실행 9/20 → 20/20. 단순 장애 3종과 장애가 없는 상태를 각각 5회 평가했습니다. 검증 기준을 낮추거나 기존 실패를 성공으로 바꾸지 않고, 수정된 프로그램으로 실험을 다시 실행했습니다.

한 테스트 환경에서 미리 정한 시나리오로 얻은 결과입니다. 실제 운영 환경의 진단 정확도나 평균 복구 시간(MTTR) 개선은 측정하지 않았습니다. 후속 12회 재실험에서는 보고서 출력 형식을 지키지 못한 1건을 제외한 11건이 평가 기준과 일치했습니다.

평가 지표와 후속 실패 기록
메모리 부족(OOM)·이미지 다운로드 실패·ConfigMap 누락·장애가 없는 상태
지표수정 전수정 후
사전 평가 기준과 일치한 실행9/2020/20
첫 번째로 제시한 원인이 정답인 실행4/1515/15
장애가 없을 때 원인 판단 유보5/55/5

Agent에는 정답을 제공하지 않았습니다. Agent 코드, 보고서 검증 로직, 평가 코드의 오류를 함께 고친 뒤 같은 시나리오를 다시 실행해 비교했습니다. LLM 없이 정해진 규칙으로 판단하는 비교 프로그램도 같은 20회 실험에서 모두 평가 기준을 만족했습니다.

같은 장애 유형에서 조건을 바꾸고, 수정 과정에 사용하지 않은 12개 사례도 평가했습니다. 첫 실행은 12/12, 같은 조건으로 다시 실행했을 때는 11/12가 기준과 일치했습니다. 실패한 1건은 올바른 증거를 인용했지만 정해진 출력 형식을 지키지 않아 보고서가 거절됐습니다.

현재 평가는 미리 정한 단순 장애와 그 변형을 대상으로 했습니다. 규칙 기반 방식 대비 LLM의 효과와, 여러 원인이 겹치거나 평가에 없던 장애에 대한 대응 능력은 추가 검증이 필요합니다.

02 / 2026 · 팀 프로젝트

Cantaloupe

Hybrid Kubernetes FinOps

AWS·GCP·온프레미스의 비용과 자원 사용량을 한곳에서 확인하고, 서비스 품질을 살피면서 불필요한 자원을 줄이는 프로젝트입니다.

담당
AWS 인프라, 작업량에 따른 Worker 확장·회수, 자원 사용량·처리 결과 측정
기술
Kubernetes · AWS · Terraform · Ansible · Argo CD · KEDA · Karpenter

작업이 없을 때도 남아 있는 자원

오디오 변환은 평소와 요청이 몰릴 때 필요한 자원량이 다릅니다. 최대 부하에 맞춰 Worker를 항상 유지하면 사용하지 않는 자원이 생깁니다. Pod의 CPU·메모리 요청량을 낮춰도 실제 노드가 계속 실행 중이면 노드 비용은 남습니다.

플랫폼에서는 OpenCost와 공통 가격 기준으로 비용을 비교합니다. VPA가 권고한 CPU·메모리 요청량과 실제 사용량을 검토하고, 변경값을 Git에 반영해 배포합니다. 저는 AWS에서 작업량에 맞춰 처리 자원을 늘리고, 작업 종료 후 추가 자원이 실제로 삭제되는 과정에 집중했습니다.

평소에는 기본 Worker가 처리하고, 작업이 몰리면 추가 Worker 사용
  1. SQS 대기 작업 증가
  2. KEDA: 추가 Worker Pod 생성
  3. Karpenter: EC2 생성
  4. 작업 완료·Pod 축소
  5. 빈 노드 회수

Worker 요청량, 노드 배치, 작업 후 회수를 함께 조정

  • 작업이 몰릴 때만 Worker와 노드 추가. 기본 Worker(Base)와 추가 Worker(Burst)를 분리하고, 추가 Pod를 배치할 노드의 생성·초기화까지 연결했습니다. 대기열이 비면 EC2 인스턴스, EBS 볼륨, 노드 관리 객체(NodeClaim)가 함께 정리되는지 검증했습니다.
  • 같은 작업량을 더 적은 노드에 배치. Worker의 CPU·메모리 요청량과 Karpenter가 계산하는 노드당 Pod 수용량을 조정했습니다. Pod 수용량은 실제로 사용하는 Calico 네트워크 환경에 맞췄습니다.
  • 작업 결과와 측정 누락을 따로 확인. 작업이 완료됐는지, 필요한 메트릭이 빠짐없이 수집됐는지, 두 실행의 조건이 비교 가능한지를 각각 판정했습니다. 메트릭 누락만으로 작업 자체가 실패했다고 판단하지 않도록 했습니다.

실험 결과 / 같은 150건의 작업으로 비교

150건을 모두 처리하고, 작업 후 추가 노드를 전부 회수했습니다. 설정 변경 후에는 추가 Worker Pod 6개를 노드 1대에 배치했습니다. 변경 전에는 같은 작업량을 처리할 때 추가 노드를 최대 2대 사용했습니다.

작업 완료와 노드 배치·회수는 확인했습니다. 다만 메트릭 일부가 누락돼 처리시간이 유지됐는지는 확정하지 못했고, 실제 청구액이 얼마나 줄었는지도 검증하지 않았습니다.

실험 조건과 측정 한계

같은 150건의 작업을 설정 변경 전(Baseline)과 변경 후(Candidate)에 실행하고, 각 실행에서 수집한 값을 정리했습니다. 연결한 실험 문서에는 조건과 판정 기준을 설명했으며, 원본 실행 기록은 공개하지 않았습니다.

설정 변경 전후 실행 기록
측정 항목변경 전변경 후
처리 완료 상태(READY)150/150150/150
추가 노드의 최대 수2대1대
종료 후 추가 노드0대0대
완료 건수 메트릭의 증가량139144

Worker의 CPU·메모리 요청량은 250m·256Mi에서 50m·160Mi로 조정했고, 변경 후 메모리 상한(limit)은 512Mi로 유지했습니다. 요청량과 노드당 Pod 수용량을 함께 바꿨기 때문에 어느 한 설정만으로 노드가 줄었다고 단정할 수는 없습니다.

두 실행 모두 처리 완료 상태는 150건이지만 완료 건수 메트릭의 증가량은 이에 못 미쳤습니다. 따라서 측정값이 빠짐없이 수집됐다고 볼 수 없습니다. 메트릭 누락을 해결한 뒤 반복 비교하고 실제 청구 자료와 대조하는 검증이 남아 있습니다. 부하가 짧으면 추가 노드가 준비되기 전에 작업이 끝날 수도 있습니다.

03 / 2026.06–07 · 팀 프로젝트

Clover — OpenStack Worker Automation

목표 VM 수에 따른 생성·삭제와 Docker Swarm 등록

OpenStack 기반 클라우드 플랫폼 팀 프로젝트에서 네트워크·보안 그룹 등 VM에 필요한 자원 구성과 Worker VM의 생성·초기화·Swarm 등록 자동화를 담당했습니다.

담당
OpenStack 기반 자원 구성, 목표 VM 수 조정, Worker 초기화·등록
기술
OpenStack · Kolla-Ansible · Ansible · cloud-init · Docker Swarm

VM 생성만으로 끝나지 않는 Worker 추가

Worker를 추가하려면 VM 생성 이후에도 네트워크 연결, Docker 설치·기동, Swarm 등록이 필요합니다. VM 수가 바뀔 때 이 절차를 반복하지 않도록, 목표 수량을 입력하면 현재 상태와 비교해 필요한 작업을 수행하는 흐름으로 구성했습니다.

Ansible 실행 시 목표 수량과 현재 VM 목록 비교
  1. 목표·현재 VM 비교
  2. 부족한 VM 생성
  3. Floating IP 할당
  4. cloud-init 완료 확인
  5. Swarm 등록
  6. 초과 VM 삭제

자원 구성과 초기화 순서를 코드로 관리

  • 생성·삭제할 VM을 현재 목록과 비교해 결정. 이름 접두어로 관리 대상 VM을 구분하고, 필요한 VM 목록과 현재 목록의 차이를 계산했습니다. 이미지·VM 사양(Flavor)·네트워크·라우터·보안 그룹 구성도 Ansible Playbook으로 작성했습니다.
  • Docker 준비가 끝난 뒤 Swarm에 등록. cloud-init으로 Docker를 설치·기동하고 초기화 완료를 표시합니다. Ansible은 Floating IP를 할당하고 초기화 완료를 확인한 뒤 Swarm에 등록합니다. 기본 실행에서는 이미 참여한 노드를 다시 등록하지 않습니다.
  • 실행마다 바뀌는 설정을 입력값으로 분리. 실행 스크립트에 목표 VM 수·이름 접두어·VM 사양을 전달하도록 했습니다. Swarm 참여에 필요한 Join 토큰은 별도 변수 파일에서 읽도록 구성했습니다.

구현 결과

목표 수량에 따른 VM 생성·삭제와 Worker 초기화·등록을 하나의 실행 흐름으로 연결했습니다. VM마다 명령을 따로 실행하던 절차를 Playbook과 실행 스크립트로 관리할 수 있도록 구성했습니다.

공개 코드에서 확인한 구현 내용입니다. 부하에 따라 목표 VM 수를 자동으로 정하는 기능은 포함하지 않으며, 시간 단축이나 반복 실행 성공률도 측정하지 않았습니다. VM을 삭제하기 전에 새 작업 배치를 막고 기존 작업을 다른 노드로 옮기는 절차(Swarm drain), Swarm에 남은 노드 등록 정보 정리는 추가 보완이 필요합니다.