최근에 팀 airflow
프로젝트를 컨테이너 기반으로 전환하면서 런타임에 디버깅하는 환경을 별도로 구축했어야했는데 Remote - containers
플러그인을 이용하면 운영환경에서 크게 변경없이 디버깅할 수 있어서 사용방법을 간단히 정리해본다. 이 확장을 이용하면 디버깅 용으로 별도 로컬 환경을 구축하지 않아도 컨테이너로 관리하는 서비스들을 운영 이미지 그대로 디버깅할 수 있는데, 아직 preview
버전이긴 하지만 사내에서 사용하고 있는 airflow 이미지 기준으로 문제없이 동작해서 앞으로 요긴하게 잘 쓸 것 같다.
2.2.4 버전 공식 이미지와 커뮤니티에서 제공하는 docker-compose.yml
파일을 이용해서 사용법을 정리해보면,
https://airflow.apache.org/docs/apache-airflow/2.2.4/docker-compose.yaml
다음과 같이 초기 설정을 진행해주고
mkdir -p ./dags ./logs ./plugins
chmod a+rwx ./dags ./logs ./plugins
#echo -e "AIRFLOW_UID=$(id -u)" > .env
docker-compose up airflow-init
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2fbba240865f postgres:13 "docker-entrypoint.s…" 48 seconds ago Up 45 seconds (healthy) 5432/tcp airflow-debug_postgres_1
9113cfcb4bf4 redis:latest "docker-entrypoint.s…" 48 seconds ago Up 45 seconds (healthy) 6379/tcp airflow-debug_redis_1
이어서 위 docker-compose.yml
명세서의 airflow-scheduler 서비스를 제외하고 실행한다.
services:
postgres:
image: postgres:13
...
# 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
airflow-worker:
<<: *airflow-common
command: celery worker
...
이렇게 컨테이너를 실행하면 scheduler 서비스는 기동되지 않은 채로 서비스가 실행되는데 나중에 다른 컨테이너에서 디버거를 붙여서 수동으로 실행해줄 예정이다. 스케줄러 말고 다른 프로세스를 디버깅하고 싶으면 해당 프로세스를 제외하고 실행한다.
# docker-compose up -d
debug-airflow_postgres_1 is up-to-date
debug-airflow_redis_1 is up-to-date
Starting debug-airflow_airflow-init_1 ... done
Creating debug-airflow_airflow-webserver_1 ... done
Creating debug-airflow_flower_1 ... done
Creating debug-airflow_airflow-worker_1 ... done
Creating debug-airflow_airflow-triggerer_1 ... done
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4bda22ed8d3a apache/airflow:2.2.4 "/usr/bin/dumb-init …" 47 seconds ago Up 44 seconds (healthy) 8080/tcp debug-airflow_airflow-triggerer_1
4860e0207530 apache/airflow:2.2.4 "/usr/bin/dumb-init …" 47 seconds ago Up 44 seconds (healthy) 8080/tcp debug-airflow_airflow-worker_1
551a9c164187 apache/airflow:2.2.4 "/usr/bin/dumb-init …" 47 seconds ago Up 43 seconds (healthy) 0.0.0.0:5555->5555/tcp, 8080/tcp debug-airflow_flower_1
e2996c5df253 apache/airflow:2.2.4 "/usr/bin/dumb-init …" 47 seconds ago Up 44 seconds (healthy) 0.0.0.0:8080->8080/tcp debug-airflow_airflow-webserver_1
3a676a1c4789 postgres:13 "docker-entrypoint.s…" About a minute ago Up About a minute (healthy) 5432/tcp debug-airflow_postgres_1
84522e22b760 redis:latest "docker-entrypoint.s…" About a minute ago Up About a minute (healthy) 6379/tcp debug-airflow_redis_1
컨테이너가 다 올라왔을때 웹으로 진입하면 스케줄러가 동작하지 않는다는 에러와 함께 example DAG 가 하나도 로드되지 않는데 이 상태에서 스케줄러 프로세스는 앞으로 디버거와 함께 실행할 예정이다.
다음과 같이 shell 로그인이 default 계정이 아닌 airflow 계정으로 잘 되는지 확인이 됐으면 이어서 remote 환경 세팅을 진행한다.
# docker-compose exec airflow-webserver bash
airflow@e2996c5df253:/opt/airflow$
커맨드 팔레트에서 Remote-Containers: Attach to Running Containers...
메뉴를 선택하고
적당한 airflow 컨테이너를 선택한다. (이 예시에서는 airflow 컨테이너는 전부 같은 이미지여서 아무거나 선택해도 괜찮음.)
다음과 같이 새로운 윈도우로 해당 컨테이너에서 vscode 가 실행되는데, 파일 브라우저를 잘 살펴보면 컨테이너 안에서 실행된 것을 알 수 있다. 실행 초기에 보면 vscode 가 설치되고있다는 팝업이 뜨는데 wsl 처럼 remote 호스트에 vscode-server 가 설치되면서 windows 인터페이스에서 실행되는 것 같다.
디버깅 탭으로 이동해 Run and Debug
버튼을 누르면
다음과 같이 Python
엔트리가 나와야하는데
혹시 리모트 vscode 에 python 패키지가 설치안됐다는 에러가 발생하면 해당 패키지들을 설치해준다. (offline 환경이라면, local의 *.vsix 를 이용해서 설치할 수 있다.)
패키지가 문제없이 설치돼있고 파이썬 엔트리를 선택했다면 이어서 디버깅 설정을 진행한다. Attach using Proccess ID
를 이용해 실행중인 프로세스를 디버깅할 수 있으면 좋을텐데 아직 성공하지 못해서 Python File
을 선택.. (이렇게 진행하려고 디버깅 대상 서비스를 실행하지 않음.)
launch.json
이 없다는 팝업이 발생하면 다음과 같이 디버깅하고자하는 스크립트와 파라미터를 입력해준다.
원래 이 이미지에서 scheduler 프로세스는 다음과 같이 실행되는데
/usr/local/bin/python /home/airflow/.local/bin/airflow scheduler
여기서 맨 앞의 인터프리터는 기본적으로 설정돼 있으니, 두번째 /home/airflow/.local/bin/airflow
스크립트를 program
에 적고, scheduler
를 args
에 입력한다.
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "/home/airflow/.local/bin/airflow",
"console": "integratedTerminal",
"justMyCode": false,
"args": [
"scheduler"
]
}
]
}
이 상태에서 실행 버튼이나 F5
키보드 입력을 누르면 다음과 같이 스케줄러가 실행되고 웹 ui 에서도 example DAG 가 로딩되기 시작한다.
DAG 를 아무거나 하나 on 으로 변경한 다음, 코드에서 breakpoint 를 설정하면
다음과 같이 taskinstance 상태가 곧바로 변경되지 않고 Continue
입력에 따라 진행되는 상태를 모니터링할 수 있다.