직접 짠 코드나 모델을 다른 사람에게 넘겼을 때, “내 컴퓨터에서는 됐는데요(it works on my machine)“라는 말을 해 본 적이 있을 것이다. 분석 노트북 하나를 동료에게 보냈더니 라이브러리 버전이 안 맞아 실행이 안 되고, 잘 돌던 모델 학습 스크립트를 서버에 올렸더니 처음 보는 에러가 쏟아진다. 이 시리즈는 바로 그 문제, “내가 만든 것을 언제 어디서나 똑같이 돌아가게 만드는 일” 을 다룬다.

무엇이 문제인가

소프트웨어나 ML 모델 하나를 실제로 굴리려면, 코드 자체만으로는 부족하다. 코드는 항상 환경(environment) 위에서 실행된다.

  • OS와 시스템 라이브러리: Windows냐 Linux냐, 어떤 시스템 패키지가 깔려 있느냐.
  • 언어 런타임과 패키지: Python 3.10이냐 3.12냐, NumPy·PyTorch 버전은 무엇이냐.
  • 설정과 자원: 환경 변수, 파일 경로, GPU 유무, 메모리 크기.

내 PC에서 코드가 도는 이유는 코드가 훌륭해서가 아니라, 마침 그 환경이 코드가 기대하는 모습과 맞아떨어졌기 때문이다. 환경이 조금만 달라져도 같은 코드가 다르게 동작하거나 아예 멈춘다. 이것을 재현성(reproducibility) 문제라고 부른다.

여기에 더해, 실제 서비스 단계로 가면 문제가 두 가지 더 생긴다.

  • 배포·확장(deployment & scaling): 한 대의 PC가 아니라 여러 대의 서버에 똑같은 것을 올려야 하고, 트래픽이 몰리면 그 수를 늘렸다가 줄여야 한다. 한 대가 죽으면 자동으로 살아나야 한다.
  • 반복 실행·자동화(orchestration): 데이터 수집 → 전처리 → 학습 → 평가처럼 여러 단계가 정해진 순서와 일정대로 매일 자동으로 돌아가야 한다. 중간 단계가 실패하면 그 사실을 알고, 적절히 재시도해야 한다.

세 가지 도구가 각각 푸는 문제

이 시리즈가 다루는 Docker·Kubernetes·Airflow는 위 세 문제를 차례로 해결하는 도구다. 서로 경쟁하는 기술이 아니라, 작은 단위에서 큰 단위로 층층이 쌓이는 관계라고 보면 된다.

[Airflow]   여러 작업을 "언제, 어떤 순서로" 돌릴지 스케줄링·자동화
   │  (워크플로 오케스트레이션)
   ▼
[Kubernetes] 수많은 컨테이너를 "여러 서버에 걸쳐" 배포·확장·복구
   │  (컨테이너 오케스트레이션)
   ▼
[Docker]    코드 + 환경을 통째로 "컨테이너"로 포장해 어디서나 동일 실행
            (재현성·이식성)
  • Docker — 재현성: 코드와 그 코드가 필요로 하는 환경(OS 라이브러리, 패키지, 설정)을 컨테이너(container) 라는 하나의 표준 단위로 포장한다. 이 컨테이너는 내 PC에서든 동료의 노트북에서든 클라우드 서버에서든 똑같이 실행된다. “내 PC에서만 되는” 문제의 근원을 없앤다.

  • Kubernetes — 배포·확장: 컨테이너가 하나둘일 때는 직접 켜고 끄면 되지만, 수십·수백 개가 여러 서버에 흩어지면 사람 손으로 관리할 수 없다. Kubernetes는 “이런 컨테이너를 3개 항상 띄워 두라” 처럼 원하는 상태를 선언하면, 그 상태를 유지하도록 배포·확장·장애 복구를 자동으로 해 주는 컨테이너 오케스트레이터(orchestrator) 다.

  • Airflow — 자동화: 개별 컨테이너가 잘 도는 것과, 여러 작업을 정해진 순서·일정대로 엮어 돌리는 것은 다른 문제다. Airflow는 “A가 끝나면 B와 C를 돌리고, 둘 다 끝나면 D를 돌려라” 같은 작업 흐름을 DAG(방향성 비순환 그래프) 로 정의하고, 매일 정해진 시각에 실행하며 실패를 감지·재시도하는 워크플로 스케줄러다.

이 시리즈의 흐름

위 그림의 아래에서 위로, 작은 개념부터 쌓아 올린다.

  1. Docker (컨테이너) — 컨테이너의 개념(VM과의 차이), Dockerfile로 이미지를 만드는 법, 데이터 저장과 컨테이너 간 통신.
  2. Kubernetes (오케스트레이션) — 왜 오케스트레이션이 필요한지, Pod·Deployment·Service 같은 핵심 구성 요소, “원하는 상태 선언”이라는 사고방식.
  3. Airflow & DAG (워크플로 스케줄링) — DAG로 작업 의존성을 표현하는 법, Airflow의 구조, 실제 파이프라인 작성.

마지막에는 이 셋을 하나로 엮어, Airflow가 스케줄링한 작업이 Kubernetes 위에서 Docker 컨테이너로 실행되는 전형적인 MLOps 파이프라인의 모습을 조망한다.

요약

  • 코드는 항상 환경 위에서 돌기 때문에, 환경이 달라지면 같은 코드도 다르게 동작한다 → 재현성 문제.
  • 실제 운영에서는 여기에 배포·확장자동화·스케줄링 문제가 더해진다.
  • Docker(재현성) → Kubernetes(배포·확장) → Airflow(자동화)는 작은 단위에서 큰 단위로 쌓이며 이 문제들을 차례로 해결한다.
  • 다음 글부터 가장 아래층인 컨테이너(Docker)부터 시작한다.