生产指南

以下是在生产环境中使用此 Helm Chart 时需要考虑的事项。

数据库

建议为 Airflow 元数据存储设置外部数据库。默认的 Helm Chart 部署在容器中运行的 Postgres 数据库。对于生产用途,应该使用在专用机器上运行的数据库或利用云提供商的数据库服务(如 AWS RDS),因为嵌入式 Postgres 缺乏生产数据库所需的稳定性、监控和持久性功能。它仅用于简化在“独立”版本中测试 Helm Chart 的过程,但是当您使用它时,可能会遇到数据丢失。支持的数据库和版本可以在 设置数据库后端 中找到。

注意

当使用 helm chart 时,您不需要像 设置数据库后端 中概述的那样使用 airflow db migrate 初始化数据库。

首先禁用 Postgres,以便 chart 不会部署自己的 Postgres 容器

postgresql:
  enabled: false

要向 Airflow 提供数据库凭据,您有两种选择 - 在 values 文件中或在 Kubernetes Secret 中。

Values 文件

这是更简单的选项,因为 chart 将为您创建一个 Kubernetes Secret。但是,请记住您的凭据将位于您的 values 文件中。

data:
  metadataConnection:
    user: <username>
    pass: <password>
    protocol: postgresql
    host: <hostname>
    port: 5432
    db: <database name>

Kubernetes Secret

您还可以将凭据存储在您创建的 Kubernetes Secret 中。请注意,用户名/密码中的特殊字符必须进行 URL 编码。

kubectl create secret generic mydatabase --from-literal=connection=postgresql://user:pass@host:5432/db

最后,配置 chart 以使用您创建的 secret

data:
  metadataSecretName: mydatabase

警告

如果您使用 CeleryExecutor 和 Airflow 版本 < 2.4,请记住 resultBackendSecretName 需要一个以 db+postgresql:// 开头的 URL,而 metadataSecretName 需要 postgresql:// 并且不适用于 db+postgresql://。您需要使用正确的方案创建单独的 secret。对于 Airflow 版本 >= 2.4,可以省略 result backend secret,因为 Airflow 将默认使用带有 db+ 方案前缀的 sql_alchemy_conn(在 metadataSecret 中指定)。

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

Webserver Secret Key

当使用此 chart 部署时,您应该设置一个静态的 webserver secret key,因为它可以帮助确保您的 Airflow 组件仅在必要时重新启动。

警告

您应该为您运行的每个实例使用不同的 secret key,因为此 key 用于签署会话 cookie 并执行其他安全相关的功能!

首先,生成一个强 secret key

python3 -c 'import secrets; print(secrets.token_hex(16))'

现在将 secret 添加到您的 values 文件

webserverSecretKey: <secret_key>

或者,创建一个 Kubernetes Secret 并使用 webserverSecretKeySecretName

webserverSecretKeySecretName: my-webserver-secret
# where the random key is under `webserver-secret-key` in the k8s Secret

kubectl 创建 Kubernetes Secret 的示例

kubectl create secret generic my-webserver-secret --from-literal="webserver-secret-key=$(python3 -c 'import secrets; print(secrets.token_hex(16))')"

webserver key 还用于授权对 Celery worker 的请求,以便在检索日志时使用。使用 secret key 生成的令牌具有较短的过期时间 - 请确保您运行 airflow 组件的所有机器上的时间都已同步(例如使用 ntpd),否则在访问日志时可能会出现“禁止”错误。

驱逐配置

当运行 Airflow 以及 Kubernetes Cluster Autoscaler 时,配置 pod 是否可以安全驱逐非常重要。可以在 Airflow chart 的不同级别配置此设置

workers:
  safeToEvict: true
scheduler:
  safeToEvict: true
webserver:
  safeToEvict: true

当使用 KubernetesExecutor 时,应将 workers.safeToEvict 设置为 false,以避免它们在完成之前被删除。

扩展和自定义 Airflow 镜像

Apache Airflow 社区发布 Docker 镜像,这些镜像是指 Apache Airflow 的 参考 镜像。但是,Airflow 有 60 多个社区管理的提供程序(可通过 extras 安装),并且并非每个人都使用某些默认安装的 extras/提供程序,有时需要其他 extras/提供程序,有时(实际上非常频繁)您需要添加自己的自定义依赖项、软件包甚至自定义提供程序,或者添加部署中需要的自定义工具和二进制文件。

在 Kubernetes 和 Docker 术语中,这意味着您需要另一个满足您特定要求的镜像。这就是为什么您应该学习如何构建自己的 Docker(或更恰当地说 Container)镜像。

您希望使用自定义镜像的典型场景

  • 添加 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 密钥指纹进行比较。

它们匹配,对吗?很好。现在,将公钥添加到您的 values 中。它看起来像这样

dags:
  gitSync:
    knownHosts: |
      github.com ssh-rsa AAAA...1/wsjk=

外部调度器

要使用外部调度器实例

scheduler:
  enabled: false

确保您的外部 webserver/调度器连接到同一个 redis 主机。这将确保调度器知道在 helm-chart 中部署的 worker。

访问 Airflow UI

您访问 Airflow UI 的方式取决于您的环境;但是,chart 支持各种选项

外部 Webserver

要使用外部 Webserver

webserver:
  enabled: false

确保您的外部 webserver/调度器连接到同一个 redis 主机。这将确保调度器知道在 helm-chart 中部署的 worker。

Ingress

您可以创建和配置 Ingress 对象。请参阅 Ingress chart 参数。有关 Ingress 的更多信息,请参阅 Kubernetes Ingress 文档

LoadBalancer 服务

您可以将 webserver 的 Service 类型更改为 LoadBalancer,并设置任何必要的注解

webserver:
  service:
    type: LoadBalancer

有关 LoadBalancer 服务的更多信息,请参阅 Kubernetes LoadBalancer 服务文档

日志记录

根据您选择的执行器,任务日志可能无法开箱即用。所有日志记录选项都可以在 管理日志 中找到。

指标

该 chart 可以支持将指标发送到现有的 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 后端

如果您正在使用 CeleryExecutorCeleryKubernetesExecutor,您可以自带 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

与可以配置全局 securityContexts 的方式相同,还可以通过设置其本地 securityContexts 来配置特定工作负载的不同值,如下所示

workers:
  securityContexts:
    pod:
      runAsUser: 5000
      fsGroup: 0
    containers:
      allowPrivilegeEscalation: false

在上面的示例中,worker Pod 的 securityContexts 将设置为 runAsUser: 5000fsGroup: 0。容器 pod 将设置为 allowPrivilegeEscalation: false

正如我们所看到的,本地设置在定义时将优先于全局设置。以下说明了此图表中 securityContexts 选项的优先级规则

uid: 40000
gid: 0

securityContexts:
  pod:
    runAsUser: 50000
    fsGroup: 0

workers:
  securityContexts:
    pod:
      runAsUser: 1001
      fsGroup: 0

这将生成以下 worker 部署

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

如果我们从上面的示例中删除 securityContextsworkers.securityContexts,则输出将如下所示

uid: 40000
gid: 0

securityContexts: {}

workers:
  securityContexts: {}

这将生成以下 worker 部署

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: {}

这将生成以下 worker 部署

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
      ...

内置 secret 和环境变量

默认情况下,Helm 图表使用 Kubernetes Secrets 来存储 Airflow 所需的 secret。这些 secret 的内容默认情况下会转换为 Airflow 读取的环境变量(一些环境变量有多种变体,以支持旧版本的 Airflow)。

默认情况下,secret 名称由部署 Helm 图表时使用的 Release Name 确定,但您也可以使用不同的 secret 来设置变量或完全禁用 secret 的使用,而依赖于环境变量(特别是当您想使用环境变量的 _CMD__SECRET 变体时)。

但是,Airflow 支持设置 secret 配置的其他变体 - 您可以指定一个系统命令来检索和自动轮换 secret(通过定义带有 _CMD 后缀的变量)或从 secret 后端检索变量(通过定义带有 _SECRET 后缀的变量)。

如果设置了 <VARIABLE_NAME>>,它将优先于 _CMD_SECRET 变体,因此,如果要设置其中一个 _CMD_SECRET 变体,则必须通过将 .Values.enableBuiltInSecretEnvVars.<VARIABLE_NAME> 设置为 false 来禁用从 Kubernetes secret 检索的内置变量。

例如,为了使用命令检索 DB 连接,您应该(在您的 values.yaml 文件中)指定

extraEnv:
  AIRFLOW_CONN_AIRFLOW_DB_CMD: "/usr/local/bin/retrieve_connection_url"
enableBuiltInSecretEnvVars:
  AIRFLOW_CONN_AIRFLOW_DB: false

以下是可以禁用并替换为 _CMD_SECRET 变体的 secret 的完整列表

如果未指定 secret 名称,则默认 secret 名称

使用不同的 Kubernetes Secret

Airflow 环境变量

<RELEASE_NAME>-airflow-metadata

.Values.data.metadataSecretName

AIRFLOW_CONN_AIRFLOW_DB
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN

<RELEASE_NAME>-fernet-key

.Values.fernetKeySecretName

AIRFLOW__CORE__FERNET_KEY

<RELEASE_NAME>-webserver-secret-key

.Values.webserverSecretKeySecretName

AIRFLOW__WEBSERVER__SECRET_KEY

<RELEASE_NAME>-airflow-result-backend

.Values.data.resultBackendSecretName

AIRFLOW__CELERY__CELERY_RESULT_BACKEND
AIRFLOW__CELERY__RESULT_BACKEND

<RELEASE_NAME>-airflow-brokerUrl

.Values.data.brokerUrlSecretName

AIRFLOW__CELERY__BROKER_URL

<RELEASE_NAME>-elasticsearch

.Values.elasticsearch.secretName

AIRFLOW__ELASTICSEARCH__HOST
AIRFLOW__ELASTICSEARCH__ELASTICSEARCH_HOST

还有一些 secret,其名称也由 release 名称确定,不需要禁用。这是因为它们不遵循 _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,而无需禁用基本变体。

如果未指定 secret 名称,则默认 secret 名称

使用不同的 Kubernetes Secret

Airflow 环境变量

<RELEASE_NAME>-redis-password

.Values.redis.passwordSecretName

REDIS_PASSWORD

<RELEASE_NAME>-pgbouncer-config

.Values.pgbouncer.configSecretName

<RELEASE_NAME>-pgbouncer-certificates

<RELEASE_NAME>-registry

.Values.registry.secretName

<RELEASE_NAME>-kerberos-keytab

<RELEASE_NAME>-flower

.Values.flower.secretName

AIRFLOW__CELERY__FLOWER_BASIC_AUTH

您可以在 设置配置选项 中阅读有关设置配置变量的高级方法的更多信息。

此条目是否有帮助?