DAG 在 Google Cloud Composer 网络服务器上不可点击,但在本地 Airflow 上运行良好
DAGs not clickable on Google Cloud Composer webserver, but working fine on a local Airflow
我正在使用图像版本 composer-0.5.3-airflow-1.9.0
和 Python 2.7 的 Google Cloud Composer(Google 云平台上的托管 Airflow),我遇到了一个奇怪的问题: 导入我的 DAG 后,它们 无法从网络上点击 UI(并且没有按钮 "Trigger DAG"、"Graph view"、...) ,而当 运行 本地 Airflow 时一切正常。
即使无法从 Composer 上的网络服务器使用,我的 DAG 仍然存在。我可以使用 CLI (list_dags
) 列出它们,描述它们 (list_tasks
),甚至触发它们 (trigger_dag
)。
重现问题的最小示例
我用来重现该问题的一个最小示例如下所示。使用钩子(这里,GoogleCloudStorageHook
)非常重要,因为使用钩子时会发生 Composer 上的错误。最初,我使用的是自定义挂钩(在自定义插件中),并且遇到了同样的问题。
基本上在这里,该示例列出了 GCS 存储桶 (my-bucket
) 中的所有条目,并为每个以 my_dag
.
开头的条目生成一个 DAG
import datetime
from airflow import DAG
from airflow.contrib.hooks.gcs_hook import GoogleCloudStorageHook
from airflow.operators.bash_operator import BashOperator
google_conn_id = 'google_cloud_default'
gcs_conn = GoogleCloudStorageHook(google_conn_id)
bucket = 'my-bucket'
prefix = 'my_dag'
entries = gcs_conn.list(bucket, prefix=prefix)
for entry in entries:
dag_id = str(entry)
dag = DAG(
dag_id=dag_id,
start_date=datetime.datetime.today(),
schedule_interval='0 0 1 * *'
)
op = BashOperator(
task_id='test',
bash_command='exit 0',
dag=dag
)
globals()[dag_id] = dag
Cloud Composer 上的结果
将此文件导入 Composer 后,结果如下(我在 my-bucket
中有 4 个以 my_dag
开头的文件):
正如我所解释的,DAG 不可点击,"Recent Tasks" 和 "DAG Runs" 列将永远加载。每个 DAG 名称旁边的 "info" 标记表示:This DAG isn't available in the webserver DagBag object. It shows up in this list because the scheduler marked it as active in the metadata database
.
当然刷新是没有用的,直接URL(https://****.appspot.com/admin/airflow/graph?dag_id=my_dag_1
)访问DAG Graph View时,报错:DAG "my_dag_1" seems to be missing.
本地 Airflow 的结果
在本地 Airflow 上导入脚本时,网络服务器工作正常:
一些测试
如果我将行 entries = gcs_conn.list(bucket, prefix=prefix)
替换为 entries = [u'my_dag_1', u'my_dag_2', u'my_dag_3', u'my_dag_4']
等硬编码值,则 DAG 可在 Composer Web UI 上点击(以及 "links" 列上的所有按钮出现)。从我对初始问题所做的其他测试来看,似乎 从钩子 调用方法(不仅仅是初始化钩子)导致了问题。当然,Composer 中的 DAG 在简单示例上正常工作(不涉及 hooks 方法调用)。
我不知道为什么会这样,我也检查了日志(通过在 airflow.cfg
中设置 logging_level = DEBUG
)但没有发现任何错误。我怀疑网络服务器中存在错误,但我无法获得重要的堆栈跟踪。来自 Composer(托管在 App Engine 上)的 Web 服务器日志不可用,或者至少我没有找到访问它们的方法。
是否有人在使用 Composer Web UI 时遇到过相同或类似的问题?我认为问题出在钩子的使用上,但我可能错了。它可能只是一个副作用。老实说,我测试了这么多东西后迷路了。如果有人能帮助我,我会很高兴。谢谢!
更新
按照本指南在 Kubernetes 上部署自我管理的网络服务器时:https://cloud.google.com/composer/docs/how-to/managing/deploy-webserver,我的 DAG 可从此自我管理的网络服务器中单击。
Composer 网络服务器使用与 Composer GKE 集群中的节点不同的服务帐户运行。您应确保已将适当的 role/permissions 分配给网络服务器的服务帐户。
例如如果您的网络服务器的 url 是:
foo-tp.appspot.com
那么服务帐号是:
foo-tp@appspot.gserviceaccount.com
我正在使用图像版本 composer-0.5.3-airflow-1.9.0
和 Python 2.7 的 Google Cloud Composer(Google 云平台上的托管 Airflow),我遇到了一个奇怪的问题: 导入我的 DAG 后,它们 无法从网络上点击 UI(并且没有按钮 "Trigger DAG"、"Graph view"、...) ,而当 运行 本地 Airflow 时一切正常。
即使无法从 Composer 上的网络服务器使用,我的 DAG 仍然存在。我可以使用 CLI (list_dags
) 列出它们,描述它们 (list_tasks
),甚至触发它们 (trigger_dag
)。
重现问题的最小示例
我用来重现该问题的一个最小示例如下所示。使用钩子(这里,GoogleCloudStorageHook
)非常重要,因为使用钩子时会发生 Composer 上的错误。最初,我使用的是自定义挂钩(在自定义插件中),并且遇到了同样的问题。
基本上在这里,该示例列出了 GCS 存储桶 (my-bucket
) 中的所有条目,并为每个以 my_dag
.
import datetime
from airflow import DAG
from airflow.contrib.hooks.gcs_hook import GoogleCloudStorageHook
from airflow.operators.bash_operator import BashOperator
google_conn_id = 'google_cloud_default'
gcs_conn = GoogleCloudStorageHook(google_conn_id)
bucket = 'my-bucket'
prefix = 'my_dag'
entries = gcs_conn.list(bucket, prefix=prefix)
for entry in entries:
dag_id = str(entry)
dag = DAG(
dag_id=dag_id,
start_date=datetime.datetime.today(),
schedule_interval='0 0 1 * *'
)
op = BashOperator(
task_id='test',
bash_command='exit 0',
dag=dag
)
globals()[dag_id] = dag
Cloud Composer 上的结果
将此文件导入 Composer 后,结果如下(我在 my-bucket
中有 4 个以 my_dag
开头的文件):
正如我所解释的,DAG 不可点击,"Recent Tasks" 和 "DAG Runs" 列将永远加载。每个 DAG 名称旁边的 "info" 标记表示:This DAG isn't available in the webserver DagBag object. It shows up in this list because the scheduler marked it as active in the metadata database
.
当然刷新是没有用的,直接URL(https://****.appspot.com/admin/airflow/graph?dag_id=my_dag_1
)访问DAG Graph View时,报错:DAG "my_dag_1" seems to be missing.
本地 Airflow 的结果
在本地 Airflow 上导入脚本时,网络服务器工作正常:
一些测试
如果我将行 entries = gcs_conn.list(bucket, prefix=prefix)
替换为 entries = [u'my_dag_1', u'my_dag_2', u'my_dag_3', u'my_dag_4']
等硬编码值,则 DAG 可在 Composer Web UI 上点击(以及 "links" 列上的所有按钮出现)。从我对初始问题所做的其他测试来看,似乎 从钩子 调用方法(不仅仅是初始化钩子)导致了问题。当然,Composer 中的 DAG 在简单示例上正常工作(不涉及 hooks 方法调用)。
我不知道为什么会这样,我也检查了日志(通过在 airflow.cfg
中设置 logging_level = DEBUG
)但没有发现任何错误。我怀疑网络服务器中存在错误,但我无法获得重要的堆栈跟踪。来自 Composer(托管在 App Engine 上)的 Web 服务器日志不可用,或者至少我没有找到访问它们的方法。
是否有人在使用 Composer Web UI 时遇到过相同或类似的问题?我认为问题出在钩子的使用上,但我可能错了。它可能只是一个副作用。老实说,我测试了这么多东西后迷路了。如果有人能帮助我,我会很高兴。谢谢!
更新
按照本指南在 Kubernetes 上部署自我管理的网络服务器时:https://cloud.google.com/composer/docs/how-to/managing/deploy-webserver,我的 DAG 可从此自我管理的网络服务器中单击。
Composer 网络服务器使用与 Composer GKE 集群中的节点不同的服务帐户运行。您应确保已将适当的 role/permissions 分配给网络服务器的服务帐户。
例如如果您的网络服务器的 url 是:
foo-tp.appspot.com
那么服务帐号是:
foo-tp@appspot.gserviceaccount.com