生產指南

以下是在生產環境中使用此 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://。您需要建立使用正確 scheme 的單獨 secret。對於 Airflow 版本大於等於 2.4,可以省略 result backend secret,因為 Airflow 預設將使用 sql_alchemy_conn(在 metadataSecret 中指定)並帶有 db+ scheme 字首。

PgBouncer

如果您使用 PostgreSQL 作為資料庫,您很可能也想啟用 PgBouncer。Airflow 由於其分散式特性可以開啟大量資料庫連線,而使用連線池可以顯著減少資料庫上的開放連線數。

資料庫憑據儲存在 Values 檔案中

pgbouncer:
  enabled: true

資料庫憑據儲存在 Kubernetes Secret 中

在這種情況下,預設連線字串將不起作用,您需要相應地修改

kubectl create secret generic mydatabase --from-literal=connection=postgresql://user:pass@pgbouncer_svc_name.deployment_namespace:6543/airflow-metadata

在此配置中,PgBouncer 要正常工作還需要兩個額外的 Kubernetes Secret

airflow-pgbouncer-stats

kubectl create secret generic airflow-pgbouncer-stats --from-literal=connection=postgresql://user:pass@127.0.0.1:6543/pgbouncer?sslmode=disable

airflow-pgbouncer-config

apiVersion: v1
kind: Secret
metadata:
  name: airflow-pgbouncer-config
data:
  pgbouncer.ini: dmFsdWUtMg0KDQo=
  users.txt: dmFsdWUtMg0KDQo=

pgbouncer.ini 等於此文字的 base64 編碼版本

[databases]
airflow-metadata = host={external_database_host} dbname={external_database_dbname} port=5432 pool_size=10

[pgbouncer]
pool_mode = transaction
listen_port = 6543
listen_addr = *
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/users.txt
stats_users = postgres
ignore_startup_parameters = extra_float_digits
max_client_conn = 100
verbose = 0
log_disconnections = 0
log_connections = 0

server_tls_sslmode = prefer
server_tls_ciphers = normal

users.txt 等於此文字的 base64 編碼版本

"{ external_database_host }" "{ external_database_pass }"

values.yaml 應如下所示

pgbouncer:
  enabled: true
  configSecretName: airflow-pgbouncer-config
  metricsExporterSidecar:
    statsSecretName: airflow-pgbouncer-stats

根據您的 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 生成的 token 有一個較短的過期時間 - 請確保執行 airflow 元件的所有機器上的時間都已同步(例如使用 ntpd),否則在訪問日誌時可能會出現“forbidden”錯誤。

驅逐配置

Kubernetes Cluster Autoscaler 一起執行 Airflow 時,配置 pod 是否可以安全驅逐非常重要。此設定可以在 Airflow chart 的不同級別進行配置

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

workers.safeToEvict 預設為 false,並且在使用 KubernetesExecutor 時,workers.safeToEvict 不應設定為 true,否則 worker 可能會在完成前被移除。

擴充套件和定製 Airflow 映象

Apache Airflow 社群釋出 Docker 映象,這些映象 是 Apache Airflow 的 參考映象。然而,Airflow 擁有超過 60 個社群管理的 provider(可透過 extra 安裝),其中一些預設安裝的 extras/providers 並非每個人都使用,有時需要其他 extras/providers,有時(實際上非常頻繁)您需要新增自己的自定義依賴、包,甚至自定義 provider,或者新增部署所需的自定義工具和二進位制檔案。

在 Kubernetes 和 Docker 術語中,這意味著您需要一個包含您特定需求的另一個映象。這就是為什麼您應該學習如何構建自己的 Docker(或更準確地說 容器)映象。

您可能想要使用自定義映象的典型場景

  • 新增 apt

  • 新增 PyPI

  • 新增部署所需的二進位制資源

  • 新增部署所需的自定義工具

請參閱 構建映象,瞭解如何擴充套件和定製 Airflow 映象的更多詳細資訊。

管理 DAG 檔案

請參閱 管理 DAG 檔案

knownHosts

如果您正在使用 dags.gitSync.sshKeySecret,您還應該設定 dags.gitSync.knownHosts。這裡我們將演示 GitHub 的過程,但對於任何 provider 都可以進行相同的操作

獲取 GitHub 的公鑰

ssh-keyscan -t rsa github.com > github_public_key

接下來,列印公鑰的 fingerprint

ssh-keygen -lf github_public_key

將該輸出與 GitHub 的 SSH key fingerprint 進行比較。

它們匹配,對吧?好的。現在,將公鑰新增到您的 values 檔案中。它看起來像這樣

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

外部 Scheduler

要使用外部 Scheduler 例項

scheduler:
  enabled: false

確保您的外部 webserver/scheduler 連線到同一個 redis 主機。這將確保 scheduler 知道 helm-chart 中部署的 worker。

訪問 Airflow UI

您如何訪問 Airflow UI 將取決於您的環境;但是,chart 支援各種選項

外部 Webserver

要使用外部 Webserver

webserver:
  enabled: false

確保您的外部 webserver/scheduler 連線到同一個 redis 主機。這將確保 scheduler 知道 helm-chart 中部署的 worker。

Ingress

您可以建立和配置 Ingress 物件。請參閱 Ingress chart 引數。有關 Ingress 的更多資訊,請參閱 Kubernetes Ingress 文件

LoadBalancer Service

您可以將 webserver 的 Service 型別更改為 LoadBalancer,並設定任何必要的 annotation

webserver:
  service:
    type: LoadBalancer

有關 LoadBalancer Service 的更多資訊,請參閱 Kubernetes LoadBalancer Service 文件

日誌記錄

根據您選擇的 executor,任務日誌可能無法直接工作。所有日誌記錄選項都可以在此處找到:管理日誌

指標

chart 支援將指標傳送到現有的 StatsD 例項或提供 Prometheus endpoint。

Prometheus

指標 endpoint 可在此處訪問: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: ...

IPv6 StatsD

要使用帶有 IPv6 地址的 StatsD 例項。示例:在啟用 IPv6 的 Kubernetes 中使用

statsd:
  enabled: true
config:
  metrics:  # or 'scheduler' for Airflow 1
    statsd_on: 'True'
    statsd_host: ...
    statsd_ipv6: 'True'
    statsd_port: ...
    statsd_prefix: airflow

Datadog

如果您在環境中使用 Datadog agent,這將使 Airflow 能夠將指標匯出到 Datadog agent。

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 後端。

預設情況下,chart 將部署 Redis。但是,您可以使用任何支援的 Celery 後端代替

redis:
  enabled: false
data:
  brokerUrl: redis://redis-user:password@redis-host:6379/0

有關設定 Celery broker 的更多資訊,請參閱詳細的 Celery 相關主題文件

Security Context Constraints

Security Context Constraint (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

在此 chart 中,SCC 透過 RoleBindings 繫結到 Pod,這意味著選項 rbac.create 也必須設定為 true,以完全啟用 SCC 的使用。

有關 SCC 以及透過此構造可以實現的功能的更多資訊,請參閱 管理 security context constraints

Security Context

在 Kubernetes 中,securityContext 可用於定義使用者 ID、組 ID 和能力,例如以特權模式執行容器。

將應用程式部署到 Kubernetes 時,建議賦予容器最小許可權,以減少訪問並保護容器執行的主機。

在 Airflow Helm chart 中,securityContext 可以透過多種方式進行配置

與配置全域性 securityContexts 的方式相同,也可以透過設定特定工作負載的本地 securityContexts 如下所示配置不同的值

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

在上面的示例中,worker Pod 的 securityContexts 將設定為 runAsUser: 5000fsGroup: 0。容器 Pod 將設定為 allowPrivilegeEscalation: false

可以看到,本地設定優先於全域性設定(如果已定義)。下面解釋了此 chart 中 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 Chart 使用 Kubernetes Secret 來儲存 Airflow 所需的 secret。這些 secret 的內容預設會轉換為 Airflow 讀取的環境變數(一些環境變數有多種變體以支援舊版本的 Airflow)。

預設情況下,secret 名稱是根據部署 Helm Chart 時使用的 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 中檢索的內建變數。

例如,為了使用命令檢索資料庫連線,您應該(在您的 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-broker-url

.Values.data.brokerUrlSecretName

AIRFLOW__CELERY__BROKER_URL

<RELEASE_NAME>-elasticsearch

.Values.elasticsearch.secretName

AIRFLOW__ELASTICSEARCH__HOST
AIRFLOW__ELASTICSEARCH__ELASTICSEARCH_HOST

還有一些 secret,它們的名稱也是根據 release name 確定的,但不需要停用。這是因為它們要麼不遵循 _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

您可以在 設定配置選項 中閱讀有關設定配置變數的高階方法的更多資訊。

此條目有幫助嗎?