Skip to content

Project Execution & Completion

JJong-03 edited this page Mar 12, 2026 · 3 revisions

프로젝트 수행 및 완성 (Project Execution & Completion)

1. 개요

이 문서는 Kubernetes 기반 주식 백테스팅 플랫폼의 설계, 구현, 검증, 완성 과정을 요약한다.

초기 설계 문서(Design Principles, ADR-Design Decisions)는 변경 없이 보존되어 있으며, 이 문서는 최종 구현 결과를 기존 Wiki 문서와 연결하는 요약 허브 역할을 한다.


2. 설계 / 기획

핵심 설계 철학

1 Backtest = 1 Kubernetes Job

검증 완료된 레거시 Python 백테스트 엔진을 한 줄도 수정하지 않고, Docker 컨테이너로 감싸 Kubernetes Job으로 실행하는 클라우드 네이티브 플랫폼을 구축했다.

주요 설계 결정

결정 근거
Kubernetes Job 선택 1 백테스트 = 1 Pod으로 실행 격리. Celery + Redis 대비 별도 브로커 불필요, TTL 기반 자동 정리 ([[ADR-Design Decisions#ADR-001
Stateless Web 계층 로컬 파일시스템 의존 제거. 수평 확장 시 코드 변경 불필요. 결과는 MySQL에 저장하거나 Base64로 인라인 반환
GitOps 배포 (Argo CD) Git이 인프라의 단일 진실 공급원. 선언형 매니페스트로 drift 자동 복구, 롤백은 Git revert로 완료
관측성 + 재현성 run_id 기반 전 구간 추적, 4개 재현성 식별자(data_hash, rule_type+params, engine_version, image_tag)로 동일 입력 = 동일 출력 보장

3. 수행 과정 — 프로젝트 이행

Phase별 구현 요약

프로젝트는 6개 Phase로 나누어 순차적으로 구현했다. 각 Phase는 이전 Phase의 결과물 위에 구축된다.

Phase 범위 핵심 산출물
Phase 1 — 컨테이너화 Flask 앱을 Docker 이미지로 패키징, docker compose up 한 줄로 개발 환경 구동 Dockerfile, docker-compose.yml, .env.example
Phase 2 — K8s 런타임 Web Deployment + MySQL StatefulSet, ConfigMap/Secret 환경변수 주입 k8s/*.yaml 매니페스트 세트, backtest_results DDL
Phase 3 — Job 오케스트레이션 백테스트 요청을 K8s Job으로 비동기 실행, Worker가 결과를 MySQL에 저장 worker.py, JobLauncher 추상화, /status/<run_id> API
Phase 4 — CI/CD & GitOps GitHub Actions로 test → build → push, Argo CD로 자동 배포 .github/workflows/ci.yml, Argo CD Application
Phase 5 — 관측성 검증 Rule 8 준수 확인, run_id 기반 전 구간 추적 검증, E2E 데모 scripts/demo.sh, Prometheus/Grafana(optional -> Successed)
Phase 6 — 문서화 아키텍처 다이어그램, 운영 가이드, 기술 회고 docs/ 디렉터리, Wiki 문서

실행 모델

백테스트 실행의 전체 흐름:

User Request → Web (입력 검증, PENDING insert) → K8s Job 생성
→ Worker (엔진 실행, 결과 저장) → MySQL Persistence
→ Web (/status/<run_id>로 결과 조회)

상태 머신은 PENDING → RUNNING → SUCCEEDED/FAILED 단방향 전이를 따른다.


4. 수행 과정 — 중간 점검

검증 방법

프로젝트 진행 중 아래 방법으로 구현 상태를 지속적으로 검증했다.

검증 항목 방법 참조
E2E 파이프라인 검증 scripts/demo.sh로 백테스트 제출 → 상태 폴링 → 결과 확인 자동화 E2E-demo-verification
run_id 추적 검증 kubectl logs에서 Web → Worker → MySQL 전 구간 run_id 추적 E2E-demo-verification
메트릭 모니터링 Prometheus /metrics 엔드포인트, Grafana 대시보드로 request latency, job success rate 확인 Observability
로깅 규격 준수 모든 컴포넌트가 stdout/stderr structured logging 사용, [run_id=<UUID>] 포맷 확인 Observability
CI/CD 파이프라인 git push → GitHub Actions green → 이미지 push → Argo CD auto-sync 확인 CI_CD_GitOps

핵심 체크포인트

  • docker compose up/health 200 OK, /run_backtest 정상 응답
  • kubectl apply -f k8s/ → Web Pod Ready, MySQL Pod Ready
  • 백테스트 요청 → K8s Job 생성 → MySQL에 결과 저장 → /status/<run_id> = SUCCEEDED
  • CI/CD: push → test → build → deploy 전 과정 자동화 확인

5. 기술적 완성도

최종 시스템 구성

구현 완료된 플랫폼의 핵심 구성 요소:

계층 구현 역할
Flask Web Gunicorn + Flask Deployment (Stateless) 요청 검증, run_id 발급, Job 생성, 상태 조회, UI 렌더링
K8s Worker Job 1 백테스트 = 1 Pod (Ephemeral) 엔진 실행, Adapter 파생 지표 계산, MySQL 결과 저장
MySQL 8.0 StatefulSet + PVC backtest_results 테이블 — 모든 결과의 단일 진실 공급원
Prometheus + Grafana ServiceMonitor + Dashboard JSON HTTP latency, request count, job success/failure rate 모니터링
GitHub Actions + Argo CD CI (test → build → push) + CD (auto-sync) Immutable image tag (:<git-sha-short>)로 배포 추적, Git 기반 롤백

재현성 보장

동일한 4개 식별자(data_hash, rule_type+params, engine_version, image_tag)가 주어지면 동일한 백테스트 결과가 생성된다. 모든 식별자는 backtest_results 테이블에 저장되어 사후 감사가 가능하다.

데이터 모델

backtest_results 테이블은 17개 컬럼으로 구성되며, 실행 상태(status), 재현성 식별자(data_hash, image_tag), 정규 데이터(equity_curve_json, trades_json, metrics_json), UTC 타임스탬프(created_at, started_at, completed_at)를 포함한다.


6. 프로젝트 진정성 — 회고

기술적 도전

  • 엔진 불변성 유지: 레거시 엔진을 수정하지 않으면서 5-tab 대시보드에 필요한 파생 지표(drawdown curve, portfolio curve, cumulative return)를 제공해야 했다. Adapter Layer 패턴으로 해결했으나, 엔진 내부 루프 접근이 필요한 기능(예: 실행 중 peak equity 추적)은 구현 불가 제약이 남았다.

  • Job 생성 오버헤드: Kubernetes Job은 Pod 생성에 ~5-10초 오버헤드가 발생한다. 짧은 백테스트에서는 실행 시간보다 인프라 오버헤드가 클 수 있다. Celery 대비 trade-off로 인지하고 수용했다.

  • Write Path / Read Path 분리: Write Path(Web → Job 생성 → Worker → MySQL 저장)와 Read Path(Web → MySQL 조회 → 응답)를 분리한 구조는 Web 계층이 실행 상태를 보유하지 않도록 하는 핵심 설계 결정이었다. 이를 통해 Web은 완전한 stateless를 유지하면서 비동기 실행과 결과 조회를 양립할 수 있었다.

  • Secret 관리: GitOps 환경에서 Secret을 Git에 커밋하지 않으면서 Argo CD 배포와 양립시키는 것이 도전이었다. secret-template.yaml + CI/CD 변수 주입 방식으로 해결했다.

  • Argo CD Sync 상태 reconciliation: 로컬 개발 환경 재시작 후 CLI(argocd app get) 또는 kubectl로 Application 상태를 조회하면 Unknown sync 상태가 표시되는 경우가 있었다. 그러나 Argo CD Web UI에 접속하면 상태가 재계산되어 정상(Synced/Healthy)으로 복구되었다. 이는 Argo CD controller의 reconciliation 타이밍 또는 status cache refresh 주기에 의한 동작으로, GitOps 운영 시 CLI 상태만으로 판단하지 않아야 한다는 교훈을 얻었다.

설계 Trade-off

결정 얻은 것 포기한 것
애플리케이션 매니페스트는 Raw YAML 관리 매니페스트 투명성, 학습 곡선 최소화 환경별 분기, 템플릿 재사용성
MySQL JSON 컬럼 스키마 유연성, 마이그레이션 불필요 SQL 수준 쿼리 최적화, 정규화
Immutable image tag (Git SHA) 배포 추적, 롤백 보장 latest 태그 편의성
단일 네임스페이스 구성 단순화, RBAC 범위 명확 멀티 환경(dev/staging/prod) 분리

현재 아키텍처의 한계

  • 단일 환경: dev/staging/prod 분리 없이 단일 네임스페이스에서 운영. 애플리케이션 매니페스트는 Raw YAML로 관리하며, 관측성 스택(Prometheus/Grafana)은 kube-prometheus-stack Helm chart로 설치했다. 환경별 분기가 필요해지면 Kustomize 도입을 검토할 수 있다.
  • 자동 스케일링 미적용: 현재 아키텍처는 수평 확장 친화적으로 설계되어 있다(Web은 stateless, Worker Job은 요청별 독립 실행). 그러나 HPA(Horizontal Pod Autoscaler) 기반 자동 확장은 아직 적용되지 않아, 동시 요청 급증 시 수동 개입이 필요하다.
  • 분산 트레이싱 부재: run_id grep 기반 추적은 소규모에서 충분하나, Pod 수 증가 시 OpenTelemetry 도입이 필요.
  • 데이터 lifecycle 미정의: backtest_results 테이블의 보존 기간, 압축, 아카이빙 정책이 미정의.
  • 외부 접근 아키텍처 (MetalLB): 현재는 Ingress + ClusterIP 구성으로 클러스터 내부 트래픽만 처리한다. on-prem/LAN 환경에서 외부 접근이 필요하면 MetalLB로 Ingress Controller에 LoadBalancer VIP를 부여하는 구성(MetalLB VIP → Ingress → ClusterIP)을 검토할 수 있으나, 로컬 단일 클러스터 환경에서 LAN 접근이 요구사항이 아니므로 채택하지 않았다.
  • 클러스터 스케일링 전략: Control Plane HA(다중 마스터)와 Worker 노드 확장 두 가지를 검토했다. 이 플랫폼은 백테스트를 K8s Job으로 실행하므로 처리량과 격리성이 Worker 자원에 의존하며, Control Plane HA는 핵심 실행 모델 개선에 기여하지 않는다. 따라서 현재는 Control Plane 1노드 + Worker 노드 확장 가능 구성을 전제로 설계했다.

향후 개선 방향

  • Kustomize: 애플리케이션 매니페스트의 환경별 분기 관리

  • 멀티 환경 배포: dev → staging → prod 파이프라인

  • HPA + 오토스케일링: 백테스트 요청 부하에 따른 자동 확장

  • OpenTelemetry: 분산 트레이싱으로 Web → Worker → DB 구간 latency 프로파일링

  • Sealed Secrets / External Secrets Operator: GitOps 호환 시크릿 관리 강화

  • 의사결정 기록 → ADR-Design Decisions

  • 트러블슈팅 시나리오 → Runbook-Troubleshooting


7. 관련 문서

전체 기술 문서는 아래 Wiki 페이지에서 확인할 수 있다.

설계 기반

아키텍처

실행 & API

데이터

배포 & 운영

검증

Clone this wiki locally