🧠 Proof of Automation — 작동 검증 루프
하나의 커밋으로 CI → CD → 학습/등록 → READY → 핫스왑 → 실험 → 관제까지 자동화되었음을 시각적으로 증명합니다.
🧭 목차
| # | 섹션 |
|---|---|
| 0 | 준비 (CI/CD·GitOps·Secrets 기본 세팅) |
| 1 | CI 실행 (GitHub Actions) |
| 2 | ArgoCD 자동 동기화 |
| 3 | Airflow 학습→등록→READY (FAIL/SUCCESS + Slack) |
| 4 | MLflow 모델 등록·별칭·아티팩트 |
| 5 | FastAPI 핫스왑 (/reload) |
| 6 | 수동 롤백 (운영 복구 가드레일) |
| 7 | 로그 계층 (Airflow=S3 / FastAPI=NFS) |
| 8 | ArgoCD↔Slack 운영 관제 |
| 9 | 보안 자동화 (AWS Rotation + SealedSecrets Re-seal) |
| 10 | 트래픽 실험 (A/B · Canary · Blue-Green) |
| 11 | One-Commit Flow 전체 체인 검증 |
0) 🧰 준비
- (GitOps)
charts/fastapi/values/{dev,prod}.yaml에서 ALIAS_SELECTION_MODE/DEFAULT_ALIAS/CANARY_PERCENT 값을 시나리오별로 수정 →git commit→git push - (테스트 스크립트)
/ops/ab_test.sh저장 (아래 제공)
1) 🧪 CI 진입 (GitHub Actions)

📸 proof-01-ci.png
✅ 확인 포인트: Helm Lint / Render / kubeconform 검증이 dev·prod 매트릭스 전체 모두 성공
🧩 의미: “All checks have passed” 문구를 통해 GitHub Actions CI가 자동 트리거되어 템플릿·리소스 정합성이 완전히 보장됨을 증명합니다
2) 🔁 ArgoCD 동기화 (ApplicationSet 자동 복구)

📸 proof-02-argocd-synced.png
✅ 확인 포인트: airflow, mlflow, fastapi, secrets, namespaces 등 dev/prod 전 앱이 모두 Healthy / Synced
⚙️ 의미: ArgoCD ApplicationSet의 SelfHeal/Prune로 Git(main) 기준 자동 복구가 지속 동작함이 시각적으로 증명됨.
3) 🎯 Airflow 학습→등록→READY 흐름
3-1) Airflow 학습 → 등록 → READY 흐름 (Variables 설정)

📸 proof-03-fail-flow-variables.png
✅ 확인 포인트: model_name, mlflow_alias, rollback_* 등 핵심 변수가 모두 Airflow의 Fernet Key 기반 암호화(is_encrypted=true) 상태로 저장
🧩 의미: Airflow DAG이 학습·등록·핫스왑·롤백 전 과정을 제어할 변수를 정상 인식하고 있으며, 환경별(dev/prod) 실험 파라미터가 일관되게 관리됨을 증명합니다
3-2) Airflow 학습 → 등록 → READY (MLflow 연동 결과)

📸 proof-03-fail-flow.png
✅ 확인 포인트:
train_and_evaluate와check_result까진 Success지만, 정확도(0.8666) < 임계값(0.9)으로 평가되어notify_failure가 트리거되고 이후 태스크(check_model_ready,trigger_reload)는 자동 스킵됨🧩 의미: 정확도 임계치 미달 시 학습 파이프라인이 자동 중단되고 Slack 알림으로 실패 흐름이 전달되는 자동 Fail-safe 로직이 정상 작동함을 증명합니다
3-3) Airflow FAIL FLOW (Slack 알림 검증)

📸 proof-03-fail-flow-slack.png
⚠️ 확인 포인트: Validation failed → 입력값 20 대신 기본값 200 사용 및 기준 미달 → 등록 및 핫스왑 생략 메시지가 Slack 채널(dev)로 실시간 전송
🧩 의미: 정확도 임계치(0.9) 미달 시 DAG의 실패 알림이 Slack으로 즉시 통보되어, 실패 루프가 Airflow–Slack 간 완전 자동화되어 있음을 증명합니다
3-4) Airflow SUCCESS FLOW (학습 → 등록 → READY → 핫스왑) (dev / prod 환경)

📸 proof-03-airflow-dag-success-dev.png

📸 proof-03-airflow-dag-success-prod.png
✅ 확인 포인트: train_and_evaluate → check_result → register_model → check_model_ready → trigger_reload 전 단계가 모두 Success, (* notify_failure는 스킵됨)
🧩 의미: 정확도 임계값(0.9) 이상 달성 후 전체 학습·등록·핫스왑 체인이 정상적으로 완료되었으며, FastAPI
/reload트리거까지 자동화되어 완전한 SUCCESS FLOW가 검증됨
3-5) FastAPI 모델 로드 검증 (dev / prod 환경)

📸 proof-03-fastapi-model-load(dev,prod).png
✅ 확인 포인트: https://fastapi.local 및 https://fastapi.prod 각각에서 /과 /health 응답에 “loaded_variants”: [“A”,“B”] 확인
🧩 의미: dev·prod 환경 모두에서 FastAPI 인스턴스가 최신 모델 A/B를 정상적으로 로드하고 있으며,
/predict,/reload,/models,/health엔드포인트 전체가 TLS 기반으로 정상 응답함을 증명합니다
3-6) FastAPI 모델 등록 및 핫스왑 Slack 알림 (dev / prod 환경)

📸 proof-03-model-load-slack(dev).png

📸 proof-03-model-load-slack(prod).png
✅ 확인 포인트: best_model v1 → @A, best_model v2 → @B 등록 완료 메시지와 함께 각 run_id가 Slack으로 실시간 전송
🧩 의미: Airflow에서 MLflow 등록 완료 후 FastAPI 핫스왑이 자동 수행되며, dev,prod 환경의 Slack Webhook을 통해 A/B 모델 전환 및 실행 이력(run_id) 이 투명하게 추적됨을 증명합니다
3-7) ArgoCD Self-Heal Test (드리프트 자동 복구)

📸 proof-03-drift-self-heal-test.png
✅ 확인 포인트: 수동으로 fastapi-dev-server의 CANARY_PERCENT 값을 31로 변경 후 ArgoCD 동기화로 다시 20으로 복원됨
🧩 의미: 클러스터 내 수동 변경(드리프트)이 발생하더라도 ArgoCD의 SelfHeal 기능이 Git 상태(main branch) 기준으로 자동 복구하여 GitOps 불변성이 유지됨을 증명합니다
4) 🗂️ MLflow 등록/별칭/아티팩트
4-1) MLflow 등록 및 Alias 바인딩 (Airflow Variables)

📸 proof-04-airflow-variables.png
✅ 확인 포인트: mlflow_alias=B, rollback_alias=A, rollback_version=1 등 변수 상태가 정확히 반영되어 있음
🧩 의미: Airflow DAG 실행 결과, 신규 모델이
best_model v2 → B로 등록되고 기존 버전은rollback_version=1 (A)로 유지되어, A/B alias 전환 흐름이 변수 단계에서 명확히 관리됨을 증명합니다
4-2) MLflow 등록 및 Alias 바인딩 (dev, prod 환경)

📸 proof-04-mlflow-alias-dev.png

📸 proof-04-mlflow-alias-prod.png
✅ 확인 포인트: best_model이 Version 2로 새로 등록되며, alias @B: Version 2, @A: Version 1의 이중 alias 체계가 명확히 표시됨
🧩 의미: Airflow DAG 실행 결과, MLflow Registry 내에서 신규 버전이 자동 등록되고, 기존/신규 모델이 각각 A/B alias로 바인딩되어 버전 관리 및 실험 전환 체계가 완전하게 구현되었음을 증명합니다
4-3) MLflow 아티팩트 저장 검증 (dev, prod 환경)

📸 proof-04-mlflow-artifacts-dev.png

📸 proof-04-mlflow-artifacts-prod.png
✅ 확인 포인트: model.pkl, conda.yaml, python_env.yaml 등 모델 메타데이터와 환경 정보가 s3://mlflow-artifacts-keonho/{dev, prod}/… 경로에 환경별로 분리되어 정상 저장됨
🧩 의미: MLflow가 학습 완료된 모델과 실행 환경을 아티팩트로 버전별 보관하며, 추후 FastAPI 서빙 시 동일 환경 재현이 가능한 재현성 있는 MLOps 파이프라인이 확보되었음을 증명합니다
5) ⚡ FastAPI 핫스왑
5-1) FastAPI 핫스왑 검증 (dev, prod 환경)

📸 proof-05-fastapi-reload-dev.png

📸 proof-05-fastapi-reload-prod.png
✅ 확인 포인트: /variant/A/reload, /variant/B/reload 호출 시 각각 version: “1”, “2"로 응답하며 “status”: “success” 반환
⚙️ 잘못된 토큰(
Super_Secret_Token) 사용 시Access denied, 존재하지 않는 엔드포인트 호출 시Not Found반환🧩 의미: FastAPI가 dev, prod 환경별로 토큰 인증·엔드포인트 검증을 모두 통과하며 최신 모델 버전으로 정상 교체됨을 확인 — 보안·무중단 핫스왑 체계가 완벽히 동작함을 증명합니다
5-2) FastAPI 핫스왑 Slack 알림 (dev, prod 환경)

📸 proof-05-fastapi-reload-slack-dev.png

📸 proof-05-fastapi-reload-slack-prod.png
✅ 확인 포인트: [FastAPI] 모델 A 핫스왑 완료: v1, [FastAPI] 모델 B 핫스왑 완료: v2 메시지와 함께 각 run_id가 Slack 채널(dev, prod)에 정상 전송
🧩 의미: FastAPI
/variant/{alias}/reload성공 시, 각 모델 버전의 전환 결과가 Slack Webhook을 통해 실시간 통보되어 핫스왑 완료 알림 루프(dev, prod) 가 완벽히 동작함을 증명합니다
6) 🔄 수동 롤백(운영 복구 레일)
6-1) 수동 롤백 (운영 복구 레일 – Airflow Variables)

📸 proof-06-airflow-variables.png
✅ 확인 포인트: rollback_version=1, rollback_alias=B, mlflow_alias=B, model_name=best_model 등 롤백 관련 변수들이 정확히 세팅됨
🧩 의미: Airflow 수동 롤백 DAG 실행 전, 복구 대상 버전과 모델 alias가 명확히 지정되어 있어 안정적인 운영 복구 플로우(rollback→reload)가 준비된 상태임을 증명합니다
6-2) 수동 롤백 (롤백 전 FastAPI 상태)

📸 proof-06-before-fastapi.png
✅ 확인 포인트: dev·prod 환경 모두 /models 응답에서 A: Version 1, B: Version 2로 표시되어 있음
🧩 의미: 롤백 실행 전, FastAPI가 최신 모델(
B: Version 2)을 Production으로 사용 중이며, 기존 버전(A:1) 이 여전히 보존되어 있는 상태로 안전한 복구 전 준비 상태를 증명합니다
6-3) 수동 롤백 (DAG 수행 결과 – dev, prod 환경)

📸 proof-06-rollback-dag-dev.png

📸 proof-06-rollback-dag-prod.png
✅ 확인 포인트:
- DAG 이름:
manual_rollback_model_devrollback_model_alias→reload_fastapi_model순서로 두 Task 모두success상태- 총 수행 시간 약 29초, 실패·지연 없이 완료
🧩 의미:
Airflow DAG이
rollback_alias와rollback_version값을 기반으로 MLflow alias를 A로 복구하고, FastAPI/reload호출을 자동 트리거하여 이전 모델 버전을 다시 서빙하는 완전한 자동 복구 플로우가 정상 동작했음을 증명합니다.
6-4) 수동 롤백 (롤백 후 FastAPI 상태)

📸 after-fastapi.png
✅ 확인 포인트:
- dev·prod 환경 모두
/models응답에서A: Version 1,B: Version 1로 동일하게 복구됨- rollback 대상
run_id=4a59f6b6acbc45a6a6ec91b8ad28d485가 dev/prod 양쪽에 동일하게 반영됨
🧩 의미:
Airflow 수동 롤백 DAG 실행 이후, FastAPI 서빙 레이어에서 A/B 모두 이전 모델 버전(1) 으로 복원됨을 확인.
즉, MLflow → Airflow → FastAPI 전 구간이 연결된 무중단 복구 파이프라인이 정상적으로 작동했음을 완벽히 증명합니다.
7) 📑 로그 스토리지(S3+NFS)
7-1) Airflow 로그 S3 저장 검증 (dev, prod 환경)

📸 proof-07-logs-airflow-s3-dev.png

📸 proof-07-logs-airflow-s3-prod.png
✅ 확인 포인트:
- 버킷 경로:
s3://airflow-logs/dag_id=manual_rollback_model_dev/- 태스크:
task_id=reload_fastapi_model/- 로그 파일:
attempt=1.log(2025-10-10 19:45:10 KST 저장)
🧩 의미:
Airflow가
manual_rollback_model_devDAG 실행 로그를 S3 버킷에 자동 업로드하여 모든 복구 실행 이력(rollbacks & reloads) 이 중앙화된 저장소에 안전하게 기록됨을 증명합니다.이는 운영 가시성 확보 + 장애 원인 추적 + 감사 로그(Audit Log) 체계의 핵심 기반입니다.
7-2) FastAPI 로그 NFS 저장 검증 (dev, prod 환경)

📸 proof-07-logs-fastapi-nfs.png
✅ 확인 포인트:
- 로그 경로:
/mnt/nfs_share/mlops/fastapi/logs/{dev,prod}/fastapi.log- 주요 로그:
[✔] 모델 로딩 성공 : alias=A, version=1[✔] 모델 로딩 성공 : alias=B, version=2- 롤백 이후 재시작 시에도 동일한 alias·version 로드 내역이 기록됨
🧩 의미:
FastAPI 인스턴스가 dev/prod 양쪽에서 NFS 마운트 기반 중앙 로그 수집을 수행 중이며,
모델 로드 이벤트(A/B, 버전 변동 포함)가 파일 단위로 기록됨을 확인.
이는 실시간 복구 검증 및 추적 가능한 모델 서빙 로그 체계가 구축되었음을 의미합니다.
8) 🛰️ ArgoCD↔️Slack 관제 루프

📸 proof-08-argocd-slack.png

📸 proof-08-argocd-slack-2.png
✅ 확인 포인트:
airflow-dev,airflow-prod,fastapi-logs-storage-dev/prod,prod-secrets등 주요 앱의 상태 변화가 Slack 채널(argocd)에 자동 전송- 상태 전이 감지:
Sync OutOfSync → Health HealthyHealth Degraded → HealthySync Failed시❌ Error메시지 포함- 링크(
Open in ArgoCD)로 즉시 ArgoCD UI 접근 가능
🧩 의미:
ArgoCD와 Slack이 완전 연동되어, 배포·Sync·Health 상태 변화가 실시간 감시 체계로 통합됨을 증명합니다.
즉, 모델 롤백·핫스왑·재배포 후에도 모든 ArgoCD Application의 Sync/Health 상태가 자동으로 복원·보고되는 자율 감시 루프가 구축된 것입니다.
9) 🔐 보안 자동화(크리덴셜/시크릿)
9-1-a) AWS Credentials Secret Rotation (Before 상태)

📸 proof-09-rotation-resourceversion-before.png
✅ 확인 포인트:
- 확인된 네임스페이스:
airflow-dev,fastapi-dev,mlflow-dev,airflow-prod,fastapi-prod,mlflow-prod- 각 Secret(
aws-credentials-secret)의resourceVersion값이 모두 서로 다름 (21xxxx대)- 아직 동기화(회전) 전 상태임
🧩 의미:
Secret rotation 실행 전의 baseline snapshot으로,
환경별 AWS Credentials Secret 리소스 버전이 상이함을 명확히 기록함.
이후 rotation 스크립트 실행 후 이 값들이 갱신되어야 정상 동작으로 간주됩니다.
즉, 이 이미지는 키 회전 전 정상 baseline 상태를 증명합니다.
9-1-b) AWS Credentials Secret Rotation (이전 키 중복 감지 실패 사례)

📸 proof-09-rotation-oldkeys-fails.png
✅ 확인 포인트:
- 실행 명령:
bash rotate-aws-credentials.sh dev- IAM User:
mlflow-airflow-user- 감지된 기존 키:
AKIA********CB7Z- 에러 메시지:
ERROR: mlflow-airflow-user에 이미 키 2개 존재. 하나 비활성/삭제 후 재시도.
🧩 의미:
IAM 사용자의 액세스 키가 이미 두 개 모두 활성 상태여서,
새 키를 발급할 수 없다는 AWS 제한(최대 2개)으로 회전 프로세스가 안전하게 중단됨.
즉, 스크립트의 사전 검증 로직이 정상적으로 작동하여 중복 발급 방지 기능이 유효함을 보여줍니다.
9-1-c) AWS Credentials Secret Rotation (회전 및 ArgoCD 반영 완료) (dev, prod 환경)

📸 proof-09-rotation-rotate-log-dev-1.png

📸 proof-09-rotation-rotate-log-dev-2.png

📸 proof-09-rotation-rotate-log-prod-1.png

📸 proof-09-rotation-rotate-log-prod-2.png
✅ 확인 포인트:
- dev
- IAM User:
mlflow-airflow-dev-user- 새 키:
AKIA********IH5feat(dev): rotate AWS credentials across airflow/fastapi/mlflow커밋/root/backup/...json백업 완료- ArgoCD
dev-secrets→Sync Succeeded, 모든 SealedSecretSynced / HealthyresourceVersion증가 확인 (2161301→2162096)- prod
- IAM User:
mlflow-airflow-user- 새 키:
AKIA********GHfeat(prod): rotate AWS credentials across airflow/fastapi/mlflow커밋- ArgoCD
prod-secrets→Sync Succeeded, 모든 SealedSecretSynced / HealthyresourceVersion증가 확인 (2148011→2162479)- 모든 단계에서
- GitHub Push → ArgoCD Auto Sync → SealedSecret 적용 → AWS CLI 검증 → 구 키 Inactive 권고 메시지까지 자동 출력.
- 키 회전 후 서비스 영향 없이 정상 운영 유지.
🧩 의미:
dev/prod 전 구간의 AWS 자격 증명이
단일 명령으로 완전 자동 회전 + GitOps 연동 + 무중단 반영됨을 입증.
즉, 보안/운영/자동화 3요소가 완벽히 통합된 SealedSecret 기반 Key Rotation 구조임을 보여줍니다.
9-1-d) AWS Credentials Secret Rotation (리소스 버전 비교 증명)

📸 proof-09-rotation-resourceversion-after.png
✅ 변경 전 (before) → 변경 후 (after) 비교
Namespace Secret Before After 증가 여부 airflow-dev aws-credentials-secret 2161270 2161994 ✅ fastapi-dev aws-credentials-secret 2161277 2162035 ✅ mlflow-dev aws-credentials-secret 2161301 2162098 ✅ airflow-prod aws-credentials-secret 2148004 2162742 ✅ fastapi-prod aws-credentials-secret 2147983 2162770 ✅ mlflow-prod aws-credentials-secret 2148011 2162749 ✅ 🔍 모든 dev/prod Secret의
resourceVersion이 증가했으며,이는 SealedSecret → Secret → Pod 반영까지 자동 업데이트된 것을 의미합니다.
ArgoCD Sync, AWS CLI 검증, 구 키 Inactive 확인까지 일련의 자동화 체인이
정상적으로 동작함을 최종적으로 입증합니다.
9-1-e) AWS Credentials Secret Rotation (ArgoCD 최종 상태 검증)

📸 proof-09-rotation-argocd-synced.png
✅ 확인 포인트
ArgoCD 앱
dev-secrets,prod-secrets모두
Status: Healthy / SyncedLast Synced: 2025-10-15 14:26~14:28 (회전 직후 몇 초 내 자동 동기화)- Git 리포지토리:
https://github.com/keonhoban/mlops-infra-gitops- Path:
envs/dev/sealed-secrets,envs/prod/sealed-secrets의미: 키 회전 직후 자동으로 GitOps 반영이 완료되어
수동 intervention 없이 모든 Secret이 최신 상태로 유지됨.
🧩 의미:
dev,prod전 환경의 AWS Credentials Secret Rotation 자동화 루프가 완전히 폐쇄(Closed Loop) 되었습니다.SealedSecret → Secret → Pod → ArgoCD → Git → AWS까지
단일 명령(
bash rotate-aws-credentials.sh <env>)로 전 과정이 자동화되고,무중단·무인 개입·완전 가시화 수준의 운영 체계를 달성했습니다.
9-2-a) SealedSecret Controller & Re-seal (컨트롤러 키 재발급 및 fingerprint 검증)

📸 proof-09-reseal-pub-cert-fingerprint-diff.png
✅ 확인 포인트
- 신규 Controller fingerprint:
CE:1C:D4:0D:F4:C5:B6:CB:02:C1:F5:85:08:6E:36:E1:70:CA:E9:31:15:0F:4B:77:EC:F0:A4:19:E6:FC:49:8C- dev/prod 환경 모두 재seal 완료, GitOps main 반영 및 일치 검증 OK
🧩 의미
- SealedSecret 컨트롤러 키가 교체되어 모든 시크릿이 최신 공개키로 암호화됨.
- 키 회전 후 무중단 GitOps 환경이 정상 유지됨을 증명.
9-2-b) SealedSecret Controller & Re-seal (ArgoCD 반영 확인)

📸 proof-09-reseal-argocd-synced.png
✅ 확인 포인트
- dev/prod 전 앱(
airflow,mlflow,fastapi,secrets,logs,notifications등) 상태: Healthy · Synced- Controller 키 회전 이후 모든 SealedSecret 재배포 완료
💡 의미
- Re-Seal 작업이 모든 네임스페이스에 정상 반영되었음을 증명.
- 키 교체 후 ArgoCD GitOps 파이프라인 전체가 안정적으로 유지됨.
10) 🚦트래픽 실험 — A/B · Canary · Blue-Green
FastAPI의 라우팅은 values로 제어됩니다.
운영 중 이미지 업데이트 없이 트래픽만 조절하려면
A/B/Canary/Blue-Green 중 Canary/Blue-Green 권장
(GitOps: charts/fastapi/values/{dev,prod}.yaml → ALIAS_SELECTION_MODE, DEFAULT_ALIAS, CANARY_PERCENT)
합격 기준 표
- A/B는 통계적 실험(90:10)
- Canary는 점진 배포(10~30%)
- Blue-Green은 완전 전환(100%)
| 유형 | values 설정 | 기대 분포 |
|---|---|---|
| A/B | ALIAS_SELECTION_MODE=ab_test | A/B ≈ 90:10 |
| Canary(n%) | ALIAS_SELECTION_MODE=canary,CANARY_PERCENT=30 | B ≈ 30% |
| Blue-Green | ALIAS_SELECTION_MODE=blue_green,DEFAULT_ALIAS=B | B = 100% |
📎 테스트 스크립트 (A/B·Canary·Blue-Green 공용)
파일: /ops/ab_test.sh
#!/bin/bash
# ab_test.sh — A/B/Canary/Blue-Green 분포 검증
# 사용: ./ab_test.sh [N] (기본 N=200)
set -euo pipefail
N=${1:-200}
URL=${FASTAPI_URL:-"https://fastapi.local"}
PAYLOAD='{"data": [[5.1, 3.5, 1.4, 0.2]]}'
echo "🔍 A/B·Canary·Blue-Green 분포 확인 (${N}건)"
: > ab_test_result.log
for i in $(seq 1 $N); do
id="client_$i"
variant=$(curl -sk "${URL}/predict" \
-H "Content-Type: application/json" \
-H "x-client-id: ${id}" \
-d "${PAYLOAD}" | jq -r '.variant')
echo "$id → $variant" | tee -a ab_test_result.log >/dev/null
done
count_B=$(grep -c "→ B" ab_test_result.log || true)
count_A=$((N - count_B))
ratio=$((count_B * 100 / N))
echo "📊 결과: A=${count_A}, B=${count_B} (B=${ratio}%)"
파일: /ops/capture_test.sh
#!/bin/bash
set -euo pipefail
mode=${1:-ab_test} # ab_test, canary, blue_green
echo ""
echo "=============================="
echo "🧪 테스트 모드 시작: $mode"
echo "=============================="
echo ""
grep -A 10 '^env:' charts/fastapi/values/dev.yaml
yq e ".env.ALIAS_SELECTION_MODE=\"$mode\"" -i charts/fastapi/values/dev.yaml
grep -A 10 '^env:' charts/fastapi/values/dev.yaml
git add charts/fastapi/values/dev.yaml
git commit -am "test: $mode routing" && git push
echo "⏳ ArgoCD 동기화 대기 중..."
sleep 120
echo "🚀 테스트 실행 중 ($mode)"
./ops/ab_test.sh 500
echo ""
echo "✅ 테스트 모드 종료: $mode"
echo "──────────────────────────────"
echo ""
10-1) A/B 테스트
- 설정:
ALIAS_SELECTION_MODE=ab_test - 스크립트:
/ops/ab_test.sh 200 - 합격 기준: A/B 분포 ≈ 90:10 (샘플 수가 많을수록 근접)
📸 proof-10-ab_test.png

10-2) Canary(예: 30%)
- 설정:
ALIAS_SELECTION_MODE=canary,CANARY_PERCENT=30 - 스크립트:
/ops/ab_test.sh 500 - 합격 기준: B ≈ 30% ± (표본 오차 범위)
📸 proof-10-canary.png

10-3) Blue-Green 전환
- 설정:
ALIAS_SELECTION_MODE=blue_green,DEFAULT_ALIAS=B - 스크립트:
/ops/ab_test.sh 100 - 합격 기준: B = 100% (완전 전환)
📸 proof-10-blue_green.png

11) 🔗 One-Commit Flow 전체 체인
11-1) 사전 준비 (1회만)
charts/fastapi/values/{dev,prod}.yaml의 ALIAS_SELECTION_MODE / DEFAULT_ALIAS / CANARY_PERCENT 값만 바꿔가며 테스트합니다- 테스트 스크립트
/ops/ab_test.sh(이미 공유된 버전) 사용 — 모드 전환 없이 그대로 사용 가능 - 내부망 TLS는 cert-manager 내부 CA + hosts 전제로 동작(현재 세팅 유지)
11-2) 🧱 Git 브랜치 생성 및 PR 트리거

📸 proof-11-git-pr-trigger.png
✅ 확인 포인트
feat/one-commit-flow-test브랜치 생성 후 Helm CI 트리거용 커밋 푸시 완료- GitHub PR 자동 생성 URL 출력됨
💡 의미
- CI/CD 파이프라인이 커밋 단위로 자동 실행되도록 One-Commit Flow의 시작점을 준비함.
11-3) ⚙️ CI/CD 통합 검증 (GitHub Actions + ArgoCD)

📸 proof-11-ci-cd.png
✅ 확인 포인트
- GitHub PR에서 Helm CI 6개 테스트(dev/prod 병렬) 전부 성공
- ArgoCD 내 모든 앱 상태
Healthy · Synced유지
💡 의미
- Git 커밋 → CI → CD까지 자동 연동이 완성된 One-Commit Flow 전체 파이프라인 검증 완료.
11-4) 🔄 Git PR 병합 & ArgoCD 자동 Sync

📸 proof-11-git-pr-merge-result.png
✅ 확인 포인트
main브랜치에 PR 병합(commit:cccb1dd) 완료- ArgoCD 모든 애플리케이션이 즉시
Healthy · Synced상태 유지
💡 의미
- 코드 병합 후 CD 자동 반영까지 완전 자동화됨 → GitOps 기반 “One-Commit Flow” 실시간 반영 구조 확립.
11-5) 📊 Airflow Variables 자동 반영 확인

📸 proof-11-airflow-dev-variables.png
✅ 확인 포인트
rollback_version=2,rollback_alias=B,mlflow_alias=A등 최신 상태 반영- PR 병합 이후 Airflow 환경 자동 업데이트 완료
💡 의미
- CI/CD 파이프라인을 통한 Airflow DAG 환경 변수 자동 갱신까지 성공적으로 연결됨 → 완전한 E2E 자동화 검증 완료.
11-6) 🤖 학습 → 등록 → 핫스왑 → Slack 알림 자동화

📸 proof-11-train-ready-reload-slack.png
✅ 확인 포인트
- Airflow DAG(
ml_train_register_and_reload_dev) 전 Tasksuccess- MLflow 실험
Finished및accuracy=0.9666- Slack 자동 알림: 모델 등록(
best_model v8 → @A) → 핫스왑 완료(@A)
💡 의미
- CI/CD 이후 모델 학습부터 FastAPI 실시간 반영까지 완전 자동화 루프 달성 → 진정한 “One-Commit Flow” 완성 🚀
11-7) 🧪 FastAPI Canary 라우팅 검증

📸 proof-11-routing-canary.png
✅ 확인 포인트
ALIAS_SELECTION_MODE=canary,CANARY_PERCENT=20- Blue-Green 로그 결과: A=411, B=89 (B≈17%)
- GitOps 커밋(
test: canary routing) 정상 반영
💡 의미
- 트래픽 20%가 Canary(B)로 정상 분배됨 → FastAPI 레벨 트래픽 실험 구조 완성.
11-8) 🧪 FastAPI Blue-Green 라우팅 검증

📸 proof-11-routing-blue_green.png
✅ 확인 포인트
ALIAS_SELECTION_MODE=blue_green- 테스트 결과: A=0, B=500 (정확히 100%)
- GitOps 커밋(
test: blue_green routing) 및 ArgoCD Sync 완료
💡 의미
- Canary 대비 완전 분리된 트래픽 분배 구조 검증 완료 → A/B/Blue-Green 라우팅 체계 모두 정상 동작.
11-9) 📂 로그 스토리지 계층 (S3 + NFS) 검증

📸 proof-11-logs-s3-nfs.png
✅ 확인 포인트
- S3:
mlflow-artifacts-keonho/dev/airflow-logs/...경로에 DAG별 로그 업로드 확인- NFS:
/mnt/nfs_share/mlops/fastapi/logs/dev/fastapi.log실시간 갱신- FastAPI pod 로그와 NFS 로그 동기화 시각 확인
💡 의미
Airflow → MLflow → FastAPI의 로그 파이프라인 완전 일원화,
실험·서빙 로그가 S3(백업) + NFS(실시간) 로 모두 기록됨.
11-10) 🔑 AWS Credentials 자동 회전 검증

📸 proof-11-aws-credentials-rotate.png
✅ 확인 포인트
mlflow-airflow-dev-userIAM 키 자동 회전 후 신규 키 2개 Active 상태aws-credentials-secret의resourceVersion갱신 확인 (2471260→2501958)- GitOps 커밋(
feat(dev): rotate aws credentials) 정상 반영
💡 의미
AWS IAM 키 생성 → 로컬 백업 → SealedSecret 자동 암호화 → GitOps 반영까지
완전 자동 회전 체계 성공적으로 동작함.
11-11) 🔑 SealedSecrets 컨트롤러 키 회전 & Re-Seal 검증

📸 proof-11-sealedsecret-cm-rotate-reseal.png
✅ 확인 포인트
- 새 Fingerprint:
BA:75:AD:B7...E6:0:48:AB으로 변경 확인- dev/prod 모든 SealedSecret 파일(
.yaml)에서valid결과 반환- ArgoCD 모든 앱 Healthy / Synced 상태 유지
💡 의미
Controller 키 재발급 + 전 환경 Re-Seal 후에도 서비스 중단 없이
무중단 시크릿 재암호화 체계 완성됨.
11-12) 🔄 수동 롤백 변수 설정 (Airflow Variable)

📸 proof-11-manual-rollback-variables.png
✅ 확인 포인트
rollback_version=1,rollback_model_name=best_model,rollback_alias=B설정 완료- 기존 프로덕션 모델(
A) 대비 이전 버전(B)으로의 롤백 준비 상태
💡 의미
- Airflow DAG에서 조건 기반 수동 롤백을 테스트하기 위한 변수 기반 제어 구조 정상 동작 확인.
11-13) 🔁 Airflow 수동 롤백 실행 & Slack 연동 검증

📸 proof-11-manual-rollback-diff-and-slack.png
✅ 확인 포인트
manual_rollback_model_devDAG 실행 성공 (rollback_model_alias+reload_fastapi_model완료)- FastAPI
/models결과에서Balias의 run_id4a59f6b6...로 롤백 반영 확인- Slack 알림: “[FastAPI] 모델 B 핫스왑 완료” 정상 수신
💡 의미
수동 트리거만으로 모델 레지스트리 → FastAPI Reload → Slack 알림까지
완전 자동 연동된 핫스왑 기반 롤백 루틴이 성공적으로 동작함.
한 줄 요약
이 캡처 플로우만 따르면, One Commit Flow(CI→CD→학습/등록→READY→핫스왑→실험→관제)가 실제 환경에서 정상 작동했음을 그대로 증명할 수 있습니다.