::: IT인터넷 :::

Docker로 AirFlow 설정하기 (Bitnami)

곰탱이푸우 2022. 3. 17. 08:20
반응형
Bitmani에서 제공하는 Docker 이미지로 AirFlow를 설정하는 방법에 대해 정리한다.
 
Bitnami에서 제공하는 GitHub과 DockerHub 사이트는 다음과 같다.
 
AirFlow 소개와 구조에 대해서는 다음 포스팅을 참고한다.
Apache에서 제공하는 Docker 이미지로 AirFlow를 설정하는 방법은 다음 포스팅을 참고한다.

 

 

Bitnami에서 제공하는 AirFlow

Apache에서 제공해주는 Docker 이미지로 셋팅 가능하지만 여러가지 불편한 사항이 있다.
  • docker-compose의 버전을 올려야 하고, apt 설치로 불가능하다.
  • 컨테이너 생성을 두 번에 나눠서 하므로 번거롭다.
  • 컨테이너가 너무 많이 생성된다.
 
이러한 경우 Bitnami에서 배포하는 Docker 이미지를 사용하면 보다 편리하게 사용할 수 있다.
 
Bitnami의 경우 Apache에서 배포하는 프로젝트들을 실사용에 적합하도록 리패키징해서 배포하고 있다.
실제 운영 환경에서 충분히 사용 가능한 최적화와 공식 사이트보다 간편한 설치로 상당히 유명하다.
 
일반적으로 세밀한 설정과 튜닝이 번거롭고 빠르게 실환경에 적용하기 위해 Docker를 사용한다.
따라서 Bitnami 이미지를 사용하는 것도 훌륭한 선택이 될 수 있다.
 

docker-compose.yml 다운로드

아래 명령으로 docker-compose.yml 파일을 다운로드 한다.
2022-06-28 현재 2.3.2 버전이 최신 버전이다.
$ curl -LfO \
    'https://github.com/bitnami/bitnami-docker-airflow/blob/master/2/debian-11/docker-compose.yml'
 
참고로 AirFlow는 파이썬 3.6부터 3.9까지 지원한다.
Bitnami에서 배포하는 Docker 이미지에 내장 된 파이썬의 기본 버전은 3.8이다.
 
아래 코드에서 python으로 검색하면 3.8 버전이 적용 된 것을 확인할 수 있다.
 

docker-compose.yml 수정

기본적으로 Bitnami를 이용한 AirFlow 구성은 아래 블로그를 참고하였다.
해당 블로그의 경우 AirFlow에 Jupyter Notebook을 연동하는 내용이 포함되어 있다.
Jupyter Notebook은 웹 기반의 파이썬 개발을 지원하며, 파이썬을 활용한 데이터 분석에 널리 사용되고 있다.
해당 툴이 연동되어 있으면, 웹 기반으로 DAG을 작성할 수 있어 상당히 편리하다.
 
해당 블로그의 내용을 참고하여 docker-compose.yaml 파일의 설정을 변경한다.
변경할 사항들은 다음과 같다.
  • Docker 이미지 경로 - 사설 저장소를 사용하는 경우
  • 공유 볼륨 경로 - 공유 볼륨을 다른 경로에 설정하려는 경우
  • 연결 포트 변경 - 변경이 필요한 경우
  • Jupyter Notebook 설정 추가
 
참고로 AirFlow의 서비스들이 사용하는 포트는 다음과 같다.
  • AirFlow Webserver - 8080:8080
  • Jupyter Notebook - 8888:8888
 
아래 항목들은 변경하지 않는다. Bitnami에서 설정한 것으로 변경하면 오류가 발생한다.
  • 공유 볼륨의 컨테이너 내부 경로
  • 데이터베이스와 redis의 비밀번호
 
Jupyter Notebook 설정 추가
docker-compose.yml 파일에 Jupyter Noterbook  컨테이너 설정을 추가한다.
$ vi docker-compose.yaml

version: '2'
services:
### 추가 부분 시작 ###
  jupyter:
    image: jupyter/base-notebook:latest
    volumes:
        - ./dags:/usr/local/airflow/dags
    ports:
        - "8888:8888"
    command: "start-notebook.sh \
              --NotebookApp.password='sha1:b70a055565b1:854e3f96f91c51cc0c91da371ea5dfbf7c1a61a1' \
              --sudo mkdir /usr/local/airflow/dags"
### 추가 부분 끝 ###
  postgresql:
 
password 부분에 sha1 해시로 입력 되어 있는데, 1234를 sha1으로 변경한 것이다.
나중에 접속할때 1234를 입력하면 로그인할 수 있다.
다른 비밀번호를 사용하고자 하는 경우, 원하는 값을 sha1으로 변경하여 수정한다.
 
 
Docker 이미지 경로
DockerHub를 사용하는 경우 Docker 이미지 경로를 수정할 필요는 없다.
사설 저장소를 사용할 것이므로 Docker 이미지 경로를 수정한다.
airflow, airflow-worker, airflow-scheduler 버전에 2만 명시하면 과거 버전과 섞이는 경우가 있어 전체 버전을 명시한다. (ex. 2.3.2)
$ vi docker-compose.yaml

version: '2'
services:
  jupyter:
    image: 사설저장소경로:포트/jupyter/base-notebook:latest
    ## 중략 ##

  postgresql:
    image: 사설저장소경로:포트/bitnami/postgresql:10
    ## 중략 ##

  redis:
    image: 사설저장소경로:포트/bitnami/redis:6.0
    ## 중략 ##

  airflow-scheduler:
    image: 사설저장소경로:포트/bitnami/airflow-scheduler:2.3.2
    ## 중략 ##

  airflow-worker:
    image: 사설저장소경로:포트/bitnami/airflow-worker:2.3.2
    ## 중략 ##

  airflow:
    image: 사설저장소경로:포트/bitnami/airflow:2.3.2
 
공유 볼륨 경로
공유 볼륨은 그대로 사용할 것이므로 변경하지 않는다.
변경이 필요한 경우 아래 항목을 변경한다.
$ vi docker-compose.yaml

version: '2'
services:
  ## 중략 ##
  postgresql:
    ## 중략 ##
    volumes:
      - ./postgresql_data:/bitnami/postgresql

  ## 중략 ##

  redis:
    ## 중략 ##
    volumes:
      - ./redis_data:/bitnami

  ## 중략 ##

  airflow:
    ## 중략 ##
    volumes:
      - ./dags:/opt/bitnami/airflow/dags

volumes:  # 아래 두개 남기고 나머지는 삭제
  postgresql_data:
    driver: local
  redis_data:
    driver: local
 
dags 폴더가 중요하다.
AirFlow에서 실행할 파이프라인(Pipeline)을 정의한 dag 파일은 dags 폴더에 위치한다.
dags 폴더를 공유 볼륨으로 설정하면 컨테이너 내부로 진입할 필요 없이 호스트의 dags 폴더를 사용하면 된다.
해당 폴더는 jupyter, airflow-scheduler, airflow-worker, airflow 등 4개 컨테이너에서 함께 사용하게 된다.
 
 
연결 포트
연결 포트도 그대로 사용할 것이므로 변경하지 않는다.
변경이 필요한 경우 아래 항목을 변경한다.
$ vi docker-compose.yaml

## 중략 ##
services:
  jupyter:
    ## 중략 ##
    ports:    # 8888: 부분을 변경할포트: 형태로 변경한다.
        - '8888:8888'

    ## 중략 ##

  airflow:
    ## 중략 ##
    ports:    # 8080: 부분을 변경할포트: 형태로 변경한다. 
      - '8080:8080'
 
타임존 설정
기본 설정은 UTC로 되어 있기 때문에 한국 시간 기준으로 변경한다.
변경이 필요한 경우 아래 항목을 추가한다.
$ vi docker-compose.yaml

## 중략 ##
services:
  ## 중략 ##

  airflow-scheduler:
    ## 중략 ##
    environment:
      ## 중략 ##
      - AIRFLOW__WEBSERVER__DEFAULT_UI_TIMEZONE=Asia/Seoul
      - AIRFLOW__CORE__DEFAULT_TIMEZONE=Asia/Seoul
      - TZ=Asia/Seoul
      
    ## 중략 ##

  airflow-worker:
    ## 중략 ##
    environment:
      ## 중략 ##
      - AIRFLOW__WEBSERVER__DEFAULT_UI_TIMEZONE=Asia/Seoul
      - AIRFLOW__CORE__DEFAULT_TIMEZONE=Asia/Seoul
      - TZ=Asia/Seoul
      
    ## 중략 ##

  airflow:
    ## 중략 ##
    environment:
      ## 중략 ##
      - AIRFLOW__WEBSERVER__DEFAULT_UI_TIMEZONE=Asia/Seoul
      - AIRFLOW__CORE__DEFAULT_TIMEZONE=Asia/Seoul
      - TZ=Asia/Seoul
      
    ## 중략 ##
 
 

airflow 컨테이너 실행

아래 명령으로 docker-compose를 실행한다. -d 옵션을 지정하여 백그라운드로 실행되도록 한다.
오류가 발생하면 -d 옵션을 빼고 실행한다.
$ docker-compose up -d
 
실행이 완료되면 AirFlow와 관련 된 모든 컨테이너가 생성 된 것을 확인할 수 있다.
$ docker ps

CONTAINER ID  IMAGE                                  NAMES
1d03ee0b176c  jupyter/base-notebook:latest           airflow_jupyter_1
09972e13486b  bitnami/airflow-worker:2               airflow_airflow-worker_1
a27cc5e5a207  bitnami/airflow-scheduler:2            airflow_airflow-scheduler_1
d955e359667c  bitnami/postgresql:10                  airflow_postgresql_1
127b77b23a78  bitnami/airflow:2                      airflow_airflow_1
f58e8a56f7af  bitnami/redis:6.0                      airflow_redis_1
 

redis 오류 해결

컨테이너가 실행하다가 redis 컨테이너에서 아래 오류가 발생할 수 있다.
오류 로그를 확인하려면 아래 명령을 실행한다.
$ docker logs airflow_redis_1

## 중략 ##
mkdir: cannot create directory '/bitnami/redis': Permission denied when starting the Docker
 
공유 볼륨으로 지정한 경로에 대한 권한이 없어서 발생한 문제로 아래와 같이 변경한다.
$ chmod 677 ./redis_data
 
아래 사이트를 참고하였다.
WSL 환경에서 폴더 권한 설정이 되지 않으면 아래 명령을 실행하고 다시 시도한다.
만약, 기존에 /mnt 하위에 공유 볼륨을 지정하여 사용 중인 컨테이너가 있다면 영향을 받는다.
따라서 반드시 기존 컨테이너들도 모두 종료하고 진행해야 한다.
$ sudo umount /mnt/d
$ sudo mount -t drvfs D: /mnt/d -o metadata
 
 

Scheduler, Worker 오류 해결

컨테이너가 실행하다가 airflow_airflow-scheduler_1, airflow_airflow-worker_1 컨테이너에서 아래 오류가 발생할 수 있다.
오류 로그를 확인하려면 아래 명령을 실행한다.
$ docker logs airflow_airflow-scheduler_1    # 또는 airflow_airflow-worker_1

## 중략 ##
timeout reached before the port went into state "inuse"
 
airflow_airflow-scheduler_1, airflow_airflow-worker_1 컨테이너의 환경 변수에 웹서버 포트가 지정되지 않아서 발생한 것이다.
docker-compose.yml에 아래 내용을 추가한다.
$ vi docker-compose.yaml

## 중략 ##
  airflow-scheduler:
    ## 중략 ##
    environment: 
      ## 중략 ##
      - AIRFLOW_WEBSERVER_HOST=airflow

  airflow-worker:
    ## 중략 ##
    environment: 
      ## 중략 ##
      - AIRFLOW_WEBSERVER_HOST=airflow
 
아래 사이트를 참고하였다.
https://githubmemory.com/repo/bitnami/bitnami-docker-airflow/issues/78
 

timeout reached before the port went into state "inuse" - githubmemory

timeout reached before the port went into state "inuse"

githubmemory.com

 

 

DAG 실행시 로그 출력 오류

DAG를 실행하고 로그를 확인할때 아래와 같은 오류가 나타는 경우가 있다.
*** Log file does not exist: 
/opt/bitnami/airflow/logs/tutorial/hello_task/2021-11-05T06:36:04.378967+00:00/1.log
*** Fetching from: 
http://ac8721e912e5:8793/log/tutorial/hello_task/2021-11-05T06:36:04.378967+00:00/1.log
*** !!!! Please make sure that all your Airflow components 
(e.g. schedulers, webservers and workers) 
have the same 'secret_key' configured in 'webserver' section !!!!!
****** See more at 
https://airflow.apache.org/docs/apache-airflow/stable/configurations-ref.html#secret-key
****** Failed to fetch log file from worker. 
403 Client Error: FORBIDDEN for url: 
http://ac8721e912e5:8793/log/tutorial/hello_task/2021-11-05T06:36:04.378967+00:00/1.log
For more information check: https://httpstatuses.com/403

 

airflow.cfg 설정 파일의 webserver 구역의 secret_key 값을 동일하게 적용해야 한다.

해당 설명은 다음을 참고한다.

 

 

Configuration Reference — Airflow Documentation

 

airflow.apache.org

 

환경 변수는 AIRFLOW__WEBSERVER__SECRET_KEY이다.

 

아래 명령으로 랜덤 값을 생성한다.
$ python -c 'import os; print(os.urandom(16))'
b'\xd0;G\xd1g()\xacU\x0ed\xd7\xban\xc8\xb0'

 

docker-compose.yml의 airflow 관련 컨테이너에 AIRFLOW__WEBSERVER__SECRET_KEY 환경 변수를 추가한다.

생성 된 문자열을 복사해서 해당 환경 변수의 값으로 전달한다.

$ vi docker-compose.yaml

## 중략 ## 
services: 
  ## 중략 ## 
  airflow-scheduler: 
    ## 중략 ## 
    environment: 
      ## 중략 ## 
      # 생성한 문자열 붙여넣기
      - AIRFLOW__WEBSERVER__SECRET_KEY=b'\xd0;G\xd1g()\xacU\x0ed\xd7\xban\xc8\xb0'
  
  ## 중략 ##

  airflow-worker: 
    ## 중략 ##  
    environment:  
    ## 중략 ##  
      # 생성한 문자열 붙여넣기
      - AIRFLOW__WEBSERVER__SECRET_KEY=b'\xd0;G\xd1g()\xacU\x0ed\xd7\xban\xc8\xb0'
  
  ## 중략 ##

  airflow: 
  ## 중략 ##  
    environment:  
    ## 중략 ##  
      # 생성한 문자열 붙여넣기
      - AIRFLOW__WEBSERVER__SECRET_KEY=b'\xd0;G\xd1g()\xacU\x0ed\xd7\xban\xc8\xb0'
  
  ## 중략 ##

 

아래 사이트를 참고했다.

 

In airflow's configuration file `airflow.cfg` what is the `secret_key`, and do I have to set it?

As a comment above the value, it says # Secret key used to run your flask app, but that doesn't tell me much. Currently it is set to secret_key = temporary_key, but that seems unsafe. We have set up

serverfault.com

 

 

AirFlow CPU 과점유 현상 해결

AirFlow 셋팅 후 CPU 점유율이 40~50% 정도로 과하게 점유 된다면 설정 변경이 필요하다.
현재는 해결 된 것으로 보이지만, 참고하기 위해 정리한다.
 
해당 증상은 Scheduler와 Worker간의 연결 확인을 위한 Interval이 너무 짧은 것이 원인이다.
Scheduler와 Worker 컨테이너 내부의 아래 설정 파일을 확인한다.
$ docker exec -it airflow-airflow_worker_1 /bin/bash
# 또는 docker exec -it airflow-airflow_scheduler_1 /bin/bash

$ cat /opt/bitnami/airflow/airflow.cfg
 
CPU 과점유 증상이 발생하는 경우, 일반적으로 아래 설정 값을 확인해보아야 한다.
scheduler_heartbeat_sec = 5
min_file_process_interval = 0
max_threads = 2
 
2.2.3 버전에서는 일부 변경되어 다음과 같이 설정되어 있다.
scheduler_heartbeat_sec = 5 
min_file_process_interval = 30  # 0에서 30으로 변경
# max_threads    Defrecated (없어짐)
 
만약 CPU 과점유 증상이 있는 경우 아래와 같이 설정한다. 컨테이너 내부에 vi 편집기가 없으므로 컨테이너에 환경 변수로 전달한다.
설정 관련 내용은 아래 사이트를 참고한다.
 
docker-compose.yml 파일의 airflow, scheduler, worker의 환경 변수에 아래 내용을 추가한다.
$ vi docker-compose.yaml

## 중략 ##
services:
  ## 중략 ##
  airflow-scheduler:
    ## 중략 ##
    environment:
      ## 중략 ##
      - AIRFLOW__SCHEDULER__SCHEDULER_HEARTBEAT_SEC=60
      - AIRFLOW__SCHEDULER__MIN_FILE_PROCESS_INTERVAL=60

  ## 중략 ##

  airflow-worker:
    ## 중략 ## 
    environment: 
    ## 중략 ## 
      - AIRFLOW__SCHEDULER__SCHEDULER_HEARTBEAT_SEC=60 
      - AIRFLOW__SCHEDULER__MIN_FILE_PROCESS_INTERVAL=60

  ## 중략 ##

  airflow:
  ## 중략 ## 
    environment: 
    ## 중략 ## 
      - AIRFLOW__SCHEDULER__SCHEDULER_HEARTBEAT_SEC=60 
      - AIRFLOW__SCHEDULER__MIN_FILE_PROCESS_INTERVAL=60

  ## 중략 ##
 
참고로 max_threads는 1.10.14 이후 버전부터 Defrecated 되었으므로 제외한다.
 
아래 사이트를 참고하였다.
 
 

AirFlow 웹서버 접속

localhost:8080으로 접속하면 airflow가 실행 된 것을 확인할 수 있다.
 
Bitnami에서 제공하는 Docker 이미지의 최초 로그인 계정은 user/ bitnami 이다.
관리자 ID와 비밀번호는 접속 이후 Security - User List에서 변경 가능하다.
 
로그인하면 Apache 제공 버전과 다르게 예제 튜토리얼이 없다.
가급적 Apache 제공 버전을 통해 연습하고 실제 운영은 Bitnami 버전을 사용하는 것이 나을 것으로 판단된다.

Jupyter Notebook 접속

localhost:8888으로 접속하면 Jupyter Notebook이 실행 된 것을 확인할 수 있다.
앞서 설정한 비밀번호인 1234를 입력하면 로그인할 수 있다.
 
Jupyter Notebook 사용법은 별도로 정리한다.
AirFlow와 연동되어 있으므로, 노트북을 생성하고 DAG 생성하여 실행하면 AirFlow에 전달된다.
반응형