生产环境部署

现在是将您的 DAG 部署到生产环境的时候了。为此,首先,您需要确保 Airflow 本身已准备好用于生产环境。让我们看看您需要采取哪些预防措施。

数据库后端

Airflow 默认带有 SQLite 后端。这允许用户在没有任何外部数据库的情况下运行 Airflow。但是,这种设置仅用于测试目的;在生产环境中运行默认设置可能会在多种情况下导致数据丢失。如果您想运行生产级的 Airflow,请确保将后端配置为 PostgreSQL 或 MySQL 等外部数据库。

您可以使用以下配置更改后端

[database]
sql_alchemy_conn = my_conn_string

更改后端后,airflow 需要创建操作所需的所有表。创建一个空的数据库,并授予 Airflow 的用户 CREATE/ALTER 权限。完成后,您可以运行 -

airflow db migrate

migrate 会跟踪已应用的迁移,因此您可以根据需要经常运行。

注意

在 Airflow 2.7.0 版本之前,airflow db upgrade 用于应用迁移,但是,它已被弃用,取而代之的是 airflow db migrate

多节点集群

Airflow 默认使用 SequentialExecutor。但是,从本质上讲,用户最多只能一次执行一个任务。Sequential Executor 还会在运行任务时暂停调度器,因此不建议在生产环境中使用。对于单机,您应该使用 LocalExecutor。对于多节点设置,您应该使用Kubernetes 执行器Celery 执行器

配置执行器后,必须确保集群中的每个节点都包含相同的配置和 DAG。Airflow 发送简单的指令,例如“执行 DAG Y 的任务 X”,但不发送任何 DAG 文件或配置。您可以使用简单的 cronjob 或任何其他机制在节点之间同步 DAG 和配置,例如,每 5 分钟在所有节点上从 git 存储库检出 DAG。

日志记录

如果您在集群中使用一次性节点,请将日志存储配置为分布式文件系统 (DFS),例如 S3GCS,或外部服务,例如 Stackdriver Logging、Elasticsearch 或 Amazon CloudWatch。这样,即使节点关闭或被替换,日志仍然可用。有关配置,请参阅任务日志记录

注意

日志仅在任务完成后才会出现在您的 DFS 中。您可以在 UI 中查看任务运行时日志。

配置

Airflow 捆绑了一个默认的 airflow.cfg 配置文件。您应该对跨部署更改的配置(例如元数据数据库、密码等)使用环境变量。您可以使用格式 AIRFLOW__{SECTION}__{KEY} 来完成此操作

AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=my_conn_id
AIRFLOW__WEBSERVER__BASE_URL=http://host:port

某些配置(例如 Airflow 后端连接 URI)也可以从 bash 命令派生

sql_alchemy_conn_cmd = bash_command_to_run

调度器正常运行时间

Airflow 用户偶尔会报告调度器无缘无故挂起的实例,例如在这些问题中

为了缓解这些问题,请确保您设置了一个健康检查,该检查将检测到您的调度器在一段时间内没有心跳。

生产容器镜像

我们提供一个用于 Apache Airflow 的 Docker 镜像 (OCI),用于容器化环境。考虑使用它来保证软件无论部署在哪里都始终以相同的方式运行。

Kubernetes 的 Helm Chart

Helm 提供了一种将软件部署到 Kubernetes 集群的简单机制。我们维护一个官方的 Airflow Helm chart,可帮助您定义、安装和升级部署。Helm Chart 使用我们官方的 Docker 镜像和 Dockerfile,它们也由社区维护和发布。

Airflow 的在线升级

Airflow 本身是一个分布式系统,虽然基本 Airflow 部署通常需要完全重启 Airflow 才能升级,但是当您在分布式部署中运行 Airflow 时,可以实现 Airflow 的无停机升级。

当 Airflow 元数据数据库架构没有更改时,可以进行这种在线升级,因此当您升级同一 Airflow 小版本的补丁级(错误修复)版本或在查看发布说明数据库迁移参考并确保它们之间的数据库架构没有更改后,升级相邻的 Airflow 小版本(功能)时,您应该以此为目标。

在某些情况下,当数据库迁移不明显时,通过先升级 Airflow 数据库并介于次要版本之间,也可能进行此类在线迁移,但是,不建议这样做,您应该仅在您自担风险的情况下执行此操作,仔细查看要应用于数据库架构的修改并评估此类升级的风险 - 这需要深入了解 Airflow 数据库数据库的 ERD 模式并查看数据库迁移参考。您始终应该首先在暂存环境中彻底测试此类升级。通常,与此类在线升级准备相关的成本将高于 Airflow 的短暂停机成本,因此我们强烈不建议此类在线升级。

在生产环境中执行此类在线升级程序之前,请确保在暂存环境中对其进行测试,以避免任何意外情况和副作用。

当涉及到 WebserverTriggerer 组件的在线升级时,如果它们在独立的环境中运行,并且每个组件都有多个实例,你可以逐个滚动重启它们,而不会有任何停机时间。这通常应作为升级过程的第一步完成。

当你在一个单独的 DAG 处理器 的部署中运行时,在 独立的 DAG 处理部署 中,DAG 处理器 不是水平扩展的 - 即使你有多个,通常每个特定文件夹一次只运行一个 DAG 处理器,所以你可以直接停止它并启动新的 - 但由于 DAG 处理器 不是关键组件,它可以承受短暂的停机时间。

当涉及到升级调度器和工作器时,你可以使用你所用执行器的在线升级功能。

  • 对于 本地执行器,你的任务作为调度器的子进程运行,你无法在不终止其运行的任务的情况下升级调度器。你可以暂停所有 DAG 并等待正在运行的任务完成,或者直接停止调度器并终止它运行的所有任务 - 然后你需要在升级完成后手动清除并重新启动这些任务(或者依赖于为停止的任务设置的 重试)。

  • 对于 Celery 执行器,你必须首先将你的工作器置于离线模式(通常通过向工作器发送一个 TERM 信号),等待工作器完成所有正在运行的任务,然后升级代码(例如通过替换工作器运行的镜像并重新启动工作器)。你可以通过 flower 监控工具监控你的工作器,并看到正在运行的任务数降至零。一旦工作器升级完成,它们将自动进入在线模式并开始接收新的任务。然后你可以以滚动重启模式升级 调度器

  • 对于 Kubernetes 执行器,你可以以滚动重启模式升级调度器、触发器和 Web 服务器,通常你不必担心工作器,因为它们由 Kubernetes 集群管理,并且在升级和重启后会被 调度器 自动采用。

  • 对于 CeleryKubernetesExecutor <apache-airflow-providers-celery:celery_kubernetes_executor>,你遵循与 CeleryExecutor 相同的步骤 - 你将工作器置于离线模式,等待正在运行的任务完成,升级工作器,然后以滚动重启模式升级调度器、触发器和 Web 服务器 - 这也应该采用通过执行器的 KubernetesExecutor 部分运行的任务。

大多数滚动重启升级场景都在 Apache Airflow 的 Helm Chart 中实现,所以你可以使用它来升级你的 Airflow 部署而不会有任何停机时间 - 特别是在你对 Airflow 进行补丁级升级的情况下。

Kerberos 身份验证的工作器

Apache Airflow 具有内置的机制,用于通过 KDC(密钥分发中心)进行身份验证。Airflow 有一个单独的命令 airflow kerberos,它充当令牌刷新器。它使用预配置的 Kerberos Keytab 在 KDC 中进行身份验证以获得有效的令牌,然后在当前令牌过期窗口内的固定时间间隔内刷新有效的令牌。

每次刷新请求都使用配置的主体,并且只有对指定主体有效的 keytab 才能检索身份验证令牌。

在这种情况下实现适当的安全机制的最佳实践是确保工作器工作负载无法访问 Keytab,而只能访问定期刷新的临时身份验证令牌。这可以在 Docker 环境中通过在单独的容器中运行 airflow kerberos 命令和工作器命令来实现 - 其中只有 airflow kerberos 令牌可以访问 Keytab 文件(最好配置为秘密资源)。这两个容器应该共享一个卷,其中临时令牌应该由 airflow kerberos 写入,并由工作器读取。

在 Kubernetes 环境中,这可以通过 sidecar 的概念实现,其中 Kerberos 令牌刷新器和工作器都是同一个 Pod 的一部分。只有 Kerberos sidecar 可以访问 Keytab 秘密,并且同一 Pod 中的两个容器共享卷,其中临时令牌由 sidecar 容器写入,并由工作器容器读取。

这个概念在 Apache Airflow 的 Helm Chart 中实现。

Google Cloud 上安全的服务器和服务访问

本节介绍当你的 Airflow 环境部署在 Google Cloud 上,或者你连接到 Google 服务,或者你连接到 Google API 时,安全访问服务器和服务的技术和解决方案。

IAM 和服务帐户

你不应该依赖内部网络分段或防火墙作为我们的主要安全机制。为了保护你组织的数据,你发出的每个请求都应包含发送者身份。对于 Google Cloud,身份由 IAM 和服务帐户提供。每个 Compute Engine 实例都有一个关联的服务帐户身份。它提供加密凭据,你的工作负载可以使用这些凭据在调用 Google API 或第三方服务时证明其身份。每个实例只能访问短期的凭据。如果你使用 Google 管理的服务帐户密钥,那么私钥始终会被托管,并且永远无法直接访问。

如果你使用 Kubernetes Engine,你可以使用 工作负载身份 为单个 pod 分配身份。

有关 Airflow 中服务帐户的更多信息,请参阅 Google Cloud 连接

模拟服务帐户

如果你需要访问其他服务帐户,你可以模拟其他服务帐户 以将令牌与默认身份交换为另一个服务帐户。因此,帐户密钥仍然由 Google 管理,你的工作负载无法读取。

不建议生成服务帐户密钥并将它们存储在元数据数据库或秘密后端中。即使使用后端秘密,服务帐户密钥也对你的工作负载可用。

访问 Compute Engine 实例

如果你想建立到 Compute Engine 实例的 SSH 连接,你必须拥有该实例的网络地址以及访问它的凭据。为了简化此任务,你可以使用 ComputeEngineHook 而不是 SSHHook

ComputeEngineHook 支持使用 Google OS Login 服务进行身份验证。这是一种非常强大的方式来正确管理 Linux 访问,因为它将短期的 ssh 密钥存储在元数据服务中,为访问和 sudo 特权检查提供 PAM 模块,并为元数据服务提供 nsswitch 用户查找。

它还解决了随着基础设施增长而出现的发现问题。你可以使用实例名称而不是网络地址。

访问 Amazon Web Service

借助 Web Identity Federation,你可以将 Google Cloud Platform 身份交换为 Amazon Web Service 身份,这实际上意味着可以访问 Amazon Web Service 平台。有关更多信息,请参阅:使用 Web Identity Federation 进行 Google Cloud 到 AWS 的身份验证

这个条目有帮助吗?