[Airflow] Docker Compose 환경에서 .env 누락 점검

Woong·약 22시간 전
0

Apache Airflow

목록 보기
10/10

문제 상황

  • 특정 프로젝트에서 Airflow를 Docker Compose로 배포하는 상황
  • DAG 실행 과정에서 celery queue 가 production 환경임에도 staging 환경 기준으로 실행되어 worker 할당이 되지 않아 fail 되는 상황
    • worker 에서는 환경변수로 설정된 celery queue 를 잘 바라보나, dag trigger 시 할당하는 celery queue 가 staging 기준이었음
x-airflow-common:
  &airflow-common
  environment:
    &airflow-common-env
    AIRFLOW__CORE__EXECUTOR: CeleryExecutor
    AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: ${AIRFLOW__DATABASE__SQL_ALCHEMY_CONN}
    AIRFLOW__CELERY__RESULT_BACKEND: ${AIRFLOW__CELERY__RESULT_BACKEND}
    AIRFLOW__CELERY__BROKER_URL: ${AIRFLOW__CELERY__BROKER_URL}
    AIRFLOW__CORE__FERNET_KEY: ${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'
    AIRFLOW__CORE__DEFAULT_TIMEZONE: Asia/Seoul
...

services:
  ...
  airflow-scheduler:
    <<: *airflow-common
    command: scheduler
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:8974/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    # (이 env_file 이 누락되어 있었음)
    #env_file:
    #  - .env
    restart: always
    depends_on:
      redis:
        condition: service_healthy
      postgres:
        condition: service_healthy
      airflow-init:
        condition: service_completed_successfully

  my-project-worker:
    <<: *airflow-common
    container_name: my-project-worker
    # 여기 있는 환경변수는 잘 가져오고 있었다. .env 설정을 잘 했으니까.
    command: celery worker -q ${CELERY_QUEUE_NAME:-<prod_queue_1>}
    ports:
      - "8793:8793"
    healthcheck:
      test:
        - "CMD-SHELL"
        - 'celery --app airflow.providers.celery.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}"'
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    environment:
      <<: *airflow-common-env
      DUMB_INIT_SETSID: "0"
      AIRFLOW__CELERY__HOSTNAME_CALLABLE: airflow.utils.net.get_host_ip_address
    env_file:
      - .env
    restart: unless-stopped
...

env 누락 점검

  • worker container 에서 active_queues 로 worker 에서 바라보는 queue 점검
    • (worker 에서는 .env 가 정상 반영중이었던 상황이었으므로 문제없음)
$ celery -A airflow.executors.celery_executor.app inspect active_queues
->  celery@c57759e39078: OK
    * {'name': '<prod_queue_1>', 'exchange': {'name': '<prod_queue_1>', 'type': 'direct', 'arguments': None, 'durable': True, 'passive': False, 'auto_delete': False, 'delivery_mode': None, 'no_declare': False}, 'routing_key': 'l9_asia_detection_tasks', 'queue_arguments': None, 'binding_arguments': None, 'consumer_arguments': None, 'durable': True, 'exclusive': False, 'auto_delete': False, 'no_ack': False, 'alias': None, 'bindings': [], 'no_declare': None, 'expires': None, 'message_ttl': None, 'max_length': None, 'max_length_bytes': None, 'max_priority': None}
->  celery@410645b31ebb: OK
    * {'name': '<prod_queue_2>', 'exchange': {'name': '<prod_queue_2>', 'type': 'direct', 'arguments': None, 'durable': True, 'passive': False, 'auto_delete': False, 'delivery_mode': None, 'no_declare': False}, 'routing_key': 'monitoring_tasks', 'queue_arguments': None, 'binding_arguments': None, 'consumer_arguments': None, 'durable': True, 'exclusive': False, 'auto_delete': False, 'no_ack': False, 'alias': None, 'bindings': [], 'no_declare': None, 'expires': None, 'message_ttl': None, 'max_length': None, 'max_length_bytes': None, 'max_priority': None}

2 nodes online.
  • 하지만 dag run 실행시 staging 기준으로 실행되는 상황
    • staging, production 환경에 특수성이 있어 DAG 코드 내에서 환경변수에 따라 분기 처리하고 있던 상황
    • worker 에서는 prod 를 잘 바라보고 있는데, scheduler 에서 실행하니 그렇지 못한 상황
if os.getenv('environment') == 'production':
    CELERY_QUEUE_NAME = '<prod_queue_1>'
else:
    CELERY_QUEUE_NAME = '<staging_queue>'
  • docker compose 로 config parsing 점검
    • docker compose --env-file .env -f docker-compose.yaml config 명령으로 점검
    • worker 서비스에서는 .env 값 정상 반영
    • scheduler 서비스에서는 누락 확인
# scheduler 에서는 누락
docker compose --env-file .env -f docker-compose.yaml config | grep environment -A 1
    environment:
      _AIRFLOW_DB_MIGRATE: "true"
--
    environment:
      _PIP_ADDITIONAL_REQUIREMENTS: ""
--
    environment:
      _PIP_ADDITIONAL_REQUIREMENTS: ""
--
    environment:
      POSTGRES_DB: airflow
--
  environment:
    _PIP_ADDITIONAL_REQUIREMENTS: ""
# worker 에서는 정상 반영
docker compose --env-file .env -f docker-compose.yaml config | grep environment -A 1
    environment:
      _PIP_ADDITIONAL_REQUIREMENTS: ""
--
    environment:
      _PIP_ADDITIONAL_REQUIREMENTS: ""
--
      environment: production
      min_sales: "220000"
--
  environment:
    _PIP_ADDITIONAL_REQUIREMENTS: ""
  • worker 서비스에는 다음과 같이 .env 파일 명시:
    env_file:
      - .env
  • 하지만 scheduler 서비스에는 env_file: 누락
    • -> docker-compose 수정하여 webserver, scheduler 에서도 바라보도록 수정

docker compose restart 로 인한 문제

  • docker compose restart 하였으나 반영되지 않음
    • docker compose --env-file 옵션은 docker compose config 명령이나 up 시점에만 영향을 주며, restart 시에는 적용되지 않기 때문
    • -> docker compose up -d 로 env 갱신 반영하도록 배포 스크립트 수정
docker compose --env-file $ENV_FILE -f $COMPOSE_FILE up -d

0개의 댓글