生产部署¶
现在是时候在生产环境中部署您的 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 文件或配置。您可以使用简单的 cron 作业或任何其他机制在您的节点之间同步 DAG 和配置,例如,每 5 分钟在所有节点上从 git 存储库中检出 DAG。
日志记录¶
如果您在集群中使用一次性节点,请将日志存储配置为分布式文件系统 (DFS),例如 S3
和 GCS
,或外部服务,例如 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
生产容器镜像¶
我们提供 Apache Airflow 的 Docker 镜像 (OCI),用于容器化环境。考虑使用它来确保软件无论部署在何处始终运行相同。
Kubernetes 的 Helm Chart¶
Helm 提供了一种将软件部署到 Kubernetes 集群的简单机制。我们维护 Airflow 的官方 Helm Chart,可帮助您定义、安装和升级部署。Helm Chart 使用 我们的官方 Docker 镜像和 Dockerfile,这些镜像和 Dockerfile 也由社区维护和发布。
Airflow 在线升级¶
Airflow 在设计上是一个分布式系统,虽然 基本 Airflow 部署 通常需要完全重启 Airflow 才能升级,但当您在 分布式部署 中运行 Airflow 时,可以在不停机的情况下升级 Airflow。
当 Airflow 元数据数据库架构没有变化时,这种在线升级是可能的,因此您应该在升级相同次要 Airflow 版本的补丁级别(错误修复)版本时,或者在查看 发行说明 和 数据库迁移参考 并确保它们之间的数据库架构没有变化后,在升级 Airflow 相邻次要版本(功能)之间进行升级时,都应该进行这种升级。
在某些情况下,当数据库迁移不重要时,这种在线迁移也可能在首先升级 Airflow 数据库和次要版本之间进行,但是,不建议这样做,您应该自行承担风险,仔细审查要应用于数据库架构的修改并评估此类升级的风险 - 它需要深入了解 Airflow 数据库 数据库的 ERD 模式 并审查 数据库迁移参考。您应该始终先在测试环境中彻底测试此类升级。通常,与此类在线升级准备工作相关的成本将高于 Airflow 短暂停机的成本,因此我们强烈建议不要进行此类在线升级。
在生产环境中执行此操作之前,请确保在测试环境中测试此类在线升级过程,以避免任何意外和副作用。
当涉及到在线升级 Webserver
、Triggerer
组件时,如果您在单独的环境中运行它们并且每个组件都有多个实例,则可以逐个滚动重启它们,而不会造成任何停机时间。这通常应该是您升级过程中的第一步。
当您在 单独的 DAG 处理部署 中运行具有单独 DAG 处理器
的部署时,DAG 处理器
不是水平扩展的 - 即使您有更多 DAG 处理器
,通常每个特定文件夹一次只运行一个 DAG 处理器
,因此您可以将其停止并启动新的 - 但由于 DAG 处理器
不是关键组件,因此它可以短暂停机。
当涉及到升级调度程序和工作器时,您可以使用您使用的执行器的在线升级功能
对于 本地执行器,您的任务作为调度程序的子进程运行,您无法在不终止其运行的任务的情况下升级调度程序。您可以暂停所有 DAG 并等待正在运行的任务完成,或者停止调度程序并终止其运行的所有任务 - 然后您需要在升级完成后手动清除并重启这些任务(或者依赖于为已停止的任务设置的
重试
)。对于 Celery 执行器,您必须先将工作节点置于离线模式(通常是通过向工作节点发送单个
TERM
信号),等待工作节点完成所有正在运行的任务,然后升级代码(例如,通过替换工作节点运行的镜像并重启工作节点)。您可以通过flower
监控工具监控您的工作节点,并查看正在运行的任务数量下降到零。工作节点升级完成后,它们将自动置于在线模式并开始获取新任务。然后,您可以以滚动重启模式升级调度器
。对于 Kubernetes 执行器,您可以以滚动重启模式升级调度器触发器和 Web 服务器,通常您不必担心工作节点,因为它们由 Kubernetes 集群管理,并且在
调度器
升级和重启后会自动采用它们。对于 :doc:
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 密钥表在 KDC 中进行身份验证以获取有效的令牌,然后在当前令牌到期窗口内定期刷新有效的令牌。
每次刷新请求都使用配置的主体,并且只有对指定主体有效的密钥表才能检索身份验证令牌。
在这种情况下,实现适当安全机制的最佳做法是确保工作节点工作负载无法访问密钥表,而只能访问定期刷新的临时身份验证令牌。这可以通过在 Docker 环境中运行 airflow kerberos
命令和工作节点命令在不同的容器中来实现 - 其中只有 airflow kerberos
令牌可以访问密钥表文件(最好配置为机密资源)。这两个容器应该共享一个卷,临时令牌应该由 airflow kerberos
写入并由工作节点读取。
在 Kubernetes 环境中,这可以通过边车(sidecar)的概念来实现,其中 Kerberos 令牌刷新器和工作节点都是同一个 Pod 的一部分。只有 Kerberos 边车可以访问密钥表机密,并且同一个 Pod 中的两个容器共享卷,临时令牌由边车容器写入并由工作节点容器读取。
这个概念在 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 身份联合,您可以将 Google Cloud Platform 身份交换为 Amazon Web Service 身份,这实际上意味着可以访问 Amazon Web Service 平台。有关更多信息,请参阅:使用 Web 身份联合进行 Google Cloud 到 AWS 身份验证