이번에 다중 클러스터(즉, 여러대의 컴퓨터)에서 Airflow Celery Worker환경을 세팅해야하는 업무가 생겨서 작업을했다. 과정중에 무수히 많은 시행착오가 있었고, 다음에는 이를 방지하기위해 글을 남깁니다.또한, 다른분들도 이러한 환경을 세팅할때 참고하시면 좋을것같습니다.
일단 모든 Airflow는 Docker로 구축하였습니다. 또한 Master Node와 Worker Node를 아래와 같이 구성했습니다.
버전은 다음과 같습니다
- Airflow - 2.3.3
- Python - 3.8
Master Node
- airflow worker
- airflow scheduler
- airflow webserver
- airflow trigger
- postgresql
- redis
Worker Node
- airflow worker
주의해야할점
Master Node와 Worker Node는 서로 통신이 가능해야하며, 특정 포트가 열려있는 상황이여야합니다. 기본적으로 지정되는 포트는 다음과 같습니다
- airflow webserver - 8080
- postgresql - 5432
- redis - 6379
Docker-compose로 Master Node Airflow 설치
위와같이 Master Node에서 필요로하는 요소들이 굉장히 많은데, 이것을 하나하나 설치를 하는건 복잡해서, docker-compose를 통해서 쉽게 설치가 가능하다. 이 방식은 airflow 공식 documentation에도 소개된다.
https://airflow.apache.org/docs/apache-airflow/stable/start/docker.html#docker-compose-yaml
# airflow 요소들이 담겨져있는 docker-compose.yaml 파일 다운로드
curl -LfO 'https://airflow.apache.org/docs/apache-airflow/2.3.3/docker-compose.yaml'
docker-compose.yaml파일에서 고쳐줘야하는 부분이 있는데, postgresql, redis를 export로 포트를 여는것이 아닌, ports로 포트를 열어줘야한다.
간단하게 export와 ports에 대한 설명을 하자면, export는 도커 컨테이너사이에만 개방하는 포트 개념이고, ports는 외부접근에도 개방을 해주는 개념이다.
아래와같이 수정해준다.
service:
postgres:
image: postgres:13
ports:
- 5432:5432
...
redis:
image: redis:latest
ports:
- 6379:6379
...
추가로 docker-compose.yaml파일이 있는 디렉토리에서 폴더를 생성해준다
mkdir dags
mkdir logs
mkdir plugins
이렇게 수정해주면 Master Node는 세팅이 끝나게된다. 다음 명령어로 Master Node에 Airflow를 실행시켜준다.
docker-compose up airflow-init
docker-compose up
docker ps
``` 아래와 같이 docker container가 작동하는것을 확인할수있음
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
247ebe6cf87a apache/airflow:2.3.3 "/usr/bin/dumb-init …" 3 minutes ago Up 3 minutes (healthy) 8080/tcp compose_airflow-worker_1
ed9b09fc84b1 apache/airflow:2.3.3 "/usr/bin/dumb-init …" 3 minutes ago Up 3 minutes (healthy) 8080/tcp compose_airflow-scheduler_1
7cb1fb603a98 apache/airflow:2.3.3 "/usr/bin/dumb-init …" 3 minutes ago Up 3 minutes (healthy) 0.0.0.0:8080->8080/tcp compose_airflow-webserver_1
74f3bbe506eb postgres:13 "docker-entrypoint.s…" 18 minutes ago Up 17 minutes (healthy) 5432/tcp compose_postgres_1
0bd6576d23cb redis:latest "docker-entrypoint.s…" 10 hours ago Up 17 minutes (healthy) 0.0.0.0:6379->6379/tcp compose_redis_1
```
Worker Node Airflow 세팅
이제 Worker Node를 설치하려는 클러스터(컴퓨터)로 넘어와서 Dockerfile을 아래와같이 생성해준다
FROM ubuntu:latest
# install airflow
ENV AIRFLOW_HOME="/root/airflow"
ENV AIRFLOW__WORKER__NAME="worker_node"
ENV AIRFLOW__MASTER__IP="HOST_IP"
ENV AIRFLOW__POSTGRESQL__HOST=${AIRFLOW__MASTER__IP}:5432
ENV AIRFLOW__REDIS__HOST=${AIRFLOW__MASTER__IP}:6379
ENV AIRFLOW__CORE__EXECUTOR="CeleryExecutor"
ENV AIRFLOW__DATABASE__SQL_ALCHEMY_CONN="postgresql+psycopg2://airflow:airflow@${AIRFLOW__POSTGRESQL__HOST}/airflow"
ENV AIRFLOW__CORE__SQL_ALCHEMY_CONN="postgresql+psycopg2://airflow:airflow@${AIRFLOW__POSTGRESQL__HOST}/airflow"
ENV AIRFLOW__CELERY__RESULT_BACKEND="db+postgresql://airflow:airflow@${AIRFLOW__POSTGRESQL__HOST}/airflow"
ENV AIRFLOW__CELERY__BROKER_URL="redis://:@${AIRFLOW__REDIS__HOST}/0"
ENV AIRFLOW__LOGGING__BASE_LOG_FOLDER="${AIRFLOW_HOME}/log"
ENV AIRFLOW__SCHEDULER__CHILD_PROCESS_LOG_DIRECTORY="${AIRFLOW_HOME}/log/scheduler"
ENV AIRFLOW__LOGGING__DAG_PROCESSOR_MANAGER_LOG_LOCATION="${AIRFLOW_HOME}/log/dag_processor_manager/dag_processor_manager.log"
ENV AIRFLOW__CORE__HOSTNAME_CALLABLE="airflow.utils.net.get_host_ip_address"
ENV AIRFLOW__CORE__FERNET_KEY="FERNET_KEY_INPUT"
ENV AIRFLOW__WEBSERVER__SECRET_KEY="HOST_SECRET_KEY"
ENV AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION="true"
ENV AIRFLOW__CORE__LOAD_EXAMPLES="false"
ENV AIRFLOW__API__AUTH_BACKENDS="airflow.api.auth.backend.basic_auth"
ENV _PIP_ADDITIONAL_REQUIREMENTS="${_PIP_ADDITIONAL_REQUIREMENTS:-apache-airflow-providers-google}"
RUN pip install apache-airflow[celery]==2.3.3
RUN pip install psycopg2-binary
RUN pip install Redis
RUN airflow db init
RUN mkdir ./airflow/dags
RUN mkdir ./airflow/plugins
RUN echo ${SDA_TOKEN} > /etc/moreh/token
여기서 주의해줘야하는 환경변수는 아래와 같다
- AIRFLOW__MASTER__IP - Master Node의 IP주소를 입력해준다
- AIRFLOW__CORE__HOSTNAME__CALLABLE - Master Node의 IP주소를 가져오게 하는건데 바로 IP주소를 입력하는것이 아닌 위와같은 방식으로 입력해야 인식이 된다. default는 socket.getfqdn으로 현재 컴퓨터의 Hostname을 입력하게된다. 해당 값이 세팅을 안할경우 Master Node Webserver에서 WorkerNode의 Log를 볼수가 없다
- AIRFLOW__WEBSERVER__SECRET_KEY - 해당 값은 Master Node의 webserver container로 접속하여 airflow config list | grep secret 명령어로 확인할수가있다
- AIRFLOW__LOGGING_BASE_LOG_FOLDER - 이거는 왜인지는 모르겠으나, Master 에서 Worker의 로그를 가져올때 logs폴더를 보는것이 아닌 log폴더를 보고있다. 그래서 위와같이 수정했고 그밑에 LOG_LOCATION, LOG_DIRECTORY 두개도 동일하게 logs에서 log로 바꿔줬다
이렇게 세팅된 Dockerfile을 실행하고 localhost:5555 (Flower)로 접속하면 아래와같이 Worker Node와 Master Node가 연결이 된것을 볼수가있다(model-vm00 Master, model-vm01 Worker)
Celery Worker환경에서 DAG실행시 주의해야할점
Airflow의 Dag을 실행할때 Celery worker환경에서 주의해야할점은, Master, Worker둘다 같은 이름, 같은 dag파일이 존재해야한다. 하나라도 틀리거나 존재하지않으면 DAG이 실행이 안된다는점을 알아둬야한다.
'Data > Data Engineering' 카테고리의 다른 글
[Docker] Docker 기본 파일시스템 경로 변경 (0) | 2022.08.18 |
---|---|
[Airflow] DAG안에서 병렬 실행시 특정 Task가 완료될때까지 기다려야하는 경우 (0) | 2022.08.18 |
[Docker] 간단한 명령어 정리 (0) | 2022.07.07 |
[Terraform] EKS삭제 시 "aws_auth" 에러 해결방법 (0) | 2022.05.31 |
[k8s] "vingress.elbv2.k8s.aws" ... context deadline exceeded 오류 해결 (1) | 2022.05.23 |