🧠 Proof of Automation — 작동 검증 루프

하나의 커밋으로 CI → CD → 학습/등록 → READY → 핫스왑 → 실험 → 관제까지 자동화되었음을 시각적으로 증명합니다.


🧭 목차

#섹션
0준비 (CI/CD·GitOps·Secrets 기본 세팅)
1CI 실행 (GitHub Actions)
2ArgoCD 자동 동기화
3Airflow 학습→등록→READY (FAIL/SUCCESS + Slack)
4MLflow 모델 등록·별칭·아티팩트
5FastAPI 핫스왑 (/reload)
6수동 롤백 (운영 복구 가드레일)
7로그 계층 (Airflow=S3 / FastAPI=NFS)
8ArgoCD↔Slack 운영 관제
9보안 자동화 (AWS Rotation + SealedSecrets Re-seal)
10트래픽 실험 (A/B · Canary · Blue-Green)
11One-Commit Flow 전체 체인 검증

0) 🧰 준비

  • (GitOps) charts/fastapi/values/{dev,prod}.yaml에서 ALIAS_SELECTION_MODE/DEFAULT_ALIAS/CANARY_PERCENT 값을 시나리오별로 수정 → git commitgit push
  • (테스트 스크립트) /ops/ab_test.sh 저장 (아래 제공)

1) 🧪 CI 진입 (GitHub Actions)

CI_진입.png

📸 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

📸 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

📸 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

📸 proof-03-fail-flow.png

✅ 확인 포인트: train_and_evaluatecheck_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

📸 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-dev.png

proof-03-airflow-dag-success-prod.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

📸 proof-03-fastapi-model-load(dev,prod).png

✅ 확인 포인트: https://fastapi.localhttps://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(dev).png

proof-03-model-load-slack(prod).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

📸 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

📸 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-dev.png

proof-04-mlflow-alias-prod.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-dev.png

proof-04-mlflow-artifacts-prod.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-dev.png

proof-05-fastapi-reload-prod.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-dev.png

proof-05-fastapi-reload-slack-prod.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

📸 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

📸 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-dev.png

proof-06-rollback-dag-prod.png

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

✅ 확인 포인트:

  • DAG 이름: manual_rollback_model_dev
  • rollback_model_aliasreload_fastapi_model 순서로 두 Task 모두 success 상태
  • 총 수행 시간 약 29초, 실패·지연 없이 완료

🧩 의미:

Airflow DAG이 rollback_aliasrollback_version 값을 기반으로 MLflow alias를 A로 복구하고, FastAPI /reload 호출을 자동 트리거하여 이전 모델 버전을 다시 서빙하는 완전한 자동 복구 플로우가 정상 동작했음을 증명합니다.

6-4) 수동 롤백 (롤백 후 FastAPI 상태)

proof-06-after-fastapi.png

📸 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-dev.png

proof-07-logs-airflow-s3-prod.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_dev DAG 실행 로그를 S3 버킷에 자동 업로드하여 모든 복구 실행 이력(rollbacks & reloads) 이 중앙화된 저장소에 안전하게 기록됨을 증명합니다.

이는 운영 가시성 확보 + 장애 원인 추적 + 감사 로그(Audit Log) 체계의 핵심 기반입니다.

7-2) FastAPI 로그 NFS 저장 검증 (dev, prod 환경)

proof-07-logs-fastapi-nfs.png

📸 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.png

proof-08-argocd-slack-2.png

📸 proof-08-argocd-slack-2.png

✅ 확인 포인트:

  • airflow-dev, airflow-prod, fastapi-logs-storage-dev/prod, prod-secrets 등 주요 앱의 상태 변화가 Slack 채널(argocd)에 자동 전송
  • 상태 전이 감지:
    • Sync OutOfSync → Health Healthy
    • Health Degraded → Healthy
    • Sync 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

📸 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

📸 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-1.png

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

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

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

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

proof-09-rotation-rotate-log-prod-2.png

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

✅ 확인 포인트:

  • dev
    • IAM User: mlflow-airflow-dev-user
    • 새 키: AKIA********IH5
    • feat(dev): rotate AWS credentials across airflow/fastapi/mlflow 커밋
    • /root/backup/...json 백업 완료
    • ArgoCD dev-secretsSync Succeeded, 모든 SealedSecret Synced / Healthy
    • resourceVersion 증가 확인 (21613012162096)
  • prod
    • IAM User: mlflow-airflow-user
    • 새 키: AKIA********GH
    • feat(prod): rotate AWS credentials across airflow/fastapi/mlflow 커밋
    • ArgoCD prod-secretsSync Succeeded, 모든 SealedSecret Synced / Healthy
    • resourceVersion 증가 확인 (21480112162479)
  • 모든 단계에서
    • 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

📸 proof-09-rotation-resourceversion-after.png

✅ 변경 전 (before) → 변경 후 (after) 비교

NamespaceSecretBeforeAfter증가 여부
airflow-devaws-credentials-secret21612702161994
fastapi-devaws-credentials-secret21612772162035
mlflow-devaws-credentials-secret21613012162098
airflow-prodaws-credentials-secret21480042162742
fastapi-prodaws-credentials-secret21479832162770
mlflow-prodaws-credentials-secret21480112162749

🔍 모든 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

📸 proof-09-rotation-argocd-synced.png

✅ 확인 포인트

  • ArgoCD 앱 dev-secrets, prod-secrets 모두

    • Status: Healthy / Synced
    • Last 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

📸 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

📸 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-GreenCanary/Blue-Green 권장

(GitOps: charts/fastapi/values/{dev,prod}.yamlALIAS_SELECTION_MODE, DEFAULT_ALIAS, CANARY_PERCENT)

합격 기준 표

  • A/B는 통계적 실험(90:10)
  • Canary는 점진 배포(10~30%)
  • Blue-Green은 완전 전환(100%)
유형values 설정기대 분포
A/BALIAS_SELECTION_MODE=ab_testA/B ≈ 90:10
Canary(n%)ALIAS_SELECTION_MODE=canary,CANARY_PERCENT=30B ≈ 30%
Blue-GreenALIAS_SELECTION_MODE=blue_green,DEFAULT_ALIAS=BB = 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

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

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

proof-10-blue_green.png


11) 🔗 One-Commit Flow 전체 체인

11-1) 사전 준비 (1회만)

  • charts/fastapi/values/{dev,prod}.yamlALIAS_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

📸 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

📸 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

📸 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

📸 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

📸 proof-11-train-ready-reload-slack.png

✅ 확인 포인트

  • Airflow DAG(ml_train_register_and_reload_dev) 전 Task success
  • MLflow 실험 Finishedaccuracy=0.9666
  • Slack 자동 알림: 모델 등록(best_model v8 → @A) → 핫스왑 완료(@A)

💡 의미

  • CI/CD 이후 모델 학습부터 FastAPI 실시간 반영까지 완전 자동화 루프 달성 → 진정한 “One-Commit Flow” 완성 🚀

11-7) 🧪 FastAPI Canary 라우팅 검증

proof-11-routing-canary.png

📸 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

📸 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

📸 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

📸 proof-11-aws-credentials-rotate.png

✅ 확인 포인트

  • mlflow-airflow-dev-user IAM 키 자동 회전 후 신규 키 2개 Active 상태
  • aws-credentials-secretresourceVersion 갱신 확인 (24712602501958)
  • GitOps 커밋(feat(dev): rotate aws credentials) 정상 반영

💡 의미

  • AWS IAM 키 생성 → 로컬 백업 → SealedSecret 자동 암호화 → GitOps 반영까지

    완전 자동 회전 체계 성공적으로 동작함.

11-11) 🔑 SealedSecrets 컨트롤러 키 회전 & Re-Seal 검증

proof-11-sealedsecret-cm-rotate-reseal.png

📸 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

📸 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.png

📸 proof-11-manual-rollback-diff-and-slack.png

✅ 확인 포인트

  • manual_rollback_model_dev DAG 실행 성공 (rollback_model_alias + reload_fastapi_model 완료)
  • FastAPI /models 결과에서 B alias의 run_id 4a59f6b6... 로 롤백 반영 확인
  • Slack 알림: “[FastAPI] 모델 B 핫스왑 완료” 정상 수신

💡 의미

  • 수동 트리거만으로 모델 레지스트리 → FastAPI Reload → Slack 알림까지

    완전 자동 연동된 핫스왑 기반 롤백 루틴이 성공적으로 동작함.


한 줄 요약

이 캡처 플로우만 따르면, One Commit Flow(CI→CD→학습/등록→READY→핫스왑→실험→관제)가 실제 환경에서 정상 작동했음을 그대로 증명할 수 있습니다.