Docker·Kubernetes·MLflow로 짜는 MLOps 배포 파이프라인 — 카나리 배포부터 자동 롤백까지

MLflow로 실험·모델을 추적하고 Docker·Kubernetes로 카나리 배포·자동 롤백까지 이어지는 MLOps 파이프라인 구조와 코드 예시를 정리한다.

2026-08-12 · 최초 발행 2024-04-29

데이터·모델·코드가 빠르게 변하는 환경에서 재현성·확장성·안정성을 동시에 확보하려면 모델 배포를 표준화(Docker, Kubernetes)하고 실험·등록·배포를 자동화(MLflow)하는 운영 체계가 필요하다. MLOps(Machine Learning Operations)는 데이터 수집부터 학습·검증·배포·모니터링·재학습까지 전 과정을 DevOps 원칙으로 자동화·표준화하는 운영 프레임워크로, 소스·데이터·모델 버전관리, 실험 추적, 모델 레지스트리, CI/CD/CT, 컨테이너 배포, 관측·경보, 거버넌스·승인 절차를 아우른다.

이 체계에서 세 도구는 각기 다른 역할을 맡는다. Docker는 실행 환경 불변성과 이식성을 확보하고, Kubernetes는 확장·자가치유·롤아웃/롤백을 오케스트레이션하며, MLflow는 실험 추적(Tracking), 아티팩트·모델 관리(Artifacts/Models), 모델 레지스트리(Registry), 서빙 연계를 담당한다.

각 도구가 맡는 역할

Docker 컨테이너는 종속성을 캡슐화해 환경 편차를 제거하고 이미지를 불변 아티팩트로 관리한다. 빌드-런타임을 분리해 공격면을 축소하는 distroless 이미지가 권장되며, 이미지 서명·검증(cosign), 취약점 스캔(Trivy), 최소 권한 런타임(Non-root) 적용이 거버넌스 측면에서 중요하다.

Kubernetes는 수평 확장(HPA)과 롤링 업데이트·블루/그린·카나리 배포 전략을 지원하고, Readiness/Liveness 프로브로 장애 파드를 자가치유한다. 리소스 QoS(requests/limits), PodDisruptionBudget, GPU 스케줄링(Node selector, tolerations)까지 다루며 네트워크 정책·시크릿 관리도 함께 담당한다.

MLflow는 파라미터·메트릭·아티팩트·모델 시그니처를 실험/런 단위로 자동 기록하는 Tracking 기능과, Staging→Production 단계 전환·승인 워크플로·버전 아카이빙을 지원하는 Model Registry로 나뉜다. 모델 URI를 일원화해 서빙 경로를 안정화하는 역할도 한다.

배포 옵션을 단독 Docker와 클러스터 Kubernetes로 비교하면 다음과 같다.

항목 Docker(단독) Kubernetes(클러스터)
성능 단일 노드 자원 극대화 용이 노드 풀 기반 수평 확장 용이
확장성 수동 스케일링 한계 자동 스케일링(HPA/VPA) 지원
일관성 호스트 의존성 영향 가능 선언적 상태관리로 일관성 확보
안정성 프로세스 장애 시 수동 복구 자가치유, 롤아웃/롤백 자동화
운영 편의 초기 진입 용이 초기 복잡도 높으나 장기 운영 유리

파이프라인 자동화(CI/CD/CT)는 Git 기반 트리거로 PR 빌드→테스트→이미지 빌드/스캔→레지스트리 푸시→배포 매니페스트 업데이트(GitOps)까지 이어진다. CT(Continuous Training)는 데이터 드리프트 신호가 감지되면 학습 잡을 스케줄링하고 검증 후 Registry에 등록, 카나리 배포까지 자동화하는 개념이며, 스테이지 전환 승인·락으로 동시성 충돌을 방지한다. 관측성 측면에서는 예측 지연, 오류율, 입력 분포/드리프트, 성능(정확도/AUC)을 모델·서비스 이중으로 모니터링하고, SLO 위반 시 카나리를 중지하거나 자동 롤백하며 피처·레이블 데이터 품질 체크와 스키마 유효성 검증도 함께 수행한다.

표준 배포 절차와 파이프라인 흐름

표준 배포 절차는 Git 커밋(SHA), 데이터 스냅샷(버전/해시), 환경 스펙(conda.yaml/requirements.txt)을 입력으로 받아 학습 파이프라인을 실행하고, MLflow Tracking/Artifacts에 기록한 뒤 검증 게이트(성능/스키마/바이어스)를 통과하면 Registry에 등록하고 Staging으로 전환한다. 이후 컨테이너 이미지를 빌드·서명하고 Kubernetes 카나리 배포로 넘어가며, 최종 출력은 버전이 고정된 Production 스테이지 모델과 안정화된 배포(Deployment/Service), 관측 대시보드·경보 룰이다.

에러 처리를 포함한 전체 흐름은 다음과 같다.

NoYesRejectedApprovedViolationsHealthy N minsGit commit + Data versionCI: Build/TestTrain: ML pipelineValidate: metrics = SLO?Fail pipeline + Notify +BlockMLflow Register: Newmodel versionStage=Staging, ApprovalgateBuild Docker image + SignK8s Canary deploy 5%Monitor:latency/error/driftAuto rollback + AlertPromote canary - 100%MLflow Stage=ProductionObserve + Scheduleretraining

검증 게이트를 통과하지 못하거나 Staging 승인이 거부되면 파이프라인이 중단되고 알림이 발송된다는 점, 카나리 배포 중 지연·오류율·드리프트 위반이 감지되면 자동 롤백된다는 점이 이 흐름의 핵심이다.

최소 구현 예시

전제조건은 Python 3.10, mlflow 2.x, scikit-learn, Docker 24+, Kubernetes 1.27+(최신 정보 확인 필요), kubectl 구성 완료다.

학습과 등록은 MLflow Tracking/Registry로 처리한다.

# train_register.py
import mlflow, mlflow.sklearn
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

mlflow.set_tracking_uri("http://mlflow-tracking:5000")  # 또는 file:/.../mlruns
mlflow.set_experiment("iris-rf")

X, y = load_iris(return_X_y=True)
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.2, random_state=42)
with mlflow.start_run() as run:
    model = RandomForestClassifier(n_estimators=200, random_state=42).fit(Xtr, ytr)
    acc = model.score(Xte, yte)
    mlflow.log_metric("accuracy", acc)
    mlflow.sklearn.log_model(model, "model", registered_model_name="iris_rf")
    # 새 버전이 Registry에 생성됨
print("Accuracy:", acc)

모델 서빙 컨테이너는 Dockerfile과 FastAPI로 구성한다.

# Dockerfile
FROM python:3.10-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
RUN pip install --no-cache-dir fastapi uvicorn mlflow scikit-learn
COPY app.py /app/app.py
# 런타임 시 MLFLOW_MODEL_URI 전달 예: models:/iris_rf/Production
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080"]
# app.py
import os, mlflow.pyfunc
from fastapi import FastAPI, HTTPException
import numpy as np

app = FastAPI()
model_uri = os.getenv("MLFLOW_MODEL_URI", "")
if not model_uri:
    raise RuntimeError("MLFLOW_MODEL_URI not set")
model = mlflow.pyfunc.load_model(model_uri)

@app.post("/predict")
def predict(payload: dict):
    try:
        X = np.array(payload["instances"])
        preds = model.predict(X).tolist()
        return {"predictions": preds}
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))

Kubernetes 배포 매니페스트는 카나리용 Replica 분리가 가능한 구조로 작성한다.

# deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: iris-api
spec:
  replicas: 3
  selector: { matchLabels: { app: iris-api } }
  template:
    metadata: { labels: { app: iris-api } }
    spec:
      containers:
        - name: api
          image: your-registry/iris-api:1.0.0
          env:
            - name: MLFLOW_MODEL_URI
              value: "models:/iris_rf/Production"
          ports: [{ containerPort: 8080 }]
          resources:
            requests: { cpu: "200m", memory: "256Mi" }
            limits: { cpu: "1", memory: "512Mi" }
          readinessProbe:
            httpGet: { path: /predict, port: 8080 }
            initialDelaySeconds: 10
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata: { name: iris-api }
spec:
  selector: { app: iris-api }
  ports: [{ port: 80, targetPort: 8080 }]
  type: ClusterIP

운영 팁으로는 kustomize/Helm으로 환경별 오버레이(prod/stage/dev)를 구성하고 커밋 SHA로 이미지를 태깅하는 GitOps, 이미지 서명 검증(admission controller)과 CSI/KMS 암호화·네트워크 정책 기반 egress 제한으로 보안을 강화하는 방법, 요청 타임아웃/재시도·서킷브레이커(서비스 메시)·지표 기반 카나리(Argo Rollouts/Flagger)로 신뢰성을 높이는 방법이 있다.

기대 효과와 도입 순서

자동화된 MLOps 파이프라인을 도입하면 여러 지표에서 개선을 기대할 수 있다. 배포 리드타임은 수작업 대비 7090% 감소해 주 단위 작업이 시간 단위로 줄어들고, 실패 시 MTTR은 자동 롤백을 통해 50% 이상 단축된다. 실험·아티팩트·레지스트리를 일관되게 버전관리하면 재현성과 감사 추적이 향상돼 감사 대응 시간이 60% 이상 단축되고, 자동 스케일링과 리소스 상한 설정으로 피크 외 시간 자원을 3060% 절감할 수 있다. 드리프트·스키마 검증과 승인 게이트를 갖추면 성능 급락 사고율도 50% 이상 감소한다.

Docker로 불변 실행 환경을 확보하고 Kubernetes로 확장·가용성을 보장하며 MLflow로 실험·모델 생애주기를 표준화하는 것이 이 구조의 핵심이다. 여기에 CI/CD/CT 파이프라인과 관측 체계를 동시에 구축하면 운영 리스크를 줄이고 컴플라이언스 대응력도 강화된다. 처음부터 전체 체계를 갖추기보다는 단일 모델·단일 파이프라인으로 시작한 뒤, 지표 기반 카나리와 GitOps를 순차적으로 도입해 점진적으로 확장하는 방식이 현실적이다.

MLOpsDockerKubernetesMLflow모델배포