-
Airflow on ECS 파이프라인 구축기프로젝트 회고록 2023. 7. 10. 23:38
Airflow multi-cluster architecture <프로젝트의 목적>
기존 ec2 기반의 airflow 서비스가 예고 없이 죽어서 멈췄을때,
자동으로 다시 서비스가 시작될 수 있도록 컨테이너 서비스로 이전할 필요가 있다는 결론을 내렸습니다.
또한 기존에는 한 대의 ec2 서버에 airflow의 모든 구성 요소들이 다 돌아가고 있었다면,
각 컴포넌트를 분리하여 서로의 작업이 각자의 기능에 영향을 끼치지 않도록
ECS에 개별 task를 생성하여 airflow를 멀티클러스터화 하려는 목적에 있었습니다.
처음 시작은 EKS를 활용한 파이프라인 구축을 목표로 했지만,
러닝커브를 고려해서 이전에 경험해봤던 ECS를 기반으로 한 파이프라인 구축을 시작했습니다.
이전의 ECS는 추천모델 서빙 용도로만 사용해봤었고,
ECS 위에서 airflow를 구축하는건 처음이라 중간 중간 많은 에러를 만났던 것 같습니다.
특히 여러 컨테이너 서비스들을 통합하는 port 연결에서 많이 헤맸었고, 이 부분에 가장 많은 시간을 투자했습니다.
아래는 초기 airflow를 multi-cluster로 구상하여 그려본 아키텍처 입니다.
처음 의도는 각 플랫폼 서비스에 맞게 여러개의 성격/목적에 따른 Airflow를
각각의 ECS Service에서 개별 multi-cluster로 구축하여 별도로 운영하는 것 이었습니다.
하지만 현재 서비스의 규모가 크지 않고, 그만큼 자원이 많이 필요하거나 분리해서 별도로 운영이 필요없다면,
자원의 중복 사용 및 낭비라고 생각했습니다.
따라서 Airflow 자원을 공용으로 쓰고 안정성 및 독립성을 위해 Airflow 구성 요소들을
각각의 Service로 띄워 운영하는 것을 목표로 했습니다.
Airflow의 구성요소인 airflow-webserver, airflow-scheduler, airflow-worker, (mysql), redis를
하나의 ECS 클러스터 안에서 각각의 Service로 띄우고,
각 Service 안에서는 Task라는 하나(또는 여러개)의 docker container를 띄워
개별 자원에서 돌아가는 airflow 구성 요소들을 구축 및 통합하기 위한 작업
<ECS 구축 순서>
- Dockerfile 작성
- ECR docker image upload
- ALB, SecurityGroup, TargetGroup 생성
- ECS - Cluster, Task Definition, Service 생성
ECS에는 다양한 구성 요소들이 있는데,
ECS Cluster > Service > Task 순서로 이루어져 있고,
해당 Task(실행할 작업 단위)에 container를 할당하는, 즉 개별 자원(ec2 또는 fargate)에서 운영되는 하나의 서비스라고 할 수 있습니다.
이 Task를 (자동으로)만들기 위해서는
Task Definition, 즉 '작업 정의'라는 것을 만들어서 해당 Task에 컨테이너를 띄우기 위한 여러가지 설정 값들을 정의합니다.
Service 생성 시 해당 Task Definition을 추가합니다.
또한 컨테이너의 기반이 되는 Dockerfile 작성 및 ECR 이미지를 빌드해야 합니다.
빌드한 이미지는 ECS에서 사용할 수 있도록 ECR에 저장(push)해 놓습니다.
이렇게 Task들을 만들고 나서 하나의 Airflow 환경에서 운영될 수 있도록
해당 Task들을 이어주기 위해 Load Balancer와, Security Group, Target Group의 사전 작업이 필요합니다.
따라서 맨 앞의 최종 output을 볼 수 있는 작업을 위해 뒤에서부터 작업했습니다.
1. airflow-common Dockerfile
Airflow 베이스 이미지를 기반으로 작성을 했고,
airflow-webserver, airflow-scheduler, airflow-worker 각자 변수만 다르게 하면
하나의 Dockerfile을 공유해서 사용할 수 있다고 판단하여 airflow-common이라는 공유용 Dockerfile을 작성했습니다.
Docerfile에 각 서비스를 실행시키는 명령어를 담은 스크립트 파일을 포함시키면,
ECS Service 생성 시 Task Definition의 환경변수로 각 스크립트를 실행하는 로직으로 구성했습니다.2. Docker image build
위 Dockerfile을 기반으로 Image를 build하고 ECR 인증후 이미지 태깅하여 ECR Push 완료!
3. LB/SG/TG
- LB(Load Balancer)는 ALB(Application Load Balancer)와 NLB(Network Load Balancer) 두가지를 활용했는데
- ALB는 airflow-webserver용으로, 즉 http UI 화면에 직접 접속하기 위해 사용하고
- NLB는 redis용으로 서버 내부에서 동작하기 위한 LB로 사용했습니다.
- SG(Security Group)은 LB와 TG 두 가지로 활용했습니다.
- LB는 UI에서 서버에 직접 붙는 용도로 활용
- TG는 UI에서 내부 서비스에 접근할 때, ECS Task 생성 시 각 Task를 허용하기 위한 용도로 활용
- TG(Target Group)
- airflow 각 서비스 구성 요소들(airflow-webserver, airflow-worker, redis)을 하나의 Task로 만들고 LB를 통해 target group에 forwarding(연결)하는 작업
LB/TG/TG 연결 (대충 이런..)구조 4. ECS 작업
1. Cluster 생성
- Fargate용으로 사용한 Networking only cluster 생성
- spot과 함께 사용하기 위한 capacity provider strategy 설정(on-demand:30%, spot:70%)
2. Task Definition 작업
- Task container가 생성되기 위해 필요한 설정값들 정의하는 작업
- Airflow 구성 요소별 1개씩 작업
- Task Size, ECR 이미지 URI, port mapping, docker run ENTRYPOINT 명령어(webserver, scheduler, worker) 설정
3. Service 생성
- 서비스 구성에 대한 설정
- Airflow 구성 요소별 1개씩 작업
- Task 개수(여러 대 복제 기능) 및 LoadBalancer(ALB/NLB), Target Group(port mapping) 연동 설정
이후 각 target group의 health check 및 연동 확인, 각 task 실행 로그 확인.
<기대효과>
이러한 과정을 통해 ECS cluster 위에서의 Airflow 구축을 완성했습니다.
poc부터 개발용 테스트, 그리고 운영까지 길고 길었던 5개월의 대장정을 마쳤습니다.
Airflow를 ECS로 이전하여 다음과 같은 효과를 기대할 수 있습니다:
- Airflow 서비스의 독립적 운영 => 각 서비스가 서로에게 영향 받지 않도록 독립성을 유지해 좀 더 안정적인 운영 가능함
- 지속적인 Airflow version 업데이트와 설정 변경 시 관리가 용이함 => image 업데이트 후 재배포
- 유연한 리소스 확보 및 할당 => Auto scaling을 통해 DAG가 늘어나도 실행 시간이 늘어거나 지연되지 않도록
앞서 말했듯이 port mapping 부분에서 보안그룹이라던지 vpc 서브넷그룹 등의 이슈로
가장 많이 헤맸었던 것 같고 이 외에도 많은 부분에서 트러블슈팅 경험들이 있었는데
이 부분은 추후에 하나씩 정리해보려고 합니다.
<트러블슈팅 & 배운점>
1. MySQL DB container => RDS Postgres DB 교체
이번 프로젝트를 통해 가장 크게 배운점이 있다면, 그건 바로 컨테이너 환경에서의 DB사용법 입니다.
기존 ec2 환경에서 Airflow DB를 mysql로 사용하고 있었기 때문에,
ECS로 이전하면서 당연히 DB 또한 하나의 컨테이너로 만들었고, 다른 서비스들과의 연동까지 성공하여 운영에 사용하고 있었습니다.
그러나, 작은 사이즈로 만들었던 DB 컨테이너에 로그가 다 차면서, 메모리 이슈로 task가 죽고 새로 띄웠을 때 데이터가 다 날라가는 현상이 있었습니다. 이 데이터를 보존하기 위해 컨테이너가 죽기 직전 데이터를 백업하는 로직으로 코드 구현을 해봤지만,
airflow db에 테이블을 update하는 데 어려움이 있었어서 컨테이너 환경에서의 DB 활용법을 찾아봤고,
AWS 관리형 DB인 RDS를 사용하기로 했습니다.
RDS로 옮기면서 DB를 Airflow 공식문서에서 권장하는 postgres db로 먼저 테스트해봤고,
이후 airflow.cfg 설정과 다른 서비스들과의 연동(보안그룹) 작업을 통해 운영까지 갈 수 있었습니다.
2. Dockerfile user 권한 변경 설정
https://ninano1109.tistory.com/252
[Docker] Dockerfile user 권한 변경 설정
Dockerfile에서 base 이미지를 사용하고 필요한 패키치를 설치하려고 할 때, 이미지를 빌드 시 다음과 같은 permission 에러가 발생한다. => ERROR [2/4] RUN apt-get update 0.3s ------ > [2/4] RUN apt-get update: #5 0.263 R
ninano1109.tistory.com
👇 이후 모니터링 시스템을 구축한 삽질일기는 요기에 👇
https://ninano1109.tistory.com/273
Airflow 모니터링 시스템 구축기 Part.1(Feat. exporter 셋팅)
Airflow on ECS 파이프라인을 구축한 후, Airflow 서버와 DB로 사용중인 RDS 서버를 모니터링하기 위한 파이프라인을 아래와 같이 구축했습니다. Airflow와 RDS 각 서비스에서 매트릭을 생성해서 보내주면
ninano1109.tistory.com
여기저기 삽질도 해보고
날려도 먹으면서
배우는 게
결국 남는거다
- Z.Sabziller
'프로젝트 회고록' 카테고리의 다른 글
MS Teams에서 Airflow DAG 자동 실행 파이프라인 구축(Feat. Teams, Lambda, Airflow 연동) (0) 2022.04.22 AWS CodePipeline으로 추천 API 모델 배포하기 (0) 2021.08.16 Docker 컨테이너 배포 파이프라인 구축 스프린트 회고 (0) 2021.06.18 👣 방문자 기록 사이트 토이프로젝트 회고 (2) 2021.04.27