You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Airflow 3 Docker部署:任务状态异常与连接拒绝问题排查

Airflow 3 Docker部署调度器连接API失败排查与解决

问题背景

虚拟机上采用Docker拆分服务部署Airflow 3,对应的docker-compose配置如下:

x-airflow-common: &airflow-common
  image: ${AIRFLOW_IMAGE}
  restart: unless-stopped
  env_file: .env
  environment:
    # ---- Airflow (principales) ----
    AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: ${AIRFLOW__DATABASE__SQL_ALCHEMY_CONN}
    AIRFLOW__SDK__API_BASE_URL: ${AIRFLOW__SDK__API_BASE_URL}
    AIRFLOW__CORE__EXECUTOR: ${AIRFLOW__CORE__EXECUTOR}
    AIRFLOW__CORE__FERNET_KEY: ${AIRFLOW__CORE__FERNET_KEY}
    AIRFLOW__CORE__LOAD_EXAMPLES: ${AIRFLOW__CORE__LOAD_EXAMPLES}
    AIRFLOW__CORE__DEFAULT_TIMEZONE: ${AIRFLOW__CORE__DEFAULT_TIMEZONE}
    AIRFLOW__WEBSERVER__BASE_URL: ${AIRFLOW__WEBSERVER__BASE_URL}
    AIRFLOW__WEBSERVER__DEFAULT_UI_TIMEZONE: ${AIRFLOW__WEBSERVER__DEFAULT_UI_TIMEZONE}
    AIRFLOW__DATABASE__SQL_ALCHEMY_ENGINE_OPTIONS: ${AIRFLOW__DATABASE__SQL_ALCHEMY_ENGINE_OPTIONS}
    AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_USERS: ${AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_USERS}
    AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_PASSWORDS_FILE: ${AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_PASSWORDS_FILE}

    # ---- Réseau / Proxy : neutraliser tout proxy pour les appels internes ----
    NO_PROXY: "localhost,127.0.0.1,web,af_web,airflow.local,*.local"
    no_proxy: "localhost,127.0.0.1,web,af_web,airflow.local,*.local"
    HTTP_PROXY: ""
    HTTPS_PROXY: ""
    http_proxy: ""
    https_proxy: ""
  user: "${AIRFLOW_UID}:${AIRFLOW_GID}"
  volumes:
    - ./dags:/opt/airflow/dags
    - ./logs:/opt/airflow/logs
    - ./simple_auth_passwords.json:/opt/airflow/simple_auth_passwords.json
  networks:
    airflow_net: {}

services:
  # === API + UI Airflow ===
  web:
    <<: *airflow-common
    container_name: af_web
    ports:
      - "8080:8080"
    command: >
      bash -lc "
        airflow db migrate &&
        airflow api-server --host 0.0.0.0 --port 8080 --proxy-headers --workers 4
      "
    healthcheck:
      test: ["CMD", "bash", "-lc", "curl -sf http://localhost:8080/api/v2/monitor/health | grep -q 'healthy'"]
      interval: 10s
      timeout: 5s
      retries: 12
    networks:
      airflow_net:
        aliases: [web, af_web]

  # === Scheduler ===
  scheduler:
    <<: *airflow-common
    container_name: af_scheduler
    command: >
      bash -lc "
        export NO_PROXY='localhost,127.0.0.1,web,af_web,airflow.local,*.local' &&
        export no_proxy='$NO_PROXY' &&
        export HTTP_PROXY= HTTPS_PROXY= http_proxy= https_proxy= &&
        export AIRFLOW__SDK__API_BASE_URL='http://web:8080' &&
        airflow db migrate &&
        airflow scheduler
      "
    depends_on:
      web:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "airflow", "db", "check"]
      interval: 20s
      timeout: 5s
      retries: 10

  # === DAG Processor (parse/serialize des DAGs) ===
  dag_processor:
    <<: *airflow-common
    container_name: af_dagproc
    command: >
      bash -lc "
        export NO_PROXY='localhost,127.0.0.1,web,af_web,airflow.local,*.local' &&
        export no_proxy='$NO_PROXY' &&
        export HTTP_PROXY= HTTPS_PROXY= http_proxy= https_proxy= &&
        export AIRFLOW__SDK__API_BASE_URL='http://web:8080' &&
        airflow dag-processor
      "
    depends_on:
      web:
        condition: service_healthy
      scheduler:
        condition: service_started

  # === Triggerer (capteurs asynchrones) ===
  triggerer:
    <<: *airflow-common
    container_name: af_triggerer
    command: >
      bash -lc "
        export NO_PROXY='localhost,127.0.0.1,web,af_web,airflow.local,*.local' &&
        export no_proxy='$NO_PROXY' &&
        export HTTP_PROXY= HTTPS_PROXY= http_proxy= https_proxy= &&
        export AIRFLOW__SDK__API_BASE_URL='http://web:8080' &&
        airflow triggerer
      "
    depends_on:
      web:
        condition: service_healthy
      scheduler:
        condition: service_started

networks:
  airflow_net:
    driver: bridge

报错信息

运行DAG时出现:

Finished with state failed, but the task instance's state attribute is queued.

调度器日志显示连接拒绝:

httpx.ConnectError: [Errno 111] Connection refused

已确认执行airflow config get-value sdk api_base_url返回http://web:8080,配置看似正常。


排查与解决方案

1. 环境变量重复设置冲突

在x-airflow-common模板中已通过env_file加载AIRFLOW__SDK__API_BASE_URL,但各服务的启动命令中又手动export该变量,可能因bash变量解析问题导致实际生效的地址错误。同时代理变量也存在重复设置的问题,容易引发网络请求异常。

修复:
删除scheduler、dag_processor、triggerer命令中的所有export语句,直接使用common模板中定义的环境变量即可。

2. 无效网络配置导致连通性问题

docker-compose末尾存在不完整的dock网络定义,可能破坏airflow_net的网络连通性,导致调度器无法解析web服务地址。

修复:
确保networks块仅保留有效配置:

networks:
  airflow_net:
    driver: bridge

3. API服务就绪状态验证

虽然配置了depends_on依赖web服务的健康状态,但仍需手动验证调度器容器能否正常访问API:

# 进入调度器容器
docker exec -it af_scheduler bash
# 测试API连通性
curl http://web:8080/api/v2/monitor/health

如果无法返回healthy,检查所有服务是否都加入了airflow_net网络:

docker network inspect airflow_net

4. 执行器配置不匹配

Airflow 3拆分服务部署时,若使用SequentialExecutor会导致调度器与API的交互逻辑异常,需根据部署模式配置对应执行器:

  • 分布式部署:使用CeleryExecutor(需额外部署Redis/RabbitMQ)或KubernetesExecutor
  • 单机测试:使用SequentialExecutor(此时无需拆分调度器等服务)

检查.env中的AIRFLOW__CORE__EXECUTOR值,确保与部署模式匹配。


内容的提问来源于stack exchange,提问作者Ragnar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 01:40:56