管理 DAG 文件

创建新 DAG 文件或修改现有 DAG 文件时,需要将它们部署到环境中。本节将介绍一些可以使用的基本技术。

在 Docker 镜像中烘焙 DAG

使用这种方法,您可以将 dag 文件和相关代码包含在 airflow 镜像中。

此方法需要使用新的 docker 镜像重新部署 helm 图表中的服务,以便部署新的 DAG 代码。如果 DAG 代码预计不会频繁更改,则此方法特别有效。

docker build --pull --tag "my-company/airflow:8a0da78" . -f - <<EOF
FROM apache/airflow

COPY ./dags/ \${AIRFLOW_HOME}/dags/

EOF

注意

在 2.0.2 之前的 Airflow 镜像版本中,存在一个错误,要求您使用更长的 Dockerfile,以确保镜像保持 OpenShift 兼容性(即 DAG 具有与其他文件类似的根组)。在 2.0.2 中,此问题已得到修复。

docker build --pull --tag "my-company/airflow:8a0da78" . -f - <<EOF
FROM apache/airflow:2.0.2

USER root

COPY --chown=airflow:root ./dags/ \${AIRFLOW_HOME}/dags/

USER airflow

EOF

然后将其发布到可访问的注册表中

docker push my-company/airflow:8a0da78

最后,使用该镜像更新 Airflow Pod

helm upgrade --install airflow apache-airflow/airflow \
  --set images.airflow.repository=my-company/airflow \
  --set images.airflow.tag=8a0da78

如果您正在部署具有固定标签的镜像,则需要确保每次都拉取该镜像。

警告

使用固定标签应该仅用于测试/开发目的。使用相同的标签是一个不好的做法,因为您将丢失代码的历史记录。

helm upgrade --install airflow apache-airflow/airflow \
  --set images.airflow.repository=my-company/airflow \
  --set images.airflow.tag=8a0da78 \
  --set images.airflow.pullPolicy=Always \
  --set airflowPodAnnotations.random=r$(uuidgen)

随机生成的 Pod 注释将确保在 helm 升级时刷新 Pod。

如果您要从私有仓库部署镜像,则需要创建一个密钥,例如 gitlab-registry-credentials(有关详细信息,请参阅 从私有注册表中拉取镜像),并使用 --set registry.secretName 指定它

helm upgrade --install airflow apache-airflow/airflow \
  --set images.airflow.repository=my-company/airflow \
  --set images.airflow.tag=8a0da78 \
  --set images.airflow.pullPolicy=Always \
  --set registry.secretName=gitlab-registry-credentials

使用 Git-sync

使用启用了持久化的 Git-Sync 辅助容器挂载 DAG

此选项将使用访问模式为 ReadWriteMany 的持久卷声明。调度程序 Pod 将每隔配置的秒数将 DAG 从 git 仓库同步到 PVC。其他 Pod 将读取同步的 DAG。并非所有卷插件都支持 ReadWriteMany 访问模式。有关详细信息,请参阅 持久卷访问模式

helm upgrade --install airflow apache-airflow/airflow \
  --set dags.persistence.enabled=true \
  --set dags.gitSync.enabled=true
  # you can also override the other persistence or gitSync values
  # by setting the  dags.persistence.* and dags.gitSync.* values
  # Please refer to values.yaml for details

使用未启用持久化的 Git-Sync 辅助容器挂载 DAG

此选项将在每个调度程序、Web 服务器(如果 airflowVersion < 2.0.0)和 Worker Pod 上使用始终运行的 Git-Sync 辅助容器。Git-Sync 辅助容器将每隔配置的秒数将 DAG 从 git 仓库同步一次。如果您使用的是 KubernetesExecutor,则 Git-sync 将在您的 Worker Pod 上作为初始化容器运行。

helm upgrade --install airflow apache-airflow/airflow \
  --set dags.persistence.enabled=false \
  --set dags.gitSync.enabled=true
  # you can also override the other gitSync values
  # by setting the  dags.gitSync.* values
  # Refer values.yaml for details

当使用 apache-airflow >= 2.0.0 时,默认情况下启用 DAG 序列化,因此 Web 服务器不需要访问 DAG 文件,因此 git-sync 辅助容器不会在 Web 服务器上运行。

结合使用 git-sync 和持久化的注意事项

虽然可以同时使用 git-sync 和持久性来处理 DAG,但通常不建议这样做,除非部署管理器仔细考虑了它带来的权衡。在某些情况下,没有持久性的 git-sync 会有其他权衡(例如,DAGS 同步延迟与 Git 服务器的速率限制),这些权衡通常可以通过其他方式来缓解(例如,在新提交推送到存储库时通过 Webhook 向 git-sync 容器发送信号),但您可能仍然希望选择同时使用 git-sync 和持久性,但作为部署管理器,您应该意识到它带来的一些后果。

git-sync 解决方案主要设计用于本地、符合 POSIX 的卷,用于将 Git 存储库检出到其中。git-sync 从 Git 同步提交的过程的一部分涉及在一个新创建的文件夹中检出新版本的文件,并在检出完成后将符号链接交换到新文件夹。这样做是为了确保整个 DAGs 文件夹始终保持一致。git-sync 使用符号链接交换的方式,确保解析 DAG 始终在整个 DAG 文件夹中的一组一致的(基于单个提交的)文件上工作。

然而,当 git-sync 工作的文件夹不是本地卷而是持久卷(因此实际上是网络分布式卷)时,这种方法可能会产生不良的副作用。根据持久卷背后的技术,可能会以不同的方式处理 git-sync 方法,并产生不明显的后果。各种 K8S 安装程序都有很多持久性解决方案可用,而且每种解决方案都有不同的特性,因此您需要仔细测试和监控您的文件系统,以确保这些不希望出现的副作用不会影响您。这些影响可能会随着时间的推移而改变,或者取决于参数,例如 Dag 文件处理器扫描文件的频率、DAG 的数量和复杂性、持久卷的远程程度和分布程度、为某些文件系统分配的 IOPS 数量(通常这种文件系统的高付费功能是您可以获得多少 IOPS)以及许多其他因素。

git-sync 使用符号链接交换的方式通常会导致吞吐量的线性增长和同步的潜在延迟。来自检出的网络流量是突发的,突发的大小与存储库中文件的大小和数量成线性关系,这使得它很容易受到相当突然和意外的需求增长的影响。大多数持久性解决方案对于较小/较短的流量突发都能“足够好”地工作,但是当它们超过某些阈值时,您需要将网络升级到功能更强大、成本更高的选项。这是难以控制和不可能缓解的,因此您可能会突然面临支付更多 IOPS/持久性选项费用的情况,以保持您的 DAG 足够同步,以避免不一致和同步延迟。

您可能会观察到的副作用

  • 在新提交被检出时,网络/通信的突发(因为快速连续地删除旧文件、创建新文件、交换符号链接)。

  • 在同步 DAG 时,DAG 文件夹中的文件之间暂时缺乏一致性(因为将更改分发到集群中各个节点的延迟)。

  • 当您的 DAG 数量增长时,持久性解决方案的性能明显下降,这种下降可能会放大上述副作用。

  • 某些持久性解决方案可能缺少 git-sync 执行同步所需的文件系统功能(例如更改权限或创建符号链接)。虽然这些通常可以缓解,但建议仅将 git-sync 与完全符合 POSIX 文件系统的持久性文件系统一起使用。

一般建议仅在本地卷上使用 git-sync,如果您还想使用持久性,则需要确保您使用的持久性解决方案符合 POSIX,并监控它可能产生的副作用。

使用 git-sync 同步多个 Git 仓库

Helm Chart 中的 Airflow git-sync 集成不允许同时配置多个要同步的仓库。DAG 文件夹必须来自单个 git 仓库。但是,可以使用 子模块 创建一个“伞”仓库,您可以使用它将多个 git 仓库一起检出(使用 --submodules recursive 选项)。有一些 Airflow 用户的成功案例,他们使用这种方法将数百个仓库作为子模块通过这种“伞”仓库方法组合在一起。但是,当您选择此解决方案时,您需要找出如何链接子模块、何时在“子模块”仓库更改时更新伞仓库,并制定版本控制方法并将其自动化。这可能很简单,例如始终使用所有子模块仓库的最新版本,也可能很复杂,例如跨多个团队管理共享库、DAG 和代码的版本控制,并按照您的发布流程进行操作。

在 Airflow 峰会的 大规模管理 DAG 演示文稿中可以找到这种复杂方法的示例。

从外部填充的 PVC 挂载 DAG

在这种方法中,Airflow 将从具有 ReadOnlyManyReadWriteMany 访问模式的 PVC 读取 DAG。您必须确保 PVC 已填充/更新了所需的 DAG(这不会由图表处理)。您将卷声明的名称传递给图表

helm upgrade --install airflow apache-airflow/airflow \
  --set dags.persistence.enabled=true \
  --set dags.persistence.existingClaim=my-volume-claim \
  --set dags.gitSync.enabled=false

使用 Git-Sync 辅助容器从私有 GitHub 仓库挂载 DAG

如果您还没有在 GitHub 上创建私有仓库,请创建一个。

然后创建您的 ssh 密钥

ssh-keygen -t rsa -b 4096 -C "[email protected]"

将公钥添加到您的私有仓库(在 设置 > 部署 密钥 下)。

您必须将私有 ssh 密钥转换为 base64 字符串。您可以像这样转换私有 ssh 密钥文件

base64 <my-private-ssh-key> -w 0 > temp.txt

然后从 temp.txt 文件中复制字符串。接下来,您需要将其添加到 override-values.yaml 中。

在本例中,您将创建一个名为 override-values.yaml 的 yaml 文件来覆盖 values.yaml 文件中的值,而不是使用 --set

dags:
  gitSync:
    enabled: true
    repo: [email protected]:<username>/<private-repo-name>.git
    branch: <branch-name>
    subPath: ""
    sshKeySecret: airflow-ssh-secret
extraSecrets:
  airflow-ssh-secret:
    data: |
      gitSshKey: '<base64-converted-ssh-private-key>'

不要忘记复制您的私钥 base64 字符串。

最后,在 Airflow Helm 图表目录的上下文中,您可以安装 Airflow

helm upgrade --install airflow apache-airflow/airflow -f override-values.yaml

如果您已正确完成所有操作,Git-Sync 将获取您对私有 GitHub 存储库中 DAG 所做的更改。

您应该更进一步,设置 dags.gitSync.knownHosts,这样您就不会受到中间人攻击的影响。此过程记录在生产指南中。

此条目有帮助吗?