23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
"이 Task는 예전 코드로 실행됐던 거였나?"
Airflow를 운영하다 보면 한 번쯤은 이런 고민을 해보신 경험이 있으실 겁니다.
그런데 반가운 소식!
지난 달 말에 출시된 Airflow 3.0 버전에서 DAG Versioning 기능이 도입되었습니다 ㅎㅎ 🎉
이제 Airflow UI 상에서 DAG의 변경 이력을 추적하고, 각 task가 어떤 DAG 버전으로 실행되었는지 확인할 수 있게 되었습니다.
이 글에서는 DAG Versioning이 무엇인지, 왜 중요한지, 그리고 어떻게 사용하는지를 정리해 보려고 합니다.
앞으로 DAG 관리를 훨씬 체계적으로 관리할 수 있으실 거예요!
Airflow 2.x까지는 DAG 실행과 UI 모두 항상 로컬의 최신 DAG 코드를 기준으로 작동했습니다.
이로 인해 다음과 같은 두 가지 문제점이 발생하곤 했습니다:
DAG 수정 시, 삭제된 태스크가 Airflow UI에서 사라짐
DAG 실행 중 코드가 바뀌면, 일부 태스크는 이전 코드, 나머지는 수정된 코드로 실행됨
이러한 문제를 해결하기 위해, Airflow 3.x 버전에서는 DAG Bundles와 DAG Versioning 이 도입되었습니다.
Airflow 3.x 에서는 기존의 dags/ 폴더에 파일을 두는 구조 대신, DAG 코드를 하나의 단위로 묶는 DAG Bundle이라는 개념이 도입되었습니다.
DAG Bundle에는 두가지 종류가 있습니다.
종류 | 설명 | 버전 관리 |
|---|---|---|
LocalDagBundle | 기존처럼 | 안됨 |
GitDagBundle | Git 저장소에서 DAG 코드를 불러옴 | 가능 |
DAG Bundle 구조 덕분에 Airflow는 DAG 실행 시 해당 시점의 DAG 코드 상태를 버전(v1, v2, ...)으로 고정할 수 있게 되었습니다.
이제 직접 실습을 통해 DAG Versioning을 어떻게 사용하는지 알아보겠습니다.
Airflow 3.x 환경이 이미 구성되어 있다면 바로 사용해보실 수 있지만, 이 글에서는 더 간편한 방법으로 Astro CLI를 활용하겠습니다.
Astro CLI 설치와 사용법은 아래의 공식 문서와 글을 통해서 알아보실 수 있습니다.
https://www.astronomer.io/docs/astro/cli/install-cli
https://discourse.airflow-kr.org/t/apache-airflow-astro-cli/336
설치 후, 버전을 확인합니다:
$ astro version
Astro CLI Version: 1.34.0Astro CLI의 버전이 1.34.0 이라면 Airflow 3 버전을 지원하므로 이 글의 내용을 그대로 따라 하실 수 있습니다.
만약 버전이 더 낮다면, 최신 버전으로 업그레이드해 주세요.
이제 실습을 위한 예제 프로젝트를 포크하고 클론해줍니다.
https://github.com/AirflowKorea/dag-versioning-example
git clone https://github.com/{username}/dag-versioning-example.git
cd dag-versioning-example간단한 dag_versioning_example라는 이름의 DAG를 작성해보았습니다.
from airflow.sdk import dag, task, chain
from pendulum import datetime
@dag(
schedule="@daily",
start_date=datetime(2025, 5, 1),
tags=["example", "dag_versioning"],
default_args={
"owner": "Airflow Korea",
"retries": 3,
},
)
def dag_versioning_example():
@task
def task_1():
print("Hello! task_1")
@task
def task_2():
print("Hello! tast_2")
chain(
task_1(),
task_2(),
)
dag_versioning_example()이 상태에서 astro dev start 명령어로 Airflow를 실행하면
http://localhost:8080에서 Airflow 3의 새 UI를 볼 수 있어요.
왼쪽 사이드바의 Dags를 통해서 현재 DAG들을 볼 수 있는데요.
저희가 만든 dag_versioning_example DAG가 있는 것을 확인할 수 있습니다.
DAG를 선택해서 보면, 자세한 DAG에 대한 정보를 볼 수 있습니다.
DAG의 버전과 관련된 내용은 우측 상단의 Latest Dag Version을 통해서 확인할 수 있습니다.
현재 버전은 v1버전으로 되어있는 것을 볼 수 있습니다.
DAG버전은 Trigger를 기점으로 지정이 되므로 Trigger를 해봅시다.
이렇게 DAG가 한 번 실행되면 v1으로 고정됩니다.
그럼 DAG를 수정을 해봅시다. 아래의 코드 처럼 task_3을 추가했습니다.
from airflow.sdk import dag, task, chain
from pendulum import datetime
@dag(
schedule="@daily",
start_date=datetime(2025, 5, 1),
tags=["example", "dag_versioning"],
default_args={
"owner": "Airflow Korea",
"retries": 3,
},
)
def dag_versioning_example():
@task
def task_1():
print("Hello! task_1")
@task
def task_2():
print("Hello! tast_2")
@task
def task_3():
print("Hello! tast_3")
chain(
task_1(),
task_2(),
task_3(),
)
dag_versioning_example()변경 후 저장하고 UI에서 다시 DAG를 Trigger하면,
이제 새로운 실행은 v2로 관리됩니다.
그래프 뷰에서 각 버전별로 task가 어떻게 구성되어있는지도 확인가능합니다.
앞선 설명에서 LocalDagBundle은 버전관리가 안된다고 했었는데, v1, v2로 잘되는 것으로 보입니다.
하지만 이는 UI상에서만 DAG가 수정되었다는 사실만 확인이 가능한 것입니다.
간단하게 이 사실을 확인가능 한 것이 v1으로 실행된 DAG를 재실행하면 아래와 같이 최신 DAG코드로 실행이 된 것을 확인할 수 있습니다.
LocalDagBundle와 GitDagBundle을 비교하면 아래와 같습니다.
LocalDagBundle | GitDagBundle | |
|---|---|---|
과거 DAG 재실행 | 최신 DAG 코드 사용 | 당시 DAG 버전 코드 사용 |
개별 task 재실행 | 최신 DAG 코드 사용 | 당시 DAG 버전의 task 코드 사용 |
DAG 실행 중 코드 변경 | 새 코드로 계속 실행 | 기존 DAG 버전 코드로 끝까지 실행 |
그래서 LocalDagBundle은 개발환경에서는 적합하지만, DAG의 버전 관리가 되지 않는다고 볼 수 있습니다.
예를 들어 v1 실행을 다시 Run하면 v2 코드가 사용되는 등, 버전 고정이 되지 않습니다.
앞서 설명한 LocalDagBundle은 버전을 만들 수는 있지만, 관리할 수는 없습니다.
버전을 관리하기 위해서는 GitDagBundle을 사용해야하는데요.
apache-airflow-provider-git Provider 와 git 설치requirements.txt에 apache-airflow-provider-git를 추가해줍니다.
provider의 최신버전은 아래의 링크에서 확인하실 수 있습니다.
https://airflow.apache.org/docs/apache-airflow-providers-git/stable/index.html
packages.txt에도 git을 추가해줍니다.
.env 수정
GitHub에서 Personal Access Token을 발급받고, .env에 host부분에는 저장소의 레포지토리 주소와 password부분에는 발급받은 토큰을 설정해줍니다.
AIRFLOW_CONN_GIT_DEFAULT='{
"conn_type": "git",
"host": "https://github.com/<account>/<repo>.git",
"password": "github_token"
}'
AIRFLOW__DAG_PROCESSOR__DAG_BUNDLE_CONFIG_LIST='[
{
"name": "git-dags-bundle",
"classpath": "airflow.providers.git.bundles.git.GitDagBundle",
"kwargs": {
"git_conn_id": "my_git_conn",
"subdir": "dags",
"tracking_ref": "main",
"refresh_interval": 10
}
}
]'깔끔하게 정리하고 싶다면, 아래의 명령어로 컨테이너를 지우고 다시 시작해줍니다.
astro dev stop && astro dev kill
astro dev start그럼 아래와 같이 Git 저장소에서 DAG를 불러오고, DAG를 트리거하면 v1 버전으로 실행되는 것을 확인할 수 있습니다.
그럼 DAG를 수정해봅시다. 이번에는 이전에 추가했던 task_3를 삭제해보겠습니다.
수정하고 trigger를 해봅니다.
task_3를 삭제했는데 task_3가 실행되는 것을 확인해볼 수 있습니다.
이는 DAG를 깃허브 저장소에서 가져오기 때문입니다. 반드시 Git에 커밋되어야 새로운 버전이 적용됩니다.
커밋을 하고 다시 trigger해줍니다.
task_3가 사라지고 버전이 v2로 고정된 것을 확인할 수 있습니다.
그리드 뷰에서도 버전을 잘 확인할 수 있습니다.
그리고 task_3를 다시 돌려놓고 다시 커밋을 하면 v3로 정상적으로 버전이 잘 올라가는 것을 확인할 수 있습니다.
그럼 지금 task_3가 없었던 v2 DAG를 트리거 할 수 있는지 볼까요?
DAG를 Clear Run을 해봅시다.
정상적으로 잘 되는 것을 확인할 수 있습니다.
v1 버전도 진행해봅시다.
정상적으로 잘 실행되는 것을 확인 할 수 있습니다.
DAG Versioning의 진가를 느낄 수 있는 부분은 바로 각 DAG run에서 정확히 어떤 코드가 사용되었는지 확인할 수 있다는 점입니다.
각 DAG run의 Detail 을 확인해보면 DAG의 버전에 어떤 Bundle에 대한 자세한 설명과 어떤 코드가 사용되었는지 확인해볼 수 있습니다.
Airflow 3.x에 도입된 DAG Versioning 기능은 정말 반가운 변화입니다.
이제는 “어..? 이거 코드 바뀌기 전이었나?” 같은 고민 없이,
정확히 어떤 DAG 코드로 실행되었는지 추적할 수 있게 됐어요.
그리고 과거 버전의 DAG도 안정적으로 재실행할 수 있어서 운영 환경에서의 신뢰성도 훨씬 올라갑니다.
이제 DAG도 코드처럼 관리하고, 히스토리도 남기고, 필요한 시점으로 돌아가는 게 자연스러워졌습니다.
궁금한 점이나 Apache Airflow에 대해서 더 다뤄줬으면 하는 내용이 있다면 댓글로 알려주세요 😉
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.