Tools/Airflow

Docker Compose를 이용한 Airflow 설치

칼쵸쵸 2024. 10. 1. 04:27

공식 문서 : https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html

Airflow Docker Compose 

Airflow를 Docker로 설치하려면 docker-compose.yaml 파일을 작성해야 합니다. 공식 Apache Airflow GitHub에서 제공하는 docker-compose.yaml 예시 파일을 사용하면 쉽게 설정할 수 있습니다.

아래는 Airflow를 설치하기 위한 기본 docker-compose.yaml 파일입니다.

더보기

 

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

# Basic Airflow cluster configuration for CeleryExecutor with Redis and PostgreSQL.
#
# WARNING: This configuration is for local development. Do not use it in a production deployment.
#
# This configuration supports basic configuration using environment variables or an .env file
# The following variables are supported:
#
# AIRFLOW_IMAGE_NAME           - Docker image name used to run Airflow.
#                                Default: apache/airflow:2.10.2
# AIRFLOW_UID                  - User ID in Airflow containers
#                                Default: 50000
# AIRFLOW_PROJ_DIR             - Base path to which all the files will be volumed.
#                                Default: .
# Those configurations are useful mostly in case of standalone testing/running Airflow in test/try-out mode
#
# _AIRFLOW_WWW_USER_USERNAME   - Username for the administrator account (if requested).
#                                Default: airflow
# _AIRFLOW_WWW_USER_PASSWORD   - Password for the administrator account (if requested).
#                                Default: airflow
# _PIP_ADDITIONAL_REQUIREMENTS - Additional PIP requirements to add when starting all containers.
#                                Use this option ONLY for quick checks. Installing requirements at container
#                                startup is done EVERY TIME the service is started.
#                                A better way is to build a custom image or extend the official image
#                                as described in https://airflow.apache.org/docs/docker-stack/build.html.
#                                Default: ''
#
# Feel free to modify this file to suit your needs.
---
x-airflow-common:
  &airflow-common
  # In order to add custom dependencies or upgrade provider packages you can use your extended image.
  # Comment the image line, place your Dockerfile in the directory where you placed the docker-compose.yaml
  # and uncomment the "build" line below, Then run `docker-compose build` to build the images.
  image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.10.2}
  # build: .
  environment:
    &airflow-common-env
    AIRFLOW__CORE__EXECUTOR: CeleryExecutor
    AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow@postgres/airflow
    AIRFLOW__CELERY__RESULT_BACKEND: db+postgresql://airflow:airflow@postgres/airflow
    AIRFLOW__CELERY__BROKER_URL: redis://:@redis:6379/0
    AIRFLOW__CORE__FERNET_KEY: ''
    AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true'
    AIRFLOW__CORE__LOAD_EXAMPLES: 'false'
    AIRFLOW__API__AUTH_BACKENDS: 'airflow.api.auth.backend.basic_auth,airflow.api.auth.backend.session'
    # yamllint disable rule:line-length
    # Use simple http server on scheduler for health checks
    # See https://airflow.apache.org/docs/apache-airflow/stable/administration-and-deployment/logging-monitoring/check-health.html#scheduler-health-check-server
    # yamllint enable rule:line-length
    AIRFLOW__SCHEDULER__ENABLE_HEALTH_CHECK: 'true'
    # WARNING: Use _PIP_ADDITIONAL_REQUIREMENTS option ONLY for a quick checks
    # for other purpose (development, test and especially production usage) build/extend Airflow image.
    _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-}
    # The following line can be used to set a custom config file, stored in the local config folder
    # If you want to use it, outcomment it and replace airflow.cfg with the name of your config file
    # AIRFLOW_CONFIG: '/opt/airflow/config/airflow.cfg'
  volumes:
    - ${AIRFLOW_PROJ_DIR:-.}/dags:/opt/airflow/dags
    - ${AIRFLOW_PROJ_DIR:-.}/logs:/opt/airflow/logs
    - ${AIRFLOW_PROJ_DIR:-.}/config:/opt/airflow/config
    - ${AIRFLOW_PROJ_DIR:-.}/plugins:/opt/airflow/plugins
  user: "${AIRFLOW_UID:-50000}:0"
  depends_on:
    &airflow-common-depends-on
    redis:
      condition: service_healthy
    postgres:
      condition: service_healthy

services:
  postgres:
    image: postgres:13
    environment:
      POSTGRES_USER: airflow
      POSTGRES_PASSWORD: airflow
      POSTGRES_DB: airflow
    volumes:
      - postgres-db-volume:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "airflow"]
      interval: 10s
      retries: 5
      start_period: 5s
    restart: always

  redis:
    # Redis is limited to 7.2-bookworm due to licencing change
    # https://redis.io/blog/redis-adopts-dual-source-available-licensing/
    image: redis:7.2-bookworm
    expose:
      - 6379
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 30s
      retries: 50
      start_period: 30s
    restart: always

  airflow-webserver:
    <<: *airflow-common
    command: webserver
    ports:
      - "8080:8080"
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully

  airflow-scheduler:
    <<: *airflow-common
    command: scheduler
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:8974/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully

  airflow-worker:
    <<: *airflow-common
    command: celery worker
    healthcheck:
      # yamllint disable rule:line-length
      test:
        - "CMD-SHELL"
        - 'celery --app airflow.providers.celery.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}" || celery --app airflow.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}"'
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    environment:
      <<: *airflow-common-env
      # Required to handle warm shutdown of the celery workers properly
      # See https://airflow.apache.org/docs/docker-stack/entrypoint.html#signal-propagation
      DUMB_INIT_SETSID: "0"
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully

  airflow-triggerer:
    <<: *airflow-common
    command: triggerer
    healthcheck:
      test: ["CMD-SHELL", 'airflow jobs check --job-type TriggererJob --hostname "$${HOSTNAME}"']
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully

  airflow-init:
    <<: *airflow-common
    entrypoint: /bin/bash
    # yamllint disable rule:line-length
    command:
      - -c
      - |
        if [[ -z "${AIRFLOW_UID}" ]]; then
          echo
          echo -e "\033[1;33mWARNING!!!: AIRFLOW_UID not set!\e[0m"
          echo "If you are on Linux, you SHOULD follow the instructions below to set "
          echo "AIRFLOW_UID environment variable, otherwise files will be owned by root."
          echo "For other operating systems you can get rid of the warning with manually created .env file:"
          echo "    See: https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html#setting-the-right-airflow-user"
          echo
        fi
        one_meg=1048576
        mem_available=$$(($$(getconf _PHYS_PAGES) * $$(getconf PAGE_SIZE) / one_meg))
        cpus_available=$$(grep -cE 'cpu[0-9]+' /proc/stat)
        disk_available=$$(df / | tail -1 | awk '{print $$4}')
        warning_resources="false"
        if (( mem_available < 4000 )) ; then
          echo
          echo -e "\033[1;33mWARNING!!!: Not enough memory available for Docker.\e[0m"
          echo "At least 4GB of memory required. You have $$(numfmt --to iec $$((mem_available * one_meg)))"
          echo
          warning_resources="true"
        fi
        if (( cpus_available < 2 )); then
          echo
          echo -e "\033[1;33mWARNING!!!: Not enough CPUS available for Docker.\e[0m"
          echo "At least 2 CPUs recommended. You have $${cpus_available}"
          echo
          warning_resources="true"
        fi
        if (( disk_available < one_meg * 10 )); then
          echo
          echo -e "\033[1;33mWARNING!!!: Not enough Disk space available for Docker.\e[0m"
          echo "At least 10 GBs recommended. You have $$(numfmt --to iec $$((disk_available * 1024 )))"
          echo
          warning_resources="true"
        fi
        if [[ $${warning_resources} == "true" ]]; then
          echo
          echo -e "\033[1;33mWARNING!!!: You have not enough resources to run Airflow (see above)!\e[0m"
          echo "Please follow the instructions to increase amount of resources available:"
          echo "   https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html#before-you-begin"
          echo
        fi
        mkdir -p /sources/logs /sources/dags /sources/plugins
        chown -R "${AIRFLOW_UID}:0" /sources/{logs,dags,plugins}
        exec /entrypoint airflow version
    # yamllint enable rule:line-length
    environment:
      <<: *airflow-common-env
      _AIRFLOW_DB_MIGRATE: 'true'
      _AIRFLOW_WWW_USER_CREATE: 'true'
      _AIRFLOW_WWW_USER_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow}
      _AIRFLOW_WWW_USER_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow}
      _PIP_ADDITIONAL_REQUIREMENTS: ''
    user: "0:0"
    volumes:
      - ${AIRFLOW_PROJ_DIR:-.}:/sources

  airflow-cli:
    <<: *airflow-common
    profiles:
      - debug
    environment:
      <<: *airflow-common-env
      CONNECTION_CHECK_MAX_COUNT: "0"
    # Workaround for entrypoint issue. See: https://github.com/apache/airflow/issues/16252
    command:
      - bash
      - -c
      - airflow

  # You can enable flower by adding "--profile flower" option e.g. docker-compose --profile flower up
  # or by explicitly targeted on the command line e.g. docker-compose up flower.
  # See: https://docs.docker.com/compose/profiles/
  flower:
    <<: *airflow-common
    command: celery flower
    profiles:
      - flower
    ports:
      - "5555:5555"
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:5555/"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully

volumes:
  postgres-db-volume:

 

Airflow의 구성 요소

1. PostgreSQL (postgres)

  postgres:
    image: postgres:13
    environment:
      POSTGRES_USER: airflow
      POSTGRES_PASSWORD: airflow
      POSTGRES_DB: airflow
    volumes:
      - postgres-db-volume:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "airflow"]
      interval: 10s
      retries: 5
      start_period: 5s
    restart: always

 

 

  • PostgreSQL은 Airflow의 메타데이터 데이터베이스로 사용됩니다. Airflow는 작업 흐름(DAGs), 작업 실행 기록, 로그, 작업 상태 등의 정보를 데이터베이스에 저장합니다.
  • PostgreSQL은 메타데이터 데이터베이스로 매우 안정적이고, 성능도 뛰어나며, 오픈소스이기 때문에 널리 사용됩니다. POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB 환경 변수를 통해 데이터베이스 사용자와 비밀번호, 그리고 데이터베이스 이름을 설정할 수 있습니다.
  • volumes 섹션은 데이터를 영구적으로 저장하기 위한 저장소를 설정하는 부분입니다. 이렇게 하면 컨테이너가 삭제되더라도 데이터는 보존됩니다.

2. Redis

  redis:
    # Redis is limited to 7.2-bookworm due to licencing change
    # https://redis.io/blog/redis-adopts-dual-source-available-licensing/
    image: redis:7.2-bookworm
    expose:
      - 6379
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 30s
      retries: 50
      start_period: 30s
    restart: always

 

  • Redis는 Airflow에서 브로커(Broker) 역할을 합니다. Airflow가 CeleryExecutor를 사용할 때, 여러 워커(worker)들이 작업을 병렬로 처리하기 위해 큐를 사용하게 되는데, 이 큐를 관리하는 것이 Redis입니다.
  • CeleryExecutor는 여러 작업들을 동시에 처리할 수 있도록 해주며, Redis는 이 작업들을 중앙에서 관리하는 역할을 합니다.
  • Redis는 빠른 인메모리 데이터 저장소로, 큐잉 작업에 매우 적합합니다. 이 때문에 Airflow의 작업들이 대기하거나 처리되는 동안 효율적으로 관리할 수 있습니다.
  • 포트 6379는 Redis가 기본적으로 사용하는 포트입니다.

3. Airflow Webserver

  airflow-webserver:
    <<: *airflow-common
    command: webserver
    ports:
      - "8080:8080"
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully

 

  • Airflow Webserver는 사용자가 Airflow의 DAGs 및 작업 상태를 웹 UI로 볼 수 있게 해주는 웹 인터페이스입니다. 이를 통해 작업을 모니터링하고, DAG를 관리하며, 작업을 수동으로 실행할 수도 있습니다.

4. Airflow Scheduler

 airflow-scheduler:
    <<: *airflow-common
    command: scheduler
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:8974/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully
  • Airflow Scheduler는 Airflow의 핵심 컴포넌트 중 하나로, 작업을 예약하고 실행하는 역할을 합니다. Scheduler는 DAG 파일을 모니터링하며, 작업을 예약하고 큐로 넣어 CeleryExecutor를 통해 작업이 처리되도록 합니다.
  • Scheduler는 DAG에 정의된 스케줄에 따라 실행되고, 실행 상태를 지속적으로 모니터링합니다.

5. Airflow Worker

 airflow-worker:
    <<: *airflow-common
    command: celery worker
    healthcheck:
      # yamllint disable rule:line-length
      test:
        - "CMD-SHELL"
        - 'celery --app airflow.providers.celery.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}" || celery --app airflow.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}"'
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    environment:
      <<: *airflow-common-env
      # Required to handle warm shutdown of the celery workers properly
      # See https://airflow.apache.org/docs/docker-stack/entrypoint.html#signal-propagation
      DUMB_INIT_SETSID: "0"
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully
  • Airflow Worker는 CeleryExecutor에서 각 작업을 병렬로 실행하는 역할을 합니다. 여러 Worker가 있을 수 있으며, 각 작업은 이 Worker들이 실행하게 됩니다.
  • 각 Worker는 Redis 큐에 담긴 작업을 받아 실행하고, 그 결과를 PostgreSQL에 저장합니다. 이 Worker가 없다면 작업을 실행할 수 없기 때문에, CeleryExecutor 구조에서는 필수적인 컴포넌트입니다.
  • Worker는 volumes와 environment 설정에서 Webserver와 동일한 DAG, 로그, 플러그인을 공유합니다.

6. Airflow Init

  airflow-init:
    <<: *airflow-common
    entrypoint: /bin/bash
    # yamllint disable rule:line-length
    command:
      - -c
      - |
        if [[ -z "${AIRFLOW_UID}" ]]; then
          echo
          echo -e "\033[1;33mWARNING!!!: AIRFLOW_UID not set!\e[0m"
          echo "If you are on Linux, you SHOULD follow the instructions below to set "
          echo "AIRFLOW_UID environment variable, otherwise files will be owned by root."
          echo "For other operating systems you can get rid of the warning with manually created .env file:"
          echo "    See: https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html#setting-the-right-airflow-user"
          echo
        fi
        one_meg=1048576
        mem_available=$$(($$(getconf _PHYS_PAGES) * $$(getconf PAGE_SIZE) / one_meg))
        cpus_available=$$(grep -cE 'cpu[0-9]+' /proc/stat)
        disk_available=$$(df / | tail -1 | awk '{print $$4}')
        warning_resources="false"
        if (( mem_available < 4000 )) ; then
          echo
          echo -e "\033[1;33mWARNING!!!: Not enough memory available for Docker.\e[0m"
          echo "At least 4GB of memory required. You have $$(numfmt --to iec $$((mem_available * one_meg)))"
          echo
          warning_resources="true"
        fi
        if (( cpus_available < 2 )); then
          echo
          echo -e "\033[1;33mWARNING!!!: Not enough CPUS available for Docker.\e[0m"
          echo "At least 2 CPUs recommended. You have $${cpus_available}"
          echo
          warning_resources="true"
        fi
        if (( disk_available < one_meg * 10 )); then
          echo
          echo -e "\033[1;33mWARNING!!!: Not enough Disk space available for Docker.\e[0m"
          echo "At least 10 GBs recommended. You have $$(numfmt --to iec $$((disk_available * 1024 )))"
          echo
          warning_resources="true"
        fi
        if [[ $${warning_resources} == "true" ]]; then
          echo
          echo -e "\033[1;33mWARNING!!!: You have not enough resources to run Airflow (see above)!\e[0m"
          echo "Please follow the instructions to increase amount of resources available:"
          echo "   https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html#before-you-begin"
          echo
        fi
        mkdir -p /sources/logs /sources/dags /sources/plugins
        chown -R "${AIRFLOW_UID}:0" /sources/{logs,dags,plugins}
        exec /entrypoint airflow version
    # yamllint enable rule:line-length
    environment:
      <<: *airflow-common-env
      _AIRFLOW_DB_MIGRATE: 'true'
      _AIRFLOW_WWW_USER_CREATE: 'true'
      _AIRFLOW_WWW_USER_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow}
      _AIRFLOW_WWW_USER_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow}
      _PIP_ADDITIONAL_REQUIREMENTS: ''
    user: "0:0"
    volumes:
      - ${AIRFLOW_PROJ_DIR:-.}:/sources
  • Airflow Init데이터베이스 초기화를 위한 서비스입니다. Airflow를 처음 설정할 때 PostgreSQL 등 메타데이터 데이터베이스를 초기화하여 테이블을 생성하고 기본 데이터를 삽입합니다.
  • airflow db init 명령어를 사용하여 데이터베이스가 정상적으로 동작할 수 있도록 준비하는 역할을 합니다.

 

7. volumes 섹션

volumes:
  postgres-db-volume:
  • volumes는 Docker 컨테이너의 데이터를 영구적으로 저장하는 기능입니다. PostgreSQL의 데이터베이스는 영구 저장소로 데이터를 저장하며, 컨테이너가 재시작되거나 삭제되더라도 데이터를 보존할 수 있습니다.
  • Airflow 작업의 로그나 DAG 파일도 로컬 머신과 Docker 컨테이너 간에 공유하도록 설정되므로, volumes를 통해 각 컴포넌트가 동일한 DAG 파일을 접근할 수 있게 됩니다.

8. Airflow trigger

  airflow-triggerer:
    <<: *airflow-common
    command: triggerer
    healthcheck:
      test: ["CMD-SHELL", 'airflow jobs check --job-type TriggererJob --hostname "$${HOSTNAME}"']
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully

 

airflow-triggerer는 Airflow 트리거 서비스를 정의하는 설정입니다. 트리거 서비스는 데이터 동작과 이벤트 기반의 DAG 실행을 처리하는 역할을 합니다. 트리거는 특정 조건을 만족하는 이벤트가 발생할 때 DAG 실행을 자동으로 트리거하는 메커니즘을 제공합니다. 이를 통해 Airflow의 작업 흐름을 더 동적인 방식으로 관리할 수 있습니다.

 

9. Airflow Cli

 airflow-cli:
    <<: *airflow-common
    profiles:
      - debug
    environment:
      <<: *airflow-common-env
      CONNECTION_CHECK_MAX_COUNT: "0"
    # Workaround for entrypoint issue. See: https://github.com/apache/airflow/issues/16252
    command:
      - bash
      - -c
      - airflow

airflow-cli는 Airflow 명령줄 인터페이스 (CLI) 를 실행하는 서비스를 정의합니다. 이 설정은 주로 Airflow 관련 작업을 수행하거나 디버깅할 때 유용한 명령을 실행할 수 있는 환경을 제공합니다. Airflow CLI는 DAG의 상태를 확인하거나, 새로운 DAG을 등록하거나, 작업을 강제 종료하는 등 다양한 관리 작업을 수행하는 데 사용됩니다.

 

10. flower

  flower:
    <<: *airflow-common
    command: celery flower
    profiles:
      - flower
    ports:
      - "5555:5555"
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:5555/"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    restart: always
    depends_on:
      <<: *airflow-common-depends-on
      airflow-init:
        condition: service_completed_successfully

 

flower 서비스는 Celery 작업 관리 도구Flower를 실행하는 설정입니다. Flower는 Celery 작업자(Celery workers)의 상태를 모니터링할 수 있는 웹 기반의 도구로, 작업의 진행 상황, 큐 상태, 성공 및 실패한 작업 등을 시각적으로 확인할 수 있게 해줍니다. 이를 통해 Airflow의 CeleryExecutor를 사용하는 환경에서 작업 상태를 쉽게 모니터링할 수 있습니다.

요약

  • PostgreSQL: 메타데이터 데이터베이스로 사용되어 Airflow의 작업 상태 및 기록을 저장.
  • Redis: 작업 큐를 관리하는 브로커로, CeleryExecutor가 병렬 작업을 처리할 수 있도록 도와줌.
  • Airflow Webserver: 웹 인터페이스를 제공하여 DAG와 작업 상태를 모니터링.
  • Airflow Scheduler: 작업 스케줄링을 담당하며, DAG의 정의에 따라 작업을 실행.
  • Airflow Worker: 큐에 담긴 작업을 병렬로 처리하는 역할.
  • Airflow Init: 데이터베이스를 초기화하는 서비스.
  • Airflow trigger: 데이터 동작과 이벤트 기반의 DAG 실행
  • Airflow CLI : Airflow 명령줄 인터페이스 (CLI) 를 실행
  • flower :  Celery 작업 관리 도구 Flower를 실행

 

 

디렉토리 구조

Airflow 작업에서 DAGs, Logs, Plugins를 위한 디렉토리를 만들어야 합니다. 아래 명령어를 실행하여 필요한 디렉토리를 생성하세요.

mkdir dags logs plugins

 

1. DAGs 디렉토리:

  • 역할: DAGs 디렉토리는 Airflow에서 실행할 워크플로우(DAG)를 정의한 Python 스크립트들이 저장되는 곳입니다. Airflow는 이 폴더를 지속적으로 스캔하여 새로운 DAG 파일을 읽어오고, 그 DAG을 스케줄링하여 실행합니다.
  • 필요성: DAG 파일은 Airflow의 핵심이며, 모든 워크플로우 정의가 이 디렉토리에 포함됩니다. DAG 파일이 없으면 Airflow는 어떤 작업도 스케줄링하거나 실행할 수 없습니다.

2.Logs 디렉토리:

  • 역할: 작업(Task)이 실행될 때마다 각 Task의 실행 로그가 저장되는 곳입니다. 로그는 각 작업이 성공했는지 실패했는지 또는 다른 오류가 발생했는지에 대한 중요한 정보를 제공합니다.
  • 필요성: 로그 파일은 DAG이 실행된 후 문제를 디버깅하거나, 작업의 상태를 모니터링하는 데 필수적입니다. 특히 작업이 실패한 경우 로그를 통해 문제의 원인을 파악할 수 있습니다.

3. Plugins 디렉토리:

  • 역할: 사용자 정의 기능(예: 사용자 정의 오퍼레이터, 훅(hook), 센서 등)을 추가할 때 사용하는 디렉토리입니다. Airflow는 기본적으로 다양한 오퍼레이터를 제공하지만, 특정 기능을 확장하거나 추가할 때 플러그인을 사용합니다.
  • 필요성: Airflow를 확장하여 사용자 정의 오퍼레이터나 센서를 개발할 때 이 디렉토리가 필요합니다. 이 디렉토리에 저장된 플러그인은 자동으로 Airflow에 로드되어 사용 가능합니다.

4. 전체 디렉토리 구조:

Airflow 프로젝트가 설치된 디렉토리의 전체 구조는 다음과 같이 구성됩니다. docker-compose.yaml 파일이 포함된 루트 디렉토리를 기준으로 아래와 같은 구조를 만들 수 있습니다.

<프로젝트 루트 디렉토리>
│
├── dags/               # DAG 스크립트들이 저장되는 디렉토리
│   └── example_dag.py   # 예시 DAG 파일
│
├── logs/               # 작업 실행 로그가 저장되는 디렉토리
│   └── <DAG 이름>/<태스크 이름>/...  # 로그 파일들
│
├── plugins/            # 플러그인 파일들이 저장되는 디렉토리
│   └── my_custom_operator.py  # 사용자 정의 오퍼레이터 파일
│
├── docker-compose.yaml # Docker Compose 설정 파일

 

5. 디렉토리 설명:

  1. dags/:
    • 모든 DAG 정의 파일들이 이 디렉토리에 위치합니다.
    • Airflow가 DAG을 스캔하여 작업을 스케줄링할 수 있도록 이 디렉토리에 저장된 Python 스크립트들을 참조합니다.
  2. logs/:
    • 작업 실행 중 발생한 로그가 저장됩니다. 각 DAG 및 작업별로 하위 디렉토리가 생성되어 로그가 정리됩니다.
    • 예: logs/my_dag/task_1/2024-10-01T12:00:00.log
  3. plugins/:
    • 사용자 정의 오퍼레이터나 훅을 정의한 Python 파일이 여기에 위치합니다.
    • Airflow는 이 디렉토리를 스캔하여 플러그인을 자동으로 불러옵니다.
  4. docker-compose.yaml:
    • Airflow를 Docker Compose로 실행할 때 필요한 설정 파일입니다.
    • 모든 컨테이너 (Webserver, Scheduler, Worker, PostgreSQL, Redis 등)가 정의되어 있습니다.

6. 파일 위치의 중요성:

  • DAGs 디렉토리는 DAG 파일을 자동으로 인식하기 위해 고정된 위치에 있어야 하며, docker-compose.yaml에서 ./dags:/opt/airflow/dags로 마운트됩니다.
  • Logs 디렉토리는 로그를 저장하고 디버깅을 위해 필요합니다. ./logs:/opt/airflow/logs로 마운트되어 로그 파일을 로컬에서 확인할 수 있습니다.
  • Plugins 디렉토리는 플러그인을 추가할 때 필요하며, 이 또한 ./plugins:/opt/airflow/plugins로 마운트되어 사용자 정의 오퍼레이터나 훅을 추가할 수 있습니다.

Airflow 초기화

Airflow를 처음 설치하면 데이터베이스 초기화가 필요합니다. 아래 명령어를 통해 초기화할 수 있습니다.

docker-compose up airflow-init

 

Airflow 시작

Airflow가 초기화된 후, 다음 명령어로 Airflow를 시작할 수 있습니다.

docker-compose up

 

이제 Airflow 웹 서버가 실행되며, 브라우저에서 http://localhost:8080으로 접속할 수 있습니다.

Admin 계정 생성

1. airflow-webserver 컨테이너 내부에 접속:

이미 실행 중인 airflow-webserver 컨테이너 내부에서 직접 airflow users create 명령어를 실행해야 합니다. 다음 명령어를 사용해 웹 서버 컨테이너에 접속할 수 있습니다:

docker exec -it airflow_airflow-webserver_1 /bin/bash

 

2. 사용자 계정 생성:

컨테이너 내부에 접속한 후, 다음 명령어로 새로운 관리자를 생성합니다:

airflow users create \
    --username admin \
    --firstname Admin \
    --lastname User \
    --role Admin \
    --email admin@example.com \
    --password admin

 

3. admin/admin 계정으로 접속

 

worker가 추가되려면?

만약 워커 노드를 여러 대로 분산 처리하고 싶다면, docker-compose.yaml에서 airflow-worker 서비스를 복사하여 추가적으로 설정할 수 있습니다. 예를 들어, 두 개 이상의 워커를 두고 싶다면 추가적인 airflow-worker를 정의하거나, 동일한 worker 서비스를 스케일링할 수 있습니다.

워커를 스케일링하는 방법:

Docker Compose에서는 스케일링 기능을 통해 쉽게 여러 워커 노드를 만들 수 있습니다.

docker-compose up --scale airflow-worker=3

 

위 명령어는 3개의 워커 컨테이너가 동시에 실행되도록 설정합니다. 이를 통해 워커 노드를 3대까지 확장하여 작업을 분산 처리할 수 있습니다.

'Tools > Airflow' 카테고리의 다른 글

Airflow Dag와 Task  (0) 2024.10.05