生产部署¶
是时候将您的 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 默认使用 LocalExecutor
。对于多节点设置,您应该使用 Kubernetes executor 或 Celery executor。
配置好 executor 后,需要确保集群中的每个节点包含相同的配置和 DAG。Airflow 发送的是简单的指令,例如“执行 DAG Y 的任务 X”,但不会发送任何 DAG 文件或配置。您可以使用简单的 cronjob 或任何其他机制来同步所有节点上的 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
调度器正常运行时间¶
Airflow 用户偶尔会报告调度器无故卡死的情况,例如在这些问题中
为缓解这些问题,请确保您已设置了 健康检查,该检查将检测您的调度器是否长时间没有心跳。
生产容器镜像¶
我们提供 Apache Airflow 的 Docker 镜像 (OCI),可用于容器化环境。考虑使用它来保证软件无论部署在哪里都能一致运行。
用于 Kubernetes 的 Helm Chart¶
Helm 提供了一种将软件部署到 Kubernetes 集群的简单机制。我们维护 官方 Helm chart,可帮助您定义、安装和升级 Airflow 部署。该 Helm Chart 使用 官方 Docker 镜像和 Dockerfile,这些也由社区维护和发布。
Airflow 不停机升级¶
Airflow 在设计上是一个分布式系统,虽然 基础 Airflow 部署 通常需要完全重启 Airflow 才能升级,但在 分布式部署 中运行时,可以在不停机的情况下升级 Airflow。
当 Airflow 元数据数据库 schema 没有变化时,这种不停机升级是可能的,因此您应该在升级相同次要版本的 Airflow 的补丁级别(错误修复)版本时进行,或者在仔细查阅 发布说明 和 数据库迁移参考 并确保数据库 schema 之间没有变化后,在相邻的次要版本(功能)之间升级 Airflow 时进行。
在某些情况下,当数据库迁移不重要时,通过先升级 Airflow 数据库,并在 MINOR 版本之间进行,这种不停机迁移也可能实现,但这不被推荐,您应自行承担风险,仔细审查将要应用于数据库 schema 的修改并评估此类升级的风险——这需要深入了解 Airflow 数据库 数据库的 ERD Schema 并审查 数据库迁移参考。您应该始终首先在预生产环境 (staging environment) 中彻底测试此类升级。通常,此类不停机升级准备相关的成本会高于 Airflow 短暂停机的成本,因此我们强烈不鼓励此类不停机升级。
在生产环境进行此类不停机升级之前,请务必在预生产环境 (staging environment) 中测试该过程,以避免任何意外和副作用。
至于不停机升级 Webserver
、Triggerer
组件,如果您在单独环境中运行它们且每个组件有多个实例,则可以逐个进行滚动重启,而无需任何停机。这通常应该是您的升级过程中的第一步。
当您运行包含单独 DAG processor
的部署时,在 单独 DAG 处理部署 中,DAG processor
不会进行水平扩展——即使您有多个实例,通常每个特定文件夹一次只有一个 DAG processor
运行,所以您可以直接停止它并启动新的——但由于 DAG processor
不是关键组件,经历短暂的停机是可以接受的。
在升级调度器和 worker 时,您可以使用所用 executor 的不停机升级能力
对于 本地 executor,您的任务作为调度器的子进程运行,您无法在不终止其运行的任务的情况下升级调度器。您可以暂停所有 DAG 并等待正在运行的任务完成,或者直接停止调度器并终止其运行的所有任务——然后您需要在升级完成后手动清除并重新启动这些任务(或依靠为停止的任务设置的
retry
)。对于 Celery executor,您必须首先将 worker 置于离线模式(通常通过向 worker 发送单个
TERM
信号),等待 worker 完成所有正在运行的任务,然后升级代码(例如通过替换 worker 运行的镜像并重新启动 worker)。您可以通过flower
监控工具监控 worker,并查看正在运行的任务数量降至零。worker 升级完成后,将自动进入在线模式并开始接收新任务。然后您可以以滚动重启模式升级Scheduler
。对于 Kubernetes executor,您可以以滚动重启模式升级 scheduler、triggerer、webserver,并且通常无需担心 worker,因为它们由 Kubernetes 集群管理,并在升级和重启后由
Schedulers
自动接管。对于 CeleryKubernetesExecutor,您遵循与
CeleryExecutor
相同的过程——将 worker 置于离线模式,等待正在运行的任务完成,升级 worker,然后以滚动重启模式升级 scheduler、triggerer 和 webserver——这也应该接管通过该 executor 的KubernetesExecutor
部分运行的任务。
大多数滚动重启升级场景已在 Helm Chart for Apache Airflow 中实现,因此您可以使用它在不停机的情况下升级您的 Airflow 部署——特别是在进行 Airflow 补丁级别升级的情况下。
Kerberos 认证的 Worker¶
Apache Airflow 内置了一种与 KDC (Key Distribution Center) 进行操作认证的机制。Airflow 有一个单独的命令 airflow kerberos
,用于刷新 token。它使用预配置的 Kerberos Keytab 在 KDC 中进行认证以获取有效 token,然后在当前 token 有效期窗口内定期刷新有效 token。
每次刷新请求都使用配置好的 principal,并且只有对指定 principal 有效的 keytab 才能检索认证 token。
在这种情况下实现适当安全机制的最佳实践是确保 worker 工作负载无法访问 Keytab,而只能访问定期刷新的临时认证 token。这可以在 Docker 环境中通过在单独的容器中运行 airflow kerberos
命令和 worker 命令来实现——其中只有生成 airflow kerberos
token 的容器可以访问 Keytab 文件(最好配置为 secret 资源)。这两个容器应共享一个 volume,临时 token 应由 airflow kerberos
写入,并由 worker 读取。
在 Kubernetes 环境中,这可以通过 sidecar 的概念来实现,其中 Kerberos token 刷新器和 worker 都是同一个 Pod 的一部分。只有 Kerberos sidecar 可以访问 Keytab secret,并且同一个 Pod 中的两个容器共享 volume,临时 token 由 sidecar 容器写入,并由 worker 容器读取。
这个概念已在 Helm Chart for Apache Airflow 中实现。
Google Cloud 上的安全服务器和服务访问¶
本节介绍当您的 Airflow 环境部署在 Google Cloud 上,或者您连接到 Google 服务,或者您正在连接到 Google API 时,安全访问服务器和服务的技术和解决方案。
IAM 和服务账号¶
您不应依赖内部网络分段或防火墙作为主要安全机制。为保护您组织的数据,您发出的每个请求都应包含发送者身份。在 Google Cloud 中,身份由 IAM 和 Service account 提供。每个 Compute Engine 实例都有关联的服务账号身份。它提供加密凭据,您的工作负载在调用 Google API 或第三方服务时可以使用这些凭据来证明其身份。每个实例只能访问短期凭据。如果您使用 Google 管理的服务账号密钥,私钥将始终由托管服务保管,绝不会直接暴露。
如果您正在使用 Kubernetes Engine,可以使用 Workload Identity 为单个 pod 分配身份。
有关 Airflow 中服务账号的更多信息,请参阅:Google Cloud 连接
模拟服务账号¶
如果您需要访问其他服务账号,可以模拟其他服务账号,将默认身份的 token 交换为其他服务账号的 token。这样,账号密钥仍然由 Google 管理,无法被您的工作负载读取。
不建议生成服务账号密钥并将其存储在元数据数据库或 secrets 后端。即使使用 secrets 后端,服务账号密钥对于您的工作负载仍然可用。
访问 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 的认证