문제 상황
- 특정 프로젝트에서 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
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
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 서비스에서는 누락 확인
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: ""
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