【问题标题】:Airflow giving log file does not exist error while running on Docker在 Docker 上运行时,气流给出日志文件不存在错误
【发布时间】:2020-01-04 13:12:05
【问题描述】:

调度程序和网络服务器在不同的容器上运行,当我运行 DAG 并检查网络服务器上的日志时,它向我显示了这个特定的错误。

*** Log file does not exist: /usr/local/airflow/logs/indexing/index_articles/2019-12-31T00:00:00+00:00/1.log
*** Fetching from: http://465e0f4a4332:8793/log/indexing/index_articles/2019-12-31T00:00:00+00:00/1.log
*** Failed to fetch log file from worker. HTTPConnectionPool(host='465e0f4a4332', port=8793): Max retries exceeded with url: /log/indexing/index_articles/2019-12-31T00:00:00+00:00/1.log (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f0a143700d0>: Failed to establish a new connection: [Errno 111] Connection refused'))

我设置了其他类似问题中提到的气流变量,我在 cfg 文件中更改的唯一变量是这些。

AIRFLOW__CORE__SQL_ALCHEMY_CONN=postgresql+psycopg2://airflow:airflow@postgres:5432/airflow
AIRFLOW__CORE__LOAD_EXAMPLES=False
AIRFLOW__CORE__BASE_URL = http://{hostname}:8080

我手动检查并正确生成了日志文件,我假设唯一的问题是无法通过网络服务器容器公开访问 url。我不确定我在哪里搞砸了,我正在本地运行和测试它。

【问题讨论】:

  • 我使用 dags.persistence.accessMode=ReadWriteMany 解决了这个问题

标签: python airflow airflow-scheduler


【解决方案1】:

问题是因为 docker 容器不共享文件系统。这由响应的第一行指示。

Airflow 然后回退到尝试通过 HTTP 获取日志文件,如响应的第二行所示。其他答案尝试通过覆盖 HOSTNAME_CALLABLE 函数来解决此问题,但是除非主机通过 HTTP 公开日志文件,否则这将不起作用。

解决方案是通过挂载共享卷来解决第一个问题。

在您的 docker-compose.yml 文件中,添加一个名为 logs-volume 的新卷。

volumes:
  logs-volume:

然后,同样在 docker-compose.yml 文件中,将此卷添加到所需的日志目录,在您的情况下为 /usr/local/airflow/logs/,用于每个服务:

services: 
  worker:
    volumes:
      - logs-volume:/usr/local/airflow/logs
  webserver:
    volumes:
      - logs-volume:/usr/local/airflow/logs

【讨论】:

  • 我相信这个解决方案只有在每个服务都在同一个主机上运行时才有效。
【解决方案2】:

工作人员的主机名未正确解析。 添加文件hostname_resolver.py

import os
import socket
import requests
def resolve():
    """
    Resolves Airflow external hostname for accessing logs on a worker
    """
    if 'AWS_REGION' in os.environ:
        # Return EC2 instance hostname:
        return requests.get(
            'http://169.254.169.254/latest/meta-data/local-ipv4').text
    # Use DNS request for finding out what's our external IP:
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(('1.1.1.1', 53))
    external_ip = s.getsockname()[0]
    s.close()
    return external_ip

并导出:AIRFLOW__CORE__HOSTNAME_CALLABLE=airflow.hostname_resolver:resolve

【讨论】:

  • 我应该在哪里创建文件?
  • 它应该在airflow 文件夹中。确保所有气流服务都可以访问它。就我而言,这就是Dockerfile 的样子:sh COPY patches/hostname_resolver.py /tmp/ RUN cp /tmp/hostname_resolver.py $(pip show apache-airflow | grep ^Location | cut -d' ' -f2)/airflow/
【解决方案3】:

我在使用 Airflow 中的 docker-composeCeleryExecutor 时遇到了同样的问题。我的问题与运行airflow webserver 命令的容器无法访问在另一台机器上运行的celery worker 节点有关。

我通过在工作节​​点中公开预期端口并在运行网络服务器的主节点中添加 DNS 条目来解决此问题。

Celery Worker docker-compose 文件:

...
services:
  airflow-worker:
    <<: *airflow-common
    hostname: worker_my_hostname
    ports:
      - 8793:8793
    command: celery worker
    restart: always

主节点 docker-compose 文件部分:

---
version: "3"
x-airflow-common: &airflow-common
  extra_hosts:
    - "worker_my_hostname:10.10.59.200"
...

带有原始失败消息的日志:

Failed to fetch log file from worker. HTTPConnectionPool(host='worker_my_hostname', port=8793): Max retries exceeded with url: /log/dag_id/task_id/2021-05-14T20:24:49.433789+00:00/1.log (Caused by NewConnectionError('&lt;urllib3.connection.HTTPConnection object at 0x7f91cb1b7ac8&gt;: Failed to establish a new connection: [Errno 111] Connection refused',))

【讨论】:

    猜你喜欢
    • 2021-04-19
    • 1970-01-01
    • 2023-03-30
    • 2017-01-25
    • 2022-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    相关资源
    最近更新 更多