jupyter

1 개의 포스트

kakao

개인화된 Airflow 테스트 환경 구축 및 운영 경험 (새 탭에서 열림)

수천 개의 Airflow DAG를 운영하는 카카오 데이터서비스 조직은 테스트 과정의 반복 작업과 환경 간 차이, 리소스 충돌 문제를 해결하기 위해 PR 단위의 개인 Airflow 환경인 AirZone을 구축했습니다. AirZone은 GitHub PR 코멘트에서 생성·삭제를 요청하면 Kubernetes Job과 전용 Helm 차트로 격리된 Airflow를 배포합니다. 사용자는 인프라를 직접 구성하지 않고 실제 운영 환경과 유사한 하둡·인증 환경에서 DAG를 테스트할 수 있습니다. ## 기존 테스트 방식의 한계 - **로컬 Airflow** - Airflow뿐 아니라 하둡 인증, 연결 설정, Docker 환경까지 직접 구성해야 합니다. - 초기 구축 비용이 크고, 로컬 환경과 운영 환경의 차이로 인해 실제 배포 후 실패할 수 있습니다. - **개발용 Airflow** - 코드를 커밋하고 푸시한 뒤 GitHub webhook, submodule 업데이트, DAG 파일 처리 과정을 기다려야 합니다. - DAG를 수정할 때마다 동기화 지연이 반복되어 개발 속도를 떨어뜨렸습니다. - **테스트용 Airflow** - SSH 컨테이너에 로컬 파일을 복사해야 하므로 코드 수정 때마다 추가 작업이 필요합니다. - 실제 데이터와 하둡에 접근하려면 prod VPN을 연결해야 하는 불편도 있었습니다. - **Production Airflow에서의 테스트** - 테스트 DAG가 스케줄러와 워커 자원을 점유해 다른 프로젝트의 실행을 지연시킬 수 있습니다. - 과도한 리소스 사용으로 노드 장애가 발생하면 같은 노드의 다른 태스크까지 중단될 위험이 있습니다. ## AirZone의 핵심 요구사항 - Kubernetes나 Helm을 몰라도 브라우저에서 Airflow 환경을 생성하고 삭제할 수 있어야 합니다. - 사용자는 DAG 검증에만 집중하고, 인프라 구성은 AirZone이 담당해야 합니다. - Jupyter Notebook을 제공해 별도 로컬 환경 없이 코드를 수정할 수 있어야 합니다. - 운영 환경과 유사한 DAG 실행 환경과 하둡 인증 방식을 제공해야 합니다. - PR마다 독립된 Airflow를 생성해 사용자와 테스트 작업을 서로 격리해야 합니다. ## PR 단위의 격리된 환경 - 레포지터리명과 PR 번호를 조합해 Kubernetes 네임스페이스를 생성합니다. - Airflow 웹 서버, 스케줄러, PostgreSQL, Jupyter, DAG PVC, 로그가 PR별로 분리됩니다. - 한 PR의 테스트가 다른 프로젝트의 스케줄러·워커 자원을 침범하지 않습니다. - 리뷰어는 PR에 남은 링크로 특정 코드 상태의 실행 결과를 직접 확인할 수 있습니다. - PR이 종료되면 네임스페이스를 기준으로 관련 리소스를 쉽게 정리할 수 있습니다. ## 요청 처리와 배포 작업의 분리 - `airzone-api`는 PR 존재 여부, PR이 열려 있는지, 네임스페이스 중복 여부 등 요청의 유효성만 검증합니다. - 실제 Helm 설치와 헬스체크는 별도의 Kubernetes Job이 수행합니다. - API가 수 분이 걸리는 배포 작업을 직접 기다리지 않으므로 빠르게 응답할 수 있습니다. - Job별로 상태와 로그가 독립적으로 남아 실패 단계와 원인을 추적하기 쉽습니다. - 실패한 Job을 삭제한 뒤 새 Job을 생성하는 방식으로 배포를 재시도할 수 있습니다. - 생성 요청은 `create-airzone-{namespace}`, 삭제 요청은 `delete-airzone-{namespace}` 형식의 Job 이름을 사용합니다. ## GitHub PR 코멘트를 사용자 인터페이스로 활용 - PR 생성 이벤트를 webhook으로 받아 저장소, 브랜치, PR 번호, 요청자 정보를 확인합니다. - 사용자가 선택할 수 있도록 하둡 환경별 AirZone 생성 링크를 PR 코멘트에 남깁니다. - 생성 완료 결과와 접속 정보도 PR에 표시해 별도 플랫폼 없이 테스트를 시작할 수 있습니다. - 다만 Jupyter 토큰과 Kubernetes 네임스페이스 토큰처럼 민감한 정보는 공개 범위가 넓은 PR 대신 카카오워크로 전달합니다. - 요청 접수와 배포 완료 시점에 카카오워크 알림을 보내 진행 상태를 알립니다. ## 전용 Helm 차트로 구성한 Airflow 기존 운영용 Airflow 차트가 아닌 AirZone 전용 Helm 차트를 만들어 테스트 환경에 필요한 구성만 묶었습니다. - **Airflow 구성** - 웹 서버와 스케줄러를 배포합니다. - `KubernetesExecutor`, DAG 스캔 주기, 로그 설정, 하둡 관련 변수를 테스트 환경에 맞게 설정합니다. - **데이터베이스와 저장소** - 개인 환경용 PostgreSQL을 함께 배포합니다. - scheduler와 Jupyter가 같은 DAG 작업 디렉터리를 사용하도록 DAG PVC를 공유합니다. - **DAG 동기화** - PR의 head repository와 branch 정보를 받아 해당 코드만 동기화합니다. - Git 초기화 컨테이너 등을 통해 배포 환경에 테스트 대상 DAG를 준비합니다. - **인증과 보안** - 사용자·공용 principal, 키탭, Jupyter 토큰을 환경에 주입합니다. - 하둡 접근에 필요한 Kerberos 인증을 운영 환경과 유사하게 구성합니다. - dkos에서 제공하는 TLS 인증서도 테스트 환경에 반영합니다. - **운영 연동** - 여유 있는 노드 그룹과 같은 리전의 `storageClass`를 선택합니다. - Airflow 로그를 Elasticsearch와 Kibana에서 확인할 수 있도록 연결 정보를 주입합니다. - Jupyter를 함께 제공해 브라우저에서 DAG와 관련 코드를 수정할 수 있게 합니다. ## 자동 정리와 운영 구조 - 생성·삭제 요청은 Kubernetes Job으로 처리합니다. - PR 종료 후 남아 있는 AirZone은 매일 실행되는 CronJob이 자동으로 회수합니다. - 사용자에게는 “PR 코멘트의 링크를 누르는 기능”으로 단순하게 보이지만, 운영자는 요청·설치·헬스체크·알림·정리 단계를 각각 추적할 수 있습니다. - 운영 환경에서 불필요한 PGBouncer나 외부 DB 연결 등은 제외해 개인 테스트 환경의 복잡도와 비용을 줄였습니다. AirZone과 같은 구조를 도입할 때는 테스트 환경을 운영 환경과 최대한 유사하게 유지하되, PR 또는 브랜치 단위로 리소스를 격리하는 것이 중요합니다. 또한 긴 배포 작업은 API 요청과 분리하고, Kubernetes Job의 상태·로그·재시도 기능을 활용하면 장애 대응과 운영 추적이 훨씬 쉬워집니다.