DAG 在 Google Cloud Composer 网络服务器上不可点击,但在本地 Airflow 上运行良好

Posted

技术标签:

【中文标题】DAG 在 Google Cloud Composer 网络服务器上不可点击,但在本地 Airflow 上运行良好【英文标题】:DAGs not clickable on Google Cloud Composer webserver, but working fine on a local Airflow 【发布时间】:2018-12-15 12:43:29 【问题描述】:

我正在使用 Google Cloud Composer(Google Cloud Platform 上的托管 Airflow)和图像版本 composer-0.5.3-airflow-1.9.0 和 Python 2.7,我遇到了一个奇怪的问题:导入我的 DAG 后,它们不可点击 来自 Web 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 不可点击,并且“近期任务”和“DAG 运行”列将永远加载。每个 DAG 名称旁边的“信息”标记显示: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 上导入脚本时,网络服务器工作正常:

一些测试

如果我将entries = gcs_conn.list(bucket, prefix=prefix) 行替换为entries = [u'my_dag_1', u'my_dag_2', u'my_dag_3', u'my_dag_4'] 之类的硬编码值,则可以在Composer Web UI 上点击DAG(并且会显示“链接”列上的所有按钮)。看来,从我对最初问题所做的其他测试来看,从钩子调用方法(不仅仅是初始化钩子)会导致问题。当然,Composer 中的 DAG 在简单示例上正常工作(不涉及挂钩方法调用)。

我不知道为什么会这样,我也检查了日志(通过在airflow.cfg 中设置logging_level = DEBUG)但看不出有什么问题。我怀疑网络服务器中存在错误,但我无法获得重要的堆栈跟踪。来自 Composer(托管在 App Engine 上)的网络服务器日志不可用,或者至少我没有找到访问它们的方法。

是否有人在使用 Composer Web UI 时遇到过相同或类似的问题?我认为问题出在钩子的使用上,但我可能错了。这可能只是一个副作用。老实说,在测试了这么多东西后,我迷失了。如果有人可以帮助我,我会很高兴。谢谢!

更新

当按照本指南在 Kubernetes 上部署自我管理的网络服务器时:https://cloud.google.com/composer/docs/how-to/managing/deploy-webserver,我的 DAG 可以从这个自我管理的网络服务器中点击。

【问题讨论】:

我对 Composer 不熟悉,但是两个组件(网络服务器和调度程序)都在运行吗?路径设置是否正确? @tobi6 是的,两者都由 Composer 运行和管理。也没有办法重新启动它们。我不确定“正确设置路径”是什么意思,但 Airflow 配置是由 Google 在配置环境时完成的。奇怪的是,它在简单的例子上都能正常工作(不涉及任何钩子方法调用)。 当我遇到这样的问题时,第一次部署了 DAG 文件,但第二次我搞砸了,文件位于错误的文件夹中。如果谷歌做到了这一切,我想文件夹是正确的,但我怀疑这可能与文件有关。可能是所有权不正确或某些设置问题? 有时,Airflow 会在 db 中实例化一个 DAG,其中存在某种 python 问题,这将阻止 DAG 实际运行,从而在 UI 中留下不可点击的 DAG。你能在常规 Airflow 中重现这个问题吗? @tobi6 我确信文件没有问题,因为用硬编码值替换entries 而不是调用钩子方法(如我在测试部分中展示的那样)有效。 @VirajParekh 实际上不,我无法重现本地 Airflow 安装的问题,这是我主要关心的问题!所以我认为这个错误与 Composer 有关,但我在日志中找不到相关内容:( 【参考方案1】:

Composer 网络服务器使用与 Composer GKE 集群中的节点不同的服务帐户运行。您应该确保已为您的网络服务器的服务帐户分配了适当的角色/权限。

例如如果您的网络服务器的网址是:

foo-tp.appspot.com

那么服务帐号是:

foo-tp@appspot.gserviceaccount.com

【讨论】:

谢谢,它有效!但是,奇怪的是,在创建 Composer 环境时,并没有自动创建这个服务帐户。您知道我们如何管理其他权限,例如访问 Compute 上的自托管数据库吗?对于 Google Storage(Storage Viewer 角色)来说这很容易,但对于非托管工具来说似乎更难。 大家好,您能详细解释一下吗?我有同样的问题,dag 不可点击。我应该在哪里分配网络服务器服务帐户? @TuanVu 只需创建服务帐户,网络服务器应使用它,无需指定其他内容 @norbjd 是不是像在composer环境起来后创建这个服务账号那么简单?我面临着同样的问题,不明白为什么作曲家会忽略如此重要的事情。 我不确定这是否不是同一个问题,或者我不明白答案。如果我的气流服务器是 b1ccd38045a27e929-tp.appspot.com ,您是否建议需要 gsutil iam ch serviceAccount:b1ccd38045a27e929-tp@appspot.gserviceaccount.com:objectViewer gs://my-bucket ?因为授予objectViewer 对我来说似乎没有任何改变。

以上是关于DAG 在 Google Cloud Composer 网络服务器上不可点击,但在本地 Airflow 上运行良好的主要内容,如果未能解决你的问题,请参考以下文章

使用 Pub/Sub 消息触发 Cloud Composer DAG

google-cloud-composer BigQuery 跨数据集加载

Google Cloud Composer (Apache Airflow) 无法访问日志文件

添加第一个 dag 时出现 Cloud Composer 调度程序错误

Cloud Composer DAG 级别访问控制

如何设置 Airflow DAG 权限以查询基于 Google Sheets 文档构建的 BigQuery 表?