Search

Airflow docker-compose 리뷰 및 운영 고민 + .airflowignore

Airflow Docker docker-compose.yml 리뷰

Airflow를 Docker Compose로 실행해보자

Docker 기반 Airflow 실행

Docker 기반 Airflow 설치 문서 참조
먼저 터미널 프로그램을 실행하고 적당한 폴더로 이동
airflow-setup Github repo를 클론
airflow-setup 폴더로 이동하고 2.5.1 이미지 관련 yml 파일 다운로드
cd airflow-setup
다음 2개의 명령을 수행 (이미지 다운로드와 컨테이너 실행)
docker-compose -f docker-compose.yaml pull
docker-compose -f docker-compose.yaml up
http://localhost:8080으로 웹 UI 로그인
airflow:airflow 사용
docker-compose file
version
x-airflow-common
airflow-common이라는 별칭 정의. 여러 서비스에서 공유하는 공통 구성을 정의
이를 보통 anchor라고 부르며 YML 파일 블록을 나중에 계승이란 형태로 재사용 가능하게 해줌
version, services, volumes, networks를 제외한 최상위 레벨 키워드는 모두 anchor
아래 서비스들은 디폴트 네트워크에 포함됨
services
postgres
redis
airflow-webserver
airflow-scheduler
airflow-worker
airflow-triggerer
airflow-init
volumes
postgres-db-volume

x-airflow-common

내용
x-airflow-common: &airflow-common image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.5.1} # 1번 environment: &airflow-common-env AIRFLOW__CORE__EXECUTOR: CeleryExecutor _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-} # 4번 volumes: - ${AIRFLOW_PROJ_DIR:-.}/dags:/opt/airflow/dags # 2번 - ${AIRFLOW_PROJ_DIR:-.}/logs:/opt/airflow/logs # 2번 - ${AIRFLOW_PROJ_DIR:-.}/plugins:/opt/airflow/plugins # 2번 user: "${AIRFLOW_UID:-50000}:0" depends_on: &airflow-common-depends-on redis: condition: service_healthy # 3번 postgres: condition: service_healthy # 3번
Python
복사
1.
즉 같은 airflow 이미지가 모든 서비스 기본 이미지로 사용됨
2.
모두 세 개의 volume을 공유함 (host volumes)
3.
모두 redis와 postgres가 정상동작할 때 대기
4.
파이썬 추가 설치 모듈과 관련된 것들은 4번 항목에 작성
&airflow-common 과 같이 &을 붙여주면 해당 indentation에 해당하는 항목들은 위 네이밍을 통해 접근 및 상속 가능 <<: *airflow-common 위와 같이 접근 및 상속 가능 (아래 airflow-scheduler 서비스에서 확인 가능)

airflow-scheduler 서비스 보기

내용
airflow-scheduler: <<: *airflow-common command: scheduler healthcheck: test: ["CMD-SHELL", 'airflow jobs check --job-type SchedulerJob --hostname "$${HOSTNAME}"'] interval: 10s timeout: 10s retries: 5 restart: always depends_on: <<: *airflow-common-depends-on airflow-init: condition: service_completed_successfully
Python
복사
<<: *airflow-common 을 통해 상속 받은 후, 세부 항목들을 오버라이딩 가능하다
command, healthcheck 등을 오버라이딩
airflow-init 서비스가 정상적으로 끝나면 그 때 스케쥴러 서비스 실행
airflow-init : docker container들이 돌 때, 사용하는 리소스들이 충분히 존재하는지 확인하는 컨테이너

Dag를 구현하며 특정 파이썬 모듈을 설치해야한다면?

import yfinance as yf @task def get_historical_prices(symbol): ticket = yf.Ticker(symbol) data = ticket.history()
Python
복사
DAG를 구현하며 새로 생긴 모듈을 어떻게 설치해주어야할까? 일일히 docker container에 들어가서 설치해주는 것은 유지보수도 안되고 불가능! docker-compose.yaml에 답이 있음

Docker compose yml에서 수정된 내용 (환경 변수, 라이브러리 설치)

수정 후 docker-compose.yml (토글 형식)

x-airflow-common에서 _PIP_ADDITIONAL_REQUIREMENTS의 값을 변경
Before:
_PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-}
Python
복사
After:
_PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:- yfinance pandas numpy}
Python
복사
_PIP_ADDITIONAL_REQUIREMENTS은 Python 패키지 관리자인 pip를 통해 설치할 추가적인 패키지의 요구 사항을 정의하는 환경 변수입니다. If 문 같이 사용이 가능합니다
이 변수는 기본적으로 값이 설정되지 않았을 경우 yfinance pandas numpy로 설정됩니다.
data 폴더를 호스트 폴더에서 만들고 볼륨으로 공유: 임시 데이터를 저장할 폴더
이를 docker volume으로 지정해서 나중에 디버깅에 사용
임시 파일이 생기면 호스트 환경에서 볼 수 있게 세팅
임시 파일이 저장될 데이터 주소를 환경 변수 AIRFLOW_VAR_DATA_DIR로 만들어서 컨테이너에서 활용 → 웹 UI에서는 보이지 않지만 컨테이너 간 통신으로 DAG 코드 내에서 Airflow Variable로 활용이 가능해진다
environment: AIRFLOW_VAR_DATA_DIR: /opt/airflow/data _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:- yfinance pandas numpy oauth2client gspread} volumes:- ${AIRFLOW_PROJ_DIR:-.}/data:/opt/airflow/data airflow-init: … mkdir -p /sources/logs /sources/dags /sources/plugins /sources/data chown -R "${AIRFLOW_UID}:0" /sources/{logs,dags,plugins,data}
YAML
복사
airflow-init:
airflow-init 섹션에서 컨테이너 내부의 sources 폴더 밑에 logs, dags, plugin, data 폴더를 만든다
4개의 서브 폴더 주인으로 airflow 유저로 세팅
Detached 모드로 실행하려면 -d 옵션 지정 (-f 옵션도 존재)
docker compose up -d
http://localhost:8080으로 웹 UI 로그인
airflow:airflow 사용
️ 앞서 설정한 DATA_DIR이란 변수는 Admin ⇒ Variables에 안 보임.
DAG과 Airflow 환경 정보들은 Postgres의 Named Volume으로 유지되고 있음
환경변수로 설정한 것들은 Web UI에서는 안 보이지만 프로그램에서는 사용가능
$ docker exec -it learn-airflow-airflow-scheduler-1 airflow variables get DATA_DIR /opt/airflow/data
Python
복사
Variables/Connections 설정을 어떻게 관리하는 것이 좋을까?
이를 docker-compose.yaml에서 환경변수로 설정.

Airflow Docker 운영 방안에 있어 고민사항

고민 포인트: Airflow 실행환경 관리방안

기타 환경설정값들 (Variables, Connections 등등)을 어떻게 관리/배포할까?
보통 docker-compose.yml 파일에서 x-airflow-common → environment 아래 에 정의
x-airflow-common 부분을 대부분 컨테이너 서비스가 상속받음
x-airflow-common: &airflow-commonenvironment: &airflow-common-env AIRFLOW_VAR_DATA_DIR: /opt/airflow/data AIRFLOW_CONN_TEST_ID: test_connection
YAML
복사
환경변수가 아니라 별도 credentials 전용 Secrets 백엔드라는 것을 사용하기도 함 - 아래 링크
️ 앞서 설정한 DATA_DIR이란 변수는 Admin ⇒ Variables에 안 보임.
DAG과 Airflow 환경 정보들은 Postgres의 Named Volume으로 유지되고 있음
환경변수로 설정한 것들은 Web UI에서는 안 보이지만 프로그램에서는 사용가능
$ docker exec -it learn-airflow-airflow-scheduler-1 airflow variables get DATA_DIR /opt/airflow/data
Python
복사
Variables/Connections 설정을 어떻게 관리하는 것이 좋을까?
이를 docker-compose.yaml에서 환경변수로 설정.
어디까지 Airflow 이미지로 관리하고 무엇을 docker-compose.yml에서 관리할지 생각
이는 회사마다 조금씩 다름
Airflow 자체 이미지를 만들고 거기에 넣을지? 이 경우 환경변수를 자체 이미지에 넣고 이를 docker-compose.yaml 파일에서 사용
x-airflow-common: &airflow-common image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.5.1}
YAML
복사
아니면 docker-compose.yaml에서 환경변수를 직접 설정
AIRFLOW_IMAGE_NAME 환경변수가 정의되어 있다면 그걸 사용하고 아니면 기본값으로apache/airflow:2.5.1

고민 포인트: Airflow DAG 관리방안

DAG 코드도 마찬가지
Docker Airflow image로 DAG 코드를 복사하여 만드는 것이 좀더 깔끔
Docker airlfow 이미지를 사용할 것인가
Apache에 있는 이미지를 사용할 것인가
아니면 docker-compose에서 host volume 형태로 설정
이는 개발/테스트용으로 좀더 적합

팁 : .airflowignore

Airflow의 DAG 스캔 패턴은?
airflow는 기본적으로 5분에 한번씩 dags 폴더를 스캔하게끔 세팅이 되어있음
️ dags_folder가 가리키는 폴더를 서브폴더들까지 다 스캔해서 DAG 모듈이 포함된 모든 파이썬 스크립트를 실행해서 새로운 DAG를 찾게 되며 이는 가끔 사고로 이어짐
개발하다만 script를 실행하게끔 하면 어마어마한 부하가 발생할 것
Airflow가 의도적으로 무시해야 하는 DAG_FOLDER의 디렉터리 또는 파일을 지정
dags 폴더 밑에 .airflowignore라는 파일을 생성해서 배치하면 됨
.airflowignore의 각 줄은 정규식 패턴으로 지정하며 매칭되는 파일들은 무시됨
project_a
tenant_[\d]
위의 경우 아래 파일들이 무시됨
project_a_dag_1.py, TESTING_project_a.py, tenant_1.py, project_a/dag_1.py