生产指南¶
以下是在生产环境中使用此 Helm 图表时需要考虑的事项。
数据库¶
建议为 Airflow 元数据存储设置外部数据库。默认的 Helm 图表部署了一个在容器中运行的 Postgres 数据库。对于生产环境,应使用在专用机器上运行的数据库或利用云提供商的数据库服务(如 AWS RDS),因为嵌入式 Postgres 缺乏生产数据库所需的稳定性、监控和持久性功能。它只是为了更容易地在“独立”版本中测试 Helm 图表,但当您使用它时,您可能会遇到数据丢失。支持的数据库和版本可以在 设置数据库后端 中找到。
注意
使用 helm 图表时,您不需要使用 设置数据库后端 中所述的 airflow db migrate
初始化数据库。
首先禁用 Postgres,这样图表就不会部署自己的 Postgres 容器
postgresql:
enabled: false
要向 Airflow 提供数据库凭据,您有两种选择 - 在值文件中或在 Kubernetes 密钥中。
值文件¶
这是更简单的选择,因为图表将为您创建一个 Kubernetes 密钥。但是,请记住,您的凭据将在您的值文件中。
data:
metadataConnection:
user: <username>
pass: <password>
protocol: postgresql
host: <hostname>
port: 5432
db: <database name>
Kubernetes 密钥¶
您也可以将凭据存储在您创建的 Kubernetes 密钥中。请注意,用户名/密码中的特殊字符必须进行 URL 编码。
kubectl create secret generic mydatabase --from-literal=connection=postgresql://user:pass@host:5432/db
最后,配置图表以使用您创建的密钥
data:
metadataSecretName: mydatabase
警告
如果您使用 CeleryExecutor
且 Airflow 版本 < 2.4
,请记住 resultBackendSecretName
需要以 db+postgresql://
开头的 URL,而 metadataSecretName
需要 postgresql://
并且不能与 db+postgresql://
一起使用。您需要创建具有正确方案的单独密钥。对于 Airflow 版本 >= 2.4
,可以省略结果后端密钥,因为 Airflow 默认情况下将使用 sql_alchemy_conn
(在 metadataSecret
中指定)和 db+ 方案前缀。
PgBouncer¶
如果您使用 PostgreSQL 作为数据库,您可能还需要启用 PgBouncer。由于 Airflow 的分布式特性,它可能会打开许多数据库连接,而使用连接池可以显著减少数据库上的打开连接数。
pgbouncer:
enabled: true
根据您的 Airflow 实例的大小,您可能还需要调整以下内容(显示默认值)
pgbouncer:
# The maximum number of connections to PgBouncer
maxClientConn: 100
# The maximum number of server connections to the metadata database from PgBouncer
metadataPoolSize: 10
# The maximum number of server connections to the result backend database from PgBouncer
resultBackendPoolSize: 5
Web 服务器密钥¶
使用此图表进行部署时,您应该设置一个静态的 Web 服务器密钥,因为它将有助于确保您的 Airflow 组件仅在必要时重新启动。
警告
您应该为运行的每个实例使用不同的密钥,因为此密钥用于对会话 cookie 进行签名并执行其他与安全相关的功能!
首先,生成一个强密钥
python3 -c 'import secrets; print(secrets.token_hex(16))'
现在将密钥添加到您的值文件中
webserverSecretKey: <secret_key>
或者,创建一个 Kubernetes 密钥并使用 webserverSecretKeySecretName
webserverSecretKeySecretName: my-webserver-secret
# where the random key is under `webserver-secret-key` in the k8s Secret
从 kubectl
创建 Kubernetes 密钥的示例
kubectl create secret generic my-webserver-secret --from-literal="webserver-secret-key=$(python3 -c 'import secrets; print(secrets.token_hex(16))')"
Web 服务器密钥还用于在检索日志时授权对 Celery 工作器的请求。但是,使用密钥生成的令牌的有效期很短 - 确保运行 Airflow 组件的所有机器上的时间同步(例如使用 ntpd),否则在访问日志时可能会出现“禁止”错误。
驱逐配置¶
在将 Airflow 与 Kubernetes 集群自动缩放器 一起运行时,配置 Pod 是否可以安全驱逐非常重要。此设置可以在 Airflow 图表中以不同的级别进行配置
workers:
safeToEvict: true
scheduler:
safeToEvict: true
webserver:
safeToEvict: true
使用 KubernetesExecutor
时,应将 workers.safeToEvict
设置为 false
,以避免它们在完成之前被删除。
扩展和自定义 Airflow 镜像¶
Apache Airflow 社区发布了 Docker 镜像,这些镜像是 Apache Airflow 的 参考镜像
。但是,Airflow 拥有超过 60 个社区管理的提供程序(可通过 extras 安装),并且并非每个人都使用默认安装的一些 extras/providers,有时需要其他 extras/providers,有时(实际上经常)您需要添加自己的自定义依赖项、包甚至自定义提供程序,或者添加部署中需要的自定义工具和二进制文件。
在 Kubernetes 和 Docker 术语中,这意味着您需要另一个具有特定要求的镜像。这就是为什么您应该学习如何构建自己的 Docker
(或更准确地说是 容器
)镜像。
您希望使用自定义镜像的典型场景
添加
apt
包添加
PyPI
包添加部署所需的二进制资源
添加部署中需要的自定义工具
有关如何扩展和自定义 Airflow 镜像的更多详细信息,请参阅 构建镜像。
管理 DAG 文件¶
请参阅 管理 DAG 文件。
knownHosts¶
如果您使用的是 dags.gitSync.sshKeySecret
,那么您还应该设置 dags.gitSync.knownHosts
。这里我们将展示 GitHub 的流程,但其他提供商也可以这样做
获取 GitHub 的公钥
ssh-keyscan -t rsa github.com > github_public_key
接下来,打印公钥的指纹
ssh-keygen -lf github_public_key
将该输出与 GitHub 的 SSH 密钥指纹 进行比较。
它们匹配,对吧?很好。现在,将公钥添加到您的值中。它看起来像这样
dags:
gitSync:
knownHosts: |
github.com ssh-rsa AAAA...1/wsjk=
外部调度器¶
要使用外部调度器实例
scheduler:
enabled: false
确保您的外部 Web 服务器/调度器连接到同一个 Redis 主机。这将确保调度器知道 helm-chart 中部署的工作器。
访问 Airflow UI¶
您如何访问 Airflow UI 将取决于您的环境;但是,图表确实支持各种选项
外部 Web 服务器¶
要使用外部 Web 服务器
webserver:
enabled: false
确保您的外部 Web 服务器/调度器连接到同一个 Redis 主机。这将确保调度器知道 helm-chart 中部署的工作器。
Ingress¶
您可以创建和配置 Ingress
对象。请参阅 Ingress 图表参数。有关 Ingress
的更多信息,请参阅 Kubernetes Ingress 文档。
LoadBalancer 服务¶
您可以将 Web 服务器的 Service 类型更改为 LoadBalancer
,并设置任何必要的注释
webserver:
service:
type: LoadBalancer
有关 LoadBalancer
服务的更多信息,请参阅 Kubernetes LoadBalancer 服务文档。
指标¶
图表可以支持将指标发送到现有的 StatsD 实例或提供 Prometheus 端点。
Prometheus¶
指标端点位于 svc/{{ .Release.Name }}-statsd:9102/metrics
。
外部 StatsD¶
要使用外部 StatsD 实例
statsd:
enabled: false
config:
metrics: # or 'scheduler' for Airflow 1
statsd_on: true
statsd_host: ...
statsd_port: ...
Datadog¶
如果您在环境中使用 Datadog 代理,这将使 Airflow 能够将指标导出到 Datadog 代理。
statsd:
enabled: false
config:
metrics: # or 'scheduler' for Airflow 1
statsd_on: true
statsd_port: 8125
extraEnv: |-
- name: AIRFLOW__METRICS__STATSD_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
Celery 后端¶
如果您使用的是 CeleryExecutor
或 CeleryKubernetesExecutor
,则可以使用您自己的 Celery 后端。
默认情况下,图表将部署 Redis。但是,您可以使用任何受支持的 Celery 后端来代替
redis:
enabled: false
data:
brokerUrl: redis://redis-user:password@redis-host:6379/0
有关设置 Celery 代理的更多信息,请参阅Celery 文档中关于此主题的详尽说明。
安全上下文约束¶
安全上下文约束
(SCC) 是 OpenShift 的一种结构,其作用类似于 RBAC 规则;但是,它的目标是 Pod 而不是用户。在定义 SCC 时,可以控制 Pod 在启动和运行期间可以执行的操作和访问的资源。
SCC 被划分为不同的级别或类别,其中 restricted
SCC 是分配给 Pod 的默认 SCC。在将 Airflow 部署到 OpenShift 时,可以利用 SCC 并允许 Pod 使用 anyuid
SCC 启动容器。
为了启用 SCC 的使用,必须将参数 rbac.createSCCRoleBinding 设置为 true
,如下所示
rbac:
create: true
createSCCRoleBinding: true
在此图表中,SCC 通过 RoleBindings 绑定到 Pod,这意味着还必须将选项 rbac.create
设置为 true
才能完全启用 SCC 的使用。
有关 SCC 以及可以使用此结构实现的功能的更多信息,请参阅管理安全上下文约束。
安全上下文¶
在 Kubernetes 中,可以使用 securityContext
定义用户 ID、组 ID 和功能,例如以特权模式运行容器。
将应用程序部署到 Kubernetes 时,建议为容器赋予最小权限,以减少访问权限并保护运行容器的主机。
在 Airflow Helm 图表中,可以通过以下几种方式配置 securityContext
uid(配置全局 uid 或 RunAsUser)
gid(配置全局 gid 或 fsGroup)
securityContexts(与
uid
相同,但允许设置所有 Pod securityContext 选项 和 容器 securityContext 选项)
与配置全局 securityContexts 相同,也可以通过设置其本地 securityContexts
为特定工作负载配置不同的值,如下所示
workers:
securityContexts:
pod:
runAsUser: 5000
fsGroup: 0
containers:
allowPrivilegeEscalation: false
在上面的示例中,工作程序 Pod securityContexts
将设置为 runAsUser: 5000
和 fsGroup: 0
。容器 pod 将设置为 allowPrivilegeEscalation: false
。
如您所见,本地设置在定义时将优先于全局设置。以下说明了此图表中 securityContexts
选项的优先级规则
uid: 40000
gid: 0
securityContexts:
pod:
runAsUser: 50000
fsGroup: 0
workers:
securityContexts:
pod:
runAsUser: 1001
fsGroup: 0
这将生成以下工作程序部署
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: airflow-worker
spec:
serviceName: airflow-worker
template:
spec:
securityContext: # As the securityContexts was defined in ``workers``, its value will take priority
runAsUser: 1001
fsGroup: 0
如果我们从上面的示例中删除 securityContexts
和 workers.securityContexts
,则输出将如下所示
uid: 40000
gid: 0
securityContexts: {}
workers:
securityContexts: {}
这将生成以下工作程序部署
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: airflow-worker
spec:
serviceName: airflow-worker
template:
spec:
securityContext:
runAsUser: 40000 # As the securityContext was not defined in ``workers`` or ``podSecurity``, the value from uid will be used
fsGroup: 0 # As the securityContext was not defined in ``workers`` or ``podSecurity``, the value from gid will be used
initContainers:
- name: wait-for-airflow-migrations
...
containers:
- name: worker
...
最后,如果我们设置了 securityContexts
但没有设置 workers.securityContexts
uid: 40000
gid: 0
securityContexts:
pod:
runAsUser: 50000
fsGroup: 0
workers:
securityContexts: {}
这将生成以下工作程序部署
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: airflow-worker
spec:
serviceName: airflow-worker
template:
spec:
securityContext: # As the securityContexts was not defined in ``workers``, the values from securityContexts will take priority
runAsUser: 50000
fsGroup: 0
initContainers:
- name: wait-for-airflow-migrations
...
containers:
- name: worker
...
内置密钥和环境变量¶
默认情况下,Helm 图表使用 Kubernetes Secrets 存储 Airflow 所需的密钥。默认情况下,这些密钥的内容将转换为 Airflow 读取的环境变量(某些环境变量具有多个变体以支持旧版本的 Airflow)。
默认情况下,密钥名称由部署 Helm 图表时使用的版本名称确定,但您也可以使用其他密钥来设置变量,或者完全禁用使用密钥并依赖环境变量(特别是如果您想使用环境变量的 _CMD
或 __SECRET
变体)。
但是,Airflow 支持其他设置密钥配置的变体 - 您可以指定一个系统命令来检索和自动轮换密钥(通过使用 _CMD
后缀定义变量)或从密钥支持中检索变量(通过使用 _SECRET
后缀定义变量)。
如果设置了 <VARIABLE_NAME>>
,它将优先于 _CMD
和 _SECRET
变体,因此如果您想设置 _CMD
或 _SECRET
变体之一,则必须通过将 .Values.enableBuiltInSecretEnvVars.<VARIABLE_NAME>
设置为 false 来禁用从 Kubernetes 密钥检索的内置变量。
例如,为了使用命令检索数据库连接,您应该(在您的 values.yaml
文件中)指定
extraEnv:
AIRFLOW_CONN_AIRFLOW_DB_CMD: "/usr/local/bin/retrieve_connection_url"
enableBuiltInSecretEnvVars:
AIRFLOW_CONN_AIRFLOW_DB: false
以下是可以通过 _CMD
和 _SECRET
变体禁用和替换的密钥的完整列表
如果未指定密钥名称,则默认密钥名称 |
使用其他 Kubernetes Secret |
Airflow 环境变量 |
---|---|---|
|
|
AIRFLOW_CONN_AIRFLOW_DB AIRFLOW__DATABASE__SQL_ALCHEMY_CONN |
|
|
|
|
|
|
|
|
AIRFLOW__CELERY__CELERY_RESULT_BACKEND AIRFLOW__CELERY__RESULT_BACKEND |
|
|
|
|
|
AIRFLOW__ELASTICSEARCH__HOST AIRFLOW__ELASTICSEARCH__ELASTICSEARCH_HOST |
还有许多密钥,其名称也由版本名称确定,不需要禁用。这是因为它们要么不遵循 _CMD
或 _SECRET
模式,要么是不以 AIRFLOW__
开头的变量,要么是没有对应变量的变量。
还有一个 _AIRFLOW__*
变量 AIRFLOW__CELERY__FLOWER_BASIC_AUTH
不需要禁用,即使您想设置 _CMD
和 _SECRET
变体。默认情况下不设置此变量。仅当设置了 .Values.flower.secretName
或设置了 .Values.flower.user
和 .Values.flower.password
时才会设置它。因此,如果您没有设置任何 .Values.flower.*
变量,则可以使用 _CMD
或 _SECRET
变体自由配置 Flower Basic Auth,而无需禁用基本变体。
如果未指定密钥名称,则默认密钥名称 |
使用其他 Kubernetes Secret |
Airflow 环境变量 |
---|---|---|
|
|
|
|
|
|
|
||
|
|
|
|
||
|
|
|
您可以在设置配置选项中阅读有关设置配置变量的高级方法的更多信息。