brandonwie.dev
EN / KR
On this page
devops devopsairflowdeploymentgitopswork

DAG 배포 전략

Airflow DAG를 배포하는 다양한 방법과 트레이드오프 분석

Updated March 22, 2026 5 min read

EC2에서 Docker Compose로 Airflow를 셋업하면서 반나절을 블로그, Helm chart 기본값, GitHub issues를 읽는 데 썼어요. 딱 하나의 질문에 답하려고요: Git에 있는 DAG 파일을 실행 중인 Airflow 컨테이너에 어떻게 전달하지? Airflow 공식 문서는 여러 방법을 설명하면서도 하나를 추천하지 않고, 초반에 잘못된 전략을 고르면 나중에 마이그레이션이 고통스러워져요.

왜 중요한가

DAG 배포 전략은 한 번 정하면 몇 달은 같이 가는 결정이에요. 반복 속도(DAG 변경을 얼마나 빨리 테스트할 수 있는지), 운영 안정성(DAG 배포가 스케줄러를 재시작하는지), 보안(EC2 인스턴스에 뭐가 노출되는지) 모두에 영향을 줘요. 대부분의 가이드가 DAG 배포와 애플리케이션 배포를 묶어서 설명하는데, DAG 파일이 바뀔 때마다 Docker 이미지를 새로 빌드하게 되죠. 이 둘은 별개의 관심사이고, 섞으면 불필요한 다운타임이 생겨요.


겪었던 어려움

  • 단일 추천 방법이 없음 — Airflow 문서는 여러 전략을 설명하면서 “EC2에는 이걸 쓰세요”라고 하지 않아요. 블로그, GitHub issues, Helm chart 기본값을 조합해서 트레이드오프를 파악해야 했어요.
  • DAG 배포와 코드 배포를 혼동 — 초기 리서치에서 DAG Python 파일 배포와 Airflow 애플리케이션(Docker 이미지) 배포를 혼동했어요. 대부분의 가이드가 이걸 묶어서 설명하지만, 실제로는 별개의 관심사예요.
  • Git-sync sidecar 문서가 Kubernetes를 가정 — 가장 많이 문서화된 git-sync sidecar 방식이 Kubernetes 네이티브예요. Docker Compose + EC2 환경에 맞추려니 맞지 않는 패턴을 억지로 적용하는 느낌이었어요.
  • EC2에 전체 repo를 두면 보안 이슈 — EC2에 전체 repository를 클론하면 DAG가 아닌 파일(자격 증명, CI 설정)도 노출돼요. .gitignore와 deploy key로 충분한지 평가해야 했어요.

검토한 옵션

옵션장점단점
EC2에 전체 Git Repo간단한 셋업, 빠른 배포, 제로 다운타임, 익숙한 Git 워크플로우EC2에 전체 repo 노출, Git 인증 필요, 자동 동기화 아님
DAG를 Docker Image에 포함불변, 버전 관리, EC2에 Git 불필요느림(리빌드 + 재시작), DAG 핫 리로드 불가
Git-Sync Sidecar자동 동기화, K8s 표준, 재시작 불필요Sidecar 컨테이너 필요, Kubernetes용으로 설계
S3/EFS SyncAWS 네이티브, 멀티 리전 지원추가 인프라(S3 또는 EFS), 동기화 지연

각 방식은 서로 다른 인프라 형태를 목표로 해요. 올바른 선택은 팀 규모, 플랫폼(EC2 vs Kubernetes), DAG 변경 빈도에 따라 달라져요.


결정: EC2에 전체 Git Repo

제 상황에는 명확한 제약이 있었어요:

  • 2명의 소규모 팀, EC2 기반 인프라 (Kubernetes 아님)
  • DAG 변경이 잦고 빠른 반복이 필요 (분 단위가 아니라 초 단위)
  • 제로 다운타임이 중요 — DAG만 바꿀 때 컨테이너 재시작 불가
  • Git이 내장 버전 관리와 즉시 롤백을 제공
  • 단점(repo 노출, 인증)은 deploy key와 .gitignore로 쉽게 완화 가능

네 가지 주요 방식

1. EC2에 전체 Git Repo

EC2 /opt/airflow/          <- 전체 Git repository
├── dags/                  <- DAG 파일
├── master/
│   └── docker-compose.yml
├── worker/
└── .git/

EC2 인스턴스에 git clone으로 전체 repository를 두고, git pull로 변경 사항을 동기화해요. 컨테이너가 dags/ 폴더를 volume-mount하기 때문에 Airflow가 재시작 없이 변경을 감지해요.

소규모 팀(2-10명)이 EC2 기반 인프라에서 잦은 DAG 변경을 할 때 적합해요.

2. Docker Image에 DAG 포함 (Bake into Image)

# Dockerfile
COPY dags/ /opt/airflow/dags/

DAG 파일을 Docker 이미지 빌드 시점에 포함해요. DAG 변경 시 이미지 리빌드와 컨테이너 재시작이 필요해요. 엄격한 버전 관리가 필요한 불변 인프라에 적합해요 — 모든 배포가 감사 가능한 이미지 태그가 돼요.

3. Git-Sync Sidecar (Kubernetes 표준)

# Kubernetes Pod
containers:
  - name: scheduler
    image: airflow
  - name: git-sync # 별도 컨테이너
    image: git-sync
    args: ["--repo=https://github.com/...", "--branch=main"]

별도의 git-sync 컨테이너가 주기적으로 repository에서 공유 볼륨으로 pull해요. Airflow 컨테이너가 그 볼륨을 읽어요. Kubernetes 환경의 표준 패턴이고 대규모 팀에 잘 확장돼요.

4. S3/EFS Sync

S3 bucket                    EC2
s3://airflow-dags/   --->  /opt/airflow/dags/

DAG 파일을 S3에 업로드하고, EC2가 aws s3 sync로 동기화해요. 또는 EFS를 직접 마운트할 수도 있어요. S3 복제로 분배를 처리하는 AWS 네이티브 워크플로우, 특히 멀티 리전 배포에 적합해요.


비교 매트릭스

기준EC2 Git RepoImage에 포함Git-SyncS3/EFS
셋업 복잡도낮음낮음중간중간
DAG 변경 속도빠름 (git pull)느림 (리빌드)빠름빠름
컨테이너 재시작불필요필요불필요불필요
추가 인프라없음없음SidecarS3/EFS
적합한 환경EC2 소규모 팀불변 인프라KubernetesAWS 네이티브
팀 규모2-10무관대규모중-대규모

결정 트리

인프라가 뭔가요?
├─ Kubernetes
│   └─ Git-Sync Sidecar 사용

├─ EC2 + 소규모 팀 (10명 미만)
│   └─ EC2에 전체 Git Repo 사용

├─ 엄격한 불변 요구사항
│   └─ Image에 포함 방식 사용

└─ AWS 네이티브, 멀티 리전
    └─ S3/EFS Sync 사용

EC2 Git Repo: 상세 워크플로우

디렉토리 구조

EC2 /opt/airflow/
├── .git/
├── dags/
│   ├── __init__.py
│   └── my_pipeline.py    # <- 여기 변경하면 자동 동기화
├── master/
│   ├── docker-compose.yml
│   └── docker-compose.prod.yml
└── worker/
    └── docker-compose.yml

배포 흐름

1. 개발자가 DAG 수정
   └── git push origin main

2. GitHub Actions 트리거
   └── dags/ 변경 감지

3. SSM 명령으로 EC2에 전달
   └── cd /opt/airflow && git pull

4. 스케줄러 감지 (~30초)
   └── 새 DAG 파싱 완료

컨테이너 재시작: 불필요
다운타임: 없음
반영 시간: ~30초

핵심은 Airflow 스케줄러가 설정 가능한 간격(기본 ~30초)으로 dags/ 디렉토리를 폴링한다는 거예요. 단순한 git pull 하나면 DAG 변경이 배포돼요. 이미지 빌드도, 컨테이너 재시작도, 다운타임도 없어요.

장점

장점설명
간단함추가 인프라 불필요 (S3, EFS, git-sync 컨테이너)
빠른 배포git pull 한 번으로 DAG 동기화
익숙한 워크플로우표준 Git 기반 배포
제로 다운타임DAG 변경 시 컨테이너 재시작 불필요
버전 관리Git 히스토리로 DAG 변경 추적
쉬운 롤백git checkout <commit>으로 즉시 롤백

단점

단점설명완화 방법
Git 의존성EC2에 Git 필요Amazon Linux에 Git 내장
전체 repo 노출EC2에 불필요한 파일 존재.gitignore로 민감한 파일 제외
인증 필요Private repo에 자격 증명 필요Deploy Key 또는 HTTPS + PAT
수동 동기화자동 동기화 아님CI/CD 자동화 (SSM)

왜 이 방식이 효과적인가

핵심은 관심사의 분리예요. DAG 파일은 자주 바뀌는 코드지만, Airflow 애플리케이션(Docker 이미지)은 드물게 바뀌어요. Git으로 관리되는 dags/ 디렉토리를 volume-mount하면 DAG 변경은 Git을 통해 흐르고, 애플리케이션은 안정적으로 유지돼요. 리빌드도, 재시작도, 다운타임도 없어요.

/opt/airflow 컨벤션은 Linux 표준에서 나왔어요. /opt는 서드파티 소프트웨어를 위한 표준 디렉토리이고, Apache Airflow 공식 문서에서 AIRFLOW_HOME=/opt/airflow를 기본값으로 사용해요.

/opt        <- 서드파티 앱 (Airflow, Jenkins 등)
/usr        <- 시스템 설치 소프트웨어
/home       <- 사용자 홈 디렉토리

실전 팁

이 결정 프레임워크를 활용하세요:

  • EC2 또는 Docker Compose에 Airflow 배포 — 전체 Git repo 방식으로 시작하세요. 빠른 반복을 지원하는 가장 간단한 경로예요.
  • 새 클러스터 셋업 — 위의 비교 매트릭스로 반복 속도, 보안, 팀 규모 사이의 트레이드오프를 평가하세요.
  • 현재 방식을 넘어서야 할 때 — 아래 마이그레이션 표를 가이드로 활용하세요.

마이그레이션 시점

상황추천 변경
Kubernetes 도입Git-Sync Sidecar
보안 강화Image에 포함
멀티 리전 배포S3 + CloudFront
DAG 10개+, 팀 5명+Git-Sync 또는 S3

각 전략을 쓰면 안 되는 경우

  • EC2 전체 Git Repo — repository에 .gitignore로 제외할 수 없는 비밀이 있거나, 감사 가능한 이미지 태그가 필요한 불변 배포가 필수인 경우 사용하지 마세요.
  • Image에 포함 — DAG 반복 속도가 중요한 경우 사용하지 마세요. DAG 변경마다 리빌드하고 재시작하면 개발 중 허용할 수 없는 피드백 루프가 생겨요.
  • Git-Sync Sidecar — 일반 EC2나 Docker Compose 환경에서 사용하지 마세요. Kubernetes 밖에서 sidecar 패턴은 불필요한 복잡성만 추가해요.
  • S3/EFS Sync — DAG 배포의 엄격한 버전 관리가 필요한 경우 사용하지 마세요. S3 sync는 Git처럼 원자적 업데이트나 롤백 보장을 제공하지 않아요.

Comments

enko