CASE FILES / DEVOPS ENGINEER
진행중 · ONGOING
DevOps / Cloud Infrastructure Engineer

이국성

약 7년간 쌓아온 인프라 사건 기록 — 가이온 → 키즈노트 → 천재교육

한 지점의 장애가 전체 서비스로 번지지 않도록,
구조로 안정성을 설계한다.

사건 번호 CASE-2019—PRESENT github.com/noah2byte noah2byte.github.io linkedin
FILE 00 — 수사관 프로필

나는 어떤 문제를 해결해온 엔지니어인가

무역 데이터 플랫폼의 인프라를 다룬 가이온, CI/CD를 통합한 카카오 계열 SaaS 키즈노트, 그리고 AI 디지털교과서(AIDT) LMS를 운영하는 천재교육 클라우드인프라팀. 업무 내용은 매번 달랐지만, 실제로 매 순간 던진 질문은 하나로 수렴했다.

“이 컴포넌트 하나가 지금 죽으면, 서비스는 계속 살아있는가?”

이 질문은 AI 대학원에서 NLP를 전공하며 데이터의 무게를 배운 시절부터 시작됐다. 2022년 판교 데이터센터 화재 직후 카카오 계열사인 키즈노트에 합류하면서 신념으로 굳어졌고, 천재교육에서는 구조적인 문제 해결로 확장됐다 — 9시간짜리 배포를 병목 단위로 뜯어 10분으로 줄이고, 월 2~3회 반복되던 장애를 아키텍처 전환으로 근절하고, 원인 특정이 안 되는 성능 지연 앞에서 관측 가능성의 한계 자체를 데이터로 증명하는 방식으로.

  • 도구보다 구조를 먼저 본다 — 장애가 반복되면 설정이 아니라 설계를 의심한다.
  • 성과 수치보다 재현 가능성을 먼저 본다 — 한 번 된 것이 아니라 다시 해도 되는지를 확인한다.
  • 모르는 것을 아는 척하지 않는다 — 원인을 특정하지 못했을 땐 못했다고 쓰고, 그 과정에서 드러난 한계를 남긴다.
FILE 01 — 사건 연대기

기술적 성장 방향

연차순 나열 대신, 다뤄온 문제의 층위가 넓어져 온 순서로 정리했다.

ON-PREMISE
키즈노트 (2022~)

카카오 IDC 기반 온프레미스 환경에서 iOS/Android/프론트/백엔드 CI/CD를 Jenkins Scripted Pipeline으로 통합, 수동 배포를 100% 자동화. 도입을 거부하던 개발자들은 강요 대신 객관적 지표로 설득했고, 이후 합류한 동료 엔지니어를 위해 파이프라인 복잡도를 함께 낮춰 특정 인원에 의존하지 않는 구조로 만들었다.

CI/CD
천재교육 (2024~)

AIDT LMS 배포 파이프라인을 병목 단위로 재설계 — 배포 시간 9시간 → 10분.

KUBERNETES
천재교육

Jenkins를 K8s 위에 재구축(일회용 에이전트 파드), GitLab을 Omnibus에서 Helm 기반 K8s 운영으로 전환.

CLOUD
천재교육

AWS에서 NCP로 전환된 인프라를 운영, NCP 고유의 관측 가능성 한계를 실제 장애 대응으로 체득.

DEVSECOPS
천재교육 (2024~2025, 완료)

Spring Config Server → ConfigMap/Secret → Vault Agent Injector로 백엔드 시크릿 관리 방식을 단계적으로 전환, CI/CD 파이프라인에 실제로 녹여냄.

GITOPS / IAC
천재교육 (2026~)

Jenkins 중심 배포를 ArgoCD 기반 GitOps로 단계적 전환(PoC 진행 중).

개인 프로젝트
2023~2025년 초

Terraform 기반 IaC 패턴 기술서를 번역하며 코드 예제를 직접 실행·검증. 회사 업무와 별개로 키즈노트 재직 중 시작해 천재교육 재직 중 완성.

OBSERVABILITY
천재교육

인수인계 없는 kube-prometheus-stack/Mimir/Loki 스택을 커밋 히스토리로 역추적, NCP의 관측 가능성 격차를 벤더 대응까지 포함해 직접 규명.

PLATFORM ENGINEERING
천재교육 (진행 중)

부서별로 흩어진 SVN/CodeCommit/SourceCommit/GitLab을 전사 공용 GitLab으로 통합하는 프로젝트에 참여 — 현재 방향 논의 단계.

FILE 02 — 대표 사건
CASE No. 01 · AIDT LMS

배포 9시간의 기록 — 병목을 구조로 뜯어내다

해결 · CLOSED
KubernetesJenkinsCI/CD 표준화가용성
발단

프론트+백엔드 전체 배포에 약 9시간. Jenkins는 월 5~6회 OOM으로 완전히 다운되고, 배포 후엔 매번 수동으로 HPA를 조정해야 했다.

전체 조사 기록
현장 · CONTEXT

AIDT 서비스 특성상 학교급×학년×과목×학기×저자 조합으로 총 46개 교과목이 각각 별도 K8s 네임스페이스로 운영됐다. 배포 스크립트는 이 46개를 직렬로 순차 처리하고 있었고, Jenkins는 단일 인스턴스로 이 부하를 전부 감당했다.

조사 · ANALYSIS

병목이 도구가 아니라 구조에 있다고 판단 — 46개 직렬 처리, 46회 중복 빌드, 단일 인스턴스(SPOF), 배포 후 수작업, 네 겹의 병목이 겹쳐 있었다. 겹의 수만큼 해법을 설계해야 한다는 게 결론이었다.

해결 · SOLUTION
  • Jenkins를 Kubernetes 위에 재구축 — 빌드마다 일회용 에이전트 파드로 격리(numExecutors:0, request=limit), 컨트롤러 상태는 PVC로 영속화.
  • 파이프라인을 2단 parallel로 병렬화하고 “1회 선빌드 + 커밋 해시 재사용” 캐시로 46회 중복 빌드를 1회로 축소.
  • HPA·LimitRange를 배포 헬름 차트에 편입해, 배포 자체가 곧 완결된 상태 선언이 되도록 재설계.
담당자 메모

병목 구조 분석부터 재구축·병렬화·캐시 전략 설계, Helm 편입까지 전 과정을 직접 수행함.

결과 · RESULT
BEFORE
9시간
AFTER
약 10분
  • Jenkins 전면 다운(월 5~6회) 완전 소멸, 배포 후 수동 HPA 조정 절차 제거.
  • 정량 지표 밖의 변화 — 배포 신뢰도가 회복되며 개발팀·운영팀과의 협의 방식이 개선됨.
후속 조치

배포 시간이 줄자 스테이징 배포 요청 빈도가 늘면서, 병목이 "배포 시간"에서 "요청 처리"로 형태를 바꿔 남았다. 이를 풀기 위해 스테이징 배포에 한해 개발팀이 이력 추적과 함께 직접 배포할 수 있는 배포 API 서버를 구축 — 인프라팀에 매번 요청하지 않아도 되도록 권한을 위임했다.

미결 사항 환경 분기(stg05/stg06/prod05/prod08 등) 로직이 스크립트 곳곳에 흩어져 있고, 하드코딩 토큰이 일부 남아 있음 — 다음 리팩터링 대상으로 인지.
CASE No. 02 · GitLab

반복되는 장애 신고 — Omnibus에서 Helm으로

해결 · CLOSED
KubernetesGitLab변경관리가용성
발단

월 2~3회 장애 — /dev/shm 메트릭 캐시로 인한 디스크 풀, 백업 데이터 적재로 인한 PostgreSQL 장애 등. 여기에 하이퍼바이저가 XEN에서 KVM으로 전환되며 클러스터 재생성까지 겹쳤다.

전체 조사 기록
현장 · CONTEXT

NCP Kubernetes 기반 GitLab, 기존 구성은 Redis/PostgreSQL/MinIO가 모두 결합된 Omnibus 단일 인스턴스 구조. 구조 개선을 팀에 제안해 승인받고 방학 기간에 마이그레이션을 수행했다.

조사 · ANALYSIS

반복 장애의 원인을 개별 이벤트가 아니라 컴포넌트가 한 덩어리로 결합된 Omnibus 구조 자체로 특정, 컴포넌트 분리와 Helm 전환을 핵심 목표로 설정.

해결 · SOLUTION
  • 16.6.1 → 18.0.1까지 마이너 버전 단계적 업그레이드 후 Helm 전환, 이후 19.2.1까지 지속 업그레이드.
  • 19.0 대규모 변경(내장 컴포넌트 제거)에 맞춰 PostgreSQL·Redis·MinIO 분리 구축 (매니지드 전환은 비용 문제로 이번 범위에서 제외).
  • PostgreSQL 제약조건 위반, MinIO 시크릿 불일치, Gateway API CRD 누락으로 인한 cert-manager 장애, PostgreSQL 16→17 trust-mode 우회 처리 등 순차 해결.
  • SMTP 사용 불가 환경에 맞춰 NCP Outbound Mailer 변환 릴레이 서버를 Python으로 직접 구현.
담당자 메모

장애 원인 분석과 개선 제안부터 6개월간의 업그레이드·마이그레이션 실행, 각 단계 실제 장애 트러블슈팅까지 직접 수행함.

결과 · RESULT
  • 마이그레이션 이전 반복되던 장애 유형이 재발하지 않는 무중단 운영 실현.
  • 개발자들이 GitLab 플랫폼과 인프라팀을 다시 신뢰 — 6개월 개선 작업 중 ROI가 가장 큰 항목으로 평가.
미결 사항 CE 버전이라 Duo 등 AI 기능 사용 불가, GitLab Runner 성능은 GitHub Actions 대비 계속 검증 중.
CASE No. 03 · NCP / Jenkins

그날, 빌드가 5배 느려졌다

미확정 · UNRESOLVED
Observability장애 분석NCP
발단

백엔드 서비스 빌드 시간이 평소 1~2분에서 6분 28초로 급증. 에러 로그는 한 줄도 없이 “그냥 느려진” 상태.

전체 조사 기록
조사 · ANALYSIS
  • 동일 소스를 로컬에서 빌드해 정상 종료 확인 → 코드 문제 배제.
  • Jenkins 콘솔 로그의 구간별 타임스탬프를 과거 정상 빌드와 대조.
  • NAS 사용률 3%(200G 중 4.4G) 확인해 용량 문제 배제, 과거엔 있었던 디스크 사용률 알람이 현재 미설정 상태임을 발견.
  • 팀 TA와 함께 NCP 콘솔 지표만으로 원인 특정이 안 돼 네이버클라우드에 직접 문의 — 벤더 회신 주간 성능 그래프(IOPS·Latency·Throughput)에서도 특이점 없음.
  • 별도 발견한 kubectl cp 지연에 대해 “NAS 읽기 자체가 느리다”는 가설을 자체 벤치마크(tar 1.666초 vs cp -r 18.3초, 동일 1,638개 파일)로 재검증해 스스로 뒤집음.
담당자 메모

가설 수립부터 벤더 대응 조율, 검증용 벤치마크 설계까지 트러블슈팅 전 과정을 주도함.

결과 · RESULT — 있는 그대로

단일 장애의 근본 원인은 끝내 확정하지 못했다. 대신 “NCP는 디스크 사용률 알람은 제공하지만 IOPS·Latency 등 처리 성능 지표는 제공하지 않는다”는 구조적 관측 가능성 격차를 AWS EFS의 CloudWatch 지표(PercentIOLimit 등)와 대비해 팀 문서로 정리, 인프라 선택·모니터링 설계의 근거 자료로 남겼다.

CASE No. 04 · aidt-api-lm

배포 권한의 이관 — Jenkins에서 ArgoCD로

진행중 · IN PROGRESS
ArgoCDGitOps변경관리
발단

배포가 전적으로 Jenkins 스크립트의 values override에 의존 — 변경 이력이 Git이 아닌 Jenkins 잡 로그에만 남고, 실제 클러스터 상태가 선언된 상태와 어긋나도 감지할 방법이 없다.

전체 조사 기록
조사 · ANALYSIS

기존 젠킨스 override 로직을 전수조사해 정적/동적 값을 분류. 값 구조를 공통/도메인/이미지 4단 values로 재설계하고, 클러스터 토폴로지(도메인별 물리적으로 다른 클러스터)를 재확인.

해결 · SOLUTION
  • argo-helm 포크로 vendoring, AppProject/Application 구조 설계.
  • 젠킨스는 “빌드 → 이미지 푸시 → 이미지 태그 Git 반영”까지만 담당하도록 역할 축소.
  • ApplicationSet(list generator)으로 전환, 동기화 실패 시 Jira 자동 티켓 연동.
담당자 메모

설계부터 구현까지 단독 담당 — 릴리즈 편입 시 meta.helm.sh 어노테이션 불일치, 브랜치 체크아웃 누락 버그 등 실제 문제를 직접 해결함. 과거 다른 트러블슈팅에서 옳다고 확신한 의견이 근거 부족으로 받아들여지지 않았던 경험 이후, 이번엔 객관적 지표와 팀이 우려할 지점(러닝커브, 권한 범위)에 대한 대응안을 함께 준비해 제안했다.

현재 상태 · STATUS

백엔드 서비스 1개를 개발 환경에서 ArgoCD로 배포하는 흐름 전체 검증 완료, 물리적으로 분리된 스테이징 클러스터 두 대에 걸친 배포 구조까지 확인, 자동 동기화 1단계 적용 중.

미결 사항 프론트엔드·운영 환경 전환, 자동 동기화 2단계(자기 치유), 세밀한 권한 분리는 아직. 검증되지 않은 것을 운영에 먼저 들이지 않는다는 원칙에 따라 개발→스테이징→운영 순서를 건너뛰지 않는다.
CASE No. 05 · 개인 인프라 자동화

보류된 자동화 — 로컬 AI 에이전트로 CI/CD·모니터링 대신하기

보류 · ON HOLD
AI Agent로컬 LLM1인 운영
발단

회사 차원의 LLM 구독 지원이 없었고, 사내 기밀이 외부 API로 나가는 것에 대한 우려도 있었다. 동시에 데브옵스 엔지니어 1인으로 인프라 전반을 커버해야 하는 부담 속에서, 비용 없이 로컬 환경에서 CI/CD·모니터링을 AI 에이전트로 자동화할 수 있는지 시도해봤다.

전체 조사 기록
조사 · ANALYSIS
  • 로컬 오픈소스 에이전트(Hermes Agent)와 로컬 Ollama 모델 조합으로, API 키 없이 무료 구성 세팅을 목표로 설정.
  • 여러 로컬 모델(gemma3, gemma4:e2b, llama3, qwen3:8b)을 바꿔가며 툴 콜링 동작 여부를 직접 격리 테스트.
  • 모델별 실패 지점을 구분 — 일부는 tools 자체를 지원하지 않았고, 지원하는 모델도 툴 결과를 응답에 반영하지 못하는 문제가 있었음.
  • 최종적으로 에이전트가 요구하는 최소 컨텍스트 길이(64K)를 노트북 사양(RAM 16GB)이 감당하지 못한다는 데까지 원인을 좁혀냄.
담당자 메모

원인을 끝까지 좁혀서 명확히 특정하는 것 자체도 의미 있는 진전이라고 본다. "무료·로컬로 가능한 범위"와 "비용이 필요한 범위"의 경계를 스스로 판단할 수 있게 된 것이 이 시도의 실질적인 결과.

결과 · RESULT — 있는 그대로

“에이전틱 추론 자체는 정상 동작하나, 현재 하드웨어로는 최소 컨텍스트 요구사항을 못 맞춘다”는 것까지는 명확히 특정했지만, 실제 자동화 구현까지는 이르지 못했다.

미결 사항 로컬·무료 구성으로는 하드웨어 제약을 넘지 못해 보류. 이후 방향을 유료 API 기반 접근으로 재검토하는 계기가 됨.
FILE 07 — 보안 파일

Secret 관리 표준화 — Vault 도입

CASE No. 06 · 백엔드 CI/CD

시크릿이 코드와 함께 굴러다니지 않도록

해결 · CLOSED
VaultSecret 관리보안표준화
발단

Spring Config Server 기반 시크릿 관리에서 원인 불명의 장애가 반복됐다. 통신 문제인지 Config Server 자체 결함인지조차 특정할 수 없었고, 설상가상으로 초기 설계자가 이미 퇴사한 상태라 분석할 근거조차 없었다. 게다가 소스 코드·설정 파일에 시크릿 값이 그대로 노출되어 있다는 보안 문제도 함께 있었다.

전체 조사 기록
현장 · CONTEXT

AIDT LMS 백엔드 CI/CD(Jenkins·Kaniko·Helm·웹훅) 파이프라인 기준. Config Server를 최초 설계한 담당자는 이미 퇴사한 상태였음.

조사 · ANALYSIS

반복되는 장애를 개별적으로 대응하는 대신, Spring Config Server 자체를 걷어내는 방향으로 결론지음. 애초에 Kubernetes 기반 운영에도 맞지 않는 방식이었던 터라, 트러블슈팅 부담과 아키텍처 부적합 문제를 한 번에 해결할 기회로 판단. 단순 교체를 넘어, 시크릿이 소스·설정 파일에 노출되지 않도록 파드 실행 시점에 동적으로 주입하는 Vault 구조까지 도입하기로 결정.

해결 · SOLUTION
  • Spring Config Server 방식을 걷어내고 Kubernetes 네이티브인 ConfigMap/Secret 기반으로 전환.
  • 외부 Vault 서버와 Agent Injector를 구축해, 파드 실행 시점에 시크릿이 주입되는 구조로 전환.
  • Vault를 실제 CI/CD 파이프라인에 녹여내고, 전환 과정 전체를 회고.
담당자 메모

구조 파악부터 Config Server 탈피, Vault 도입, CI/CD 통합까지 전 과정을 직접 설계·수행함.

결과 · RESULT

한 번에 갈아엎지 않고 네 단계로 리스크를 나눠 진행, 백엔드 시크릿 관리를 Vault 기반으로 완전히 전환했다.

미결 사항 스테이징(vault.enabled=false)과 운영(vault.enabled=true)이 시크릿 관리 방식에서 대칭적이지 않다는 것을 ArgoCD 전수조사 중 발견 — 운영 전환 전 별도 재확인 예정.
FILE 08 — 수사관의 원칙

이중화에 대한 관점

이중화(redundancy)는 인프라를 설계할 때 가장 먼저 던지는 질문이다. 이 관점은 세 시기를 거치며 다듬어졌다.

  • AI 대학원(NLP 전공) — 정제한 코퍼스가 한순간에 날아가는 경험으로 “복원 불가능한 것은 반드시 여러 벌 존재해야 한다”는 원칙을 배움.
  • 가이온 — 무역 데이터 플랫폼 인프라를 다루며 스토리지·DB·파이프라인 어디에도 단일 지점을 남기지 않는 습관을 체득.
  • 키즈노트 — 2022년 10월 판교 SK C&C 화재 직후 입사, 복구 지연의 원인이 “이중화의 미완성”이었다는 정부 조사 결과로 “이중화는 만들어 두는 것이 아니라 실제로 전환되는지 검증해 두는 것”이라는 원칙으로 정교화.

이 관점은 실제 설계에도 반영돼 있다. GitLab 마이그레이션에서 PostgreSQL·Redis·MinIO를 분리했고, Jenkins 컨트롤러 상태를 PVC로 영속화했으며, 멀티클러스터 remote_write 구조에서는 허브 클러스터 장애 시에도 개별 클러스터가 로컬 메트릭을 유지하도록 구성했다.

참고 3-tier Multi-AZ 이중화 아키텍처(WEB/WAS/DB)는 이 철학을 구체적 설계로 정리해 본 연습 자료이며, 실제 운영 중인 AWS 프로덕션 구축 사례는 아니다.
FILE 09 — 부록 · 개인 기록

기술서적 번역 — 『코드형 인프라의 패턴과 실무』

에이콘출판사. Terraform 실무 구축 경험은 없다는 것을 전제하고, 그 대신 이 책의 IaC 패턴을 코드 단위로 직접 검증하며 번역했다.

단계내용
LearnTerraform 기반 IaC 설계 패턴을 원서 단위로 학습
Validate책의 Terraform 코드 예제를 직접 실행해 동작 검증
Document번역과 함께 기술 내용 검수, 실행 결과와 어긋나는 부분 확인
Publish에이콘출판사를 통해 정식 출간
FILE 10 — 역량 매핑

위의 사건들이 증명하는 것

금융권을 포함해 안정적이고 통제 가능한 인프라를 요구하는 조직이라면 공통적으로 확인하고 싶어할 지점을 정리했다.

Reliability
월 2~3회 반복 장애를 구조 개선으로 근절, 무중단 운영 실현
CASE 02
Security
Config Server → ConfigMap/Secret → Vault Agent Injector 단계적 전환
FILE 06
Traceability
Jenkins 잡 로그에만 남던 배포 이력을 Git 커밋 단위로 이관
CASE 04
Standardization
46개 교과목 배포 스크립트의 값 구조를 전수조사 후 4단 values로 표준화
CASE 01 / 04
Reproducibility
HPA/LimitRange를 Helm에 편입해 배포를 완결된 상태 선언으로 만듦
CASE 01
Observability
인수인계 없는 스택을 커밋 히스토리로 역추적, 관측 가능성 격차를 직접 규명
CASE 03
Change Management
개발 → 스테이징 → 운영 순서를 건너뛰지 않고, 미검증 기능은 명시적으로 보류
CASE 04
정직성
원인을 특정하지 못한 사건은 미해결로 남기고, 그 자체를 근거 자료로 문서화
CASE 03
FILE 11 — 사건 마감
“운영 환경의 문제를 구조적으로 해결하고,
안정적이고 재현 가능한 플랫폼으로 개선하는 엔지니어”

Kubernetes, CI/CD, 클라우드를 다뤄본 것이 아니라 — 배포 시간을 54배 줄이고, 반복 장애를 구조적으로 없애고, 관측 가능성의 공백까지 데이터로 증명해온 과정이 지금까지의 기록이다. 이 파일은 계속 갱신되는 중이다.