외부 GUI 시스템 연동을 위한 Airflow REST API의 한계와 플러그인 도입기
과거 사내 빅데이터 모니터링 플랫폼 워크플로우 디자이너(Workflow Designer) 코어 엔진을 Apache Oozie에서 Apache Airflow(및 GCP Cloud Composer)로 전환하는 기술 검증 단계에서, 가장 큰 걸림돌은 바로 UI 서버와 Airflow 데몬 간의 비동기 통신 규격이었습니다.
플랫폼 사용자가 브라우저에서 ‘실행(Run)’ 버튼을 누르면, 백엔드 스프링 서버가 Airflow 스케줄러로 REST API를 쏴서 파이프라인(DAG)을 강제 트리거해야 했습니다. Oozie 시절에는 풍부한 공식 REST API 스펙이 존재해 손쉬웠지만, 당시 널리 쓰이던 Airflow 1.x (1.10.x 대) 버전은 REST API 스펙에 꽤나 보수적이었습니다.
이때 구글 클라우드 환경과 바닐라 Airflow 환경 양쪽에서 제공하는 API 문서들을 싹 뒤지며 적용한 조사 내용을 갈무리했습니다.
1. Cloud Composer 전용 제어 API (GCP 전용)
구글 Cloud Composer를 쓴다면 Airflow 자체 API가 아닌 구글 Cloud API를 태울 수 있지 않을까 기대했습니다.
composer.projects.locations.environments.list: 현재 조직에 열려있는 컴포저 인스턴스 배열을 반환composer.projects.locations.operations.get: 프로비저닝이나 워커 확장 같은 클라우드 레이어 스케일의 작업 상황 확인
결론: 실패. 구글이 제공하는 저 API들은 철저하게 “인프라의 생사 여부”만 관리하는 Control Plane 영역이지, 그 안에서 돌아가는 Airflow 껍데기 내부의 개별 DAG 스케줄을 찌르는(Data Plane) 엔드포인트가 아니었습니다.
2. Airflow 1.x Experimental REST API
그렇다면 구글의 방화벽 구멍을 뚫고 Airflow 컨테이너 자체의 웹 서버에 직접 API 콜을 던지는 수밖에 없었습니다. Airflow 1.x는 /api/experimental/ 형태의 제한된 라우터를 제공했습니다.
GET /api/experimental/dags/<DAG_ID>/tasks/<TASK_ID>: 특정 깡통 DAG 내부의 작업 구성 정보 읽기POST /api/experimental/dags/<DAG_ID>/dag_runs: 특정 DAG 강제 트리거 (주입할 파라미터confJSON 페이로드 지원)
가장 결정적인 기능인 ‘강제 실행(Trigger)‘은 저 POST 메서드를 통해 가까스로 구현하여 UI단과 엮는 데 성공했습니다.
한계점: 하지만 특정 Task 노드의 로그만 당겨오거나, 멈춘 위치에서부터 재시작(Clear & Resume)하는 정교한 컨트롤러 API가 존재하지 않았습니다. 플랫폼 UI에서 파이프라인 재시작 버튼을 만들 수가 없는 치명적인 결함이었습니다.
3. 탈출구: Airflow Custom Plugin API 개발
기본 내장 API의 허술함을 커버하기 위해, 아예 우리가 직접 파이썬 Flask 백엔드(Airflow Webserver의 뼈대)에 플러그인을 주입하여 커스텀 API 라우터를 뚫어버리자는 돌파구를 사용했습니다.
- Airflow REST API Plugin (오픈소스): 깃허브에 돌아다니는 유저들이 만들어둔 플러그인으로, 내부적으로 리눅스의
airflow {command}CLI 명령어 텍스트 결과를 가로채어 JSON으로 리턴해주는 무식하지만 효과적인 트릭이었습니다. - 커스텀 Plugin 개발: 하지만 Celery Executor 기반의 다중 워커 노드 환경에서는 CLI 가로채기가 꼬이는 현상이 있어, 결국 Airflow의
models.py를 직접 임포트하여 ORM DB를 직접 읽어와 응답(Response)을 던져주는 API 플러그인을 사내에서 하드코딩해야만 했습니다.
현재 Airflow 2.0 이상 버전부터는 자체적으로 아주 풍부하고 완벽한 Stable REST API를 공식 제공합니다. 당시 Airflow의 성숙기를 기다리며 바닥부터 플러그인을 깎았던 것은 클라우드 데이터 파이프라인의 이면을 뼛속까지 이해하는 계기가 되었습니다.