生產指南

以下是在生產環境中使用此 Helm chart 時需要考量的事項。

資料庫

建議為 Airflow 元數據倉儲設定外部資料庫。預設的 Helm chart 部署一個在容器中運行的 Postgres 資料庫。對於生產用途,應使用在專用機器上運行的資料庫,或利用雲端供應商的資料庫服務 (例如 AWS RDS),因為內嵌的 Postgres 缺乏生產資料庫所需的穩定性、監控和持久性功能。它僅用於簡化在「獨立」版本中測試 Helm Chart,但使用它時可能會遇到資料遺失。支援的資料庫和版本可在 設定資料庫後端 中找到。

注意

當使用 helm chart 時,您不需要使用 airflow db migrate 初始化資料庫,如 設定資料庫後端 中所述。

首先停用 Postgres,這樣 chart 將不會部署自己的 Postgres 容器

postgresql:
  enabled: false

要向 Airflow 提供資料庫憑證,您有 2 個選項 - 在您的 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 將預設使用帶有 db+ scheme 前綴的 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 用於簽署 session cookies 並執行其他與安全相關的功能!

首先,產生一個強密鑰

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」錯誤。

驅逐設定

當 Airflow 與 Kubernetes Cluster Autoscaler 一起運行時,設定 pod 是否可以安全地被驅逐非常重要。此設定可以在 Airflow chart 中的不同層級進行設定

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

當使用 KubernetesExecutor 時,應將 workers.safeToEvict 設定為 false,以避免 worker 在完成之前被移除。

擴展和自訂 Airflow 映像檔

Apache Airflow 社群發布 Docker 映像檔,這些是 Apache Airflow 的 參考 映像檔。但是,Airflow 有超過 60 個社群管理的 providers (可透過 extras 安裝),並且某些預設安裝的 extras/providers 並非所有人都在使用,有時需要其他 extras/providers,有時 (實際上非常頻繁) 您需要新增自己的自訂 dependencies、packages 甚至自訂 providers,或新增部署中需要的自訂工具和 binaries。

在 Kubernetes 和 Docker 術語中,這表示您需要另一個具有特定需求的映像檔。這就是為什麼您應該學習如何建立自己的 Docker (或更準確地說 Container) 映像檔。

您可能想要使用自訂映像檔的典型情境

  • 新增 apt packages

  • 新增 PyPI packages

  • 新增部署所需的 binary 資源

  • 新增部署中需要的自訂工具

請參閱 建立映像檔 以取得有關如何擴展和自訂 Airflow 映像檔的更多詳細資訊。

管理 DAG 檔案

請參閱 管理 DAG 檔案

knownHosts

如果您正在使用 dags.gitSync.sshKeySecret,您也應該設定 dags.gitSync.knownHosts。在這裡,我們將展示 GitHub 的流程,但同樣的方法也適用於任何供應商

抓取 GitHub 的 public key

ssh-keyscan -t rsa github.com > github_public_key

接下來,列印 public key 的 fingerprint

ssh-keygen -lf github_public_key

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

它們匹配,對吧?很好。現在,將 public key 新增到您的 values。它看起來會像這樣

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

外部排程器

要使用外部排程器實例

scheduler:
  enabled: false

確保您的外部 webserver/scheduler 連接到相同的 redis host。這將確保排程器知道在 helm-chart 中部署的 worker。

存取 Airflow UI

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

外部 Webserver

要使用外部 Webserver

webserver:
  enabled: false

確保您的外部 webserver/scheduler 連接到相同的 redis host。這將確保排程器知道在 helm-chart 中部署的 worker。

Ingress

您可以建立和設定 Ingress 物件。請參閱 Ingress chart 參數。<關於 Ingress 的更多資訊,請參閱 Kubernetes Ingress 文件

LoadBalancer Service

您可以將 webserver 的 Service type 更改為 LoadBalancer,並設定任何必要的 annotations

webserver:
  service:
    type: LoadBalancer

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

日誌

根據您選擇的 executor,task logs 可能無法直接運作。所有日誌選項都可以在 管理日誌 中找到。

指標

chart 可以支援將指標發送到現有的 StatsD 實例,或提供 Prometheus endpoint。

Prometheus

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

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 Backend

如果您使用 CeleryExecutorCeleryKubernetesExecutor,您可以自備 Celery backend。

預設情況下,chart 將部署 Redis。但是,您可以改用任何支援的 Celery backend

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

關於設定 Celery broker 的更多資訊,請參閱詳盡的 Celery 相關文件

安全內容約束 (Security Context Constraints)

安全 內容 約束 (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)

在 Kubernetes 中,securityContext 可以用於定義使用者 ID、群組 ID 和 capabilities,例如以 privileged 模式運行容器。

當將應用程式部署到 Kubernetes 時,建議給予容器最小的權限,以減少存取並保護容器運行的 host。

在 Airflow Helm chart 中,securityContext 可以透過幾種方式設定

與可以設定全域 securityContexts 相同的方式,也可以透過設定其本地 securityContexts 為特定 workloads 設定不同的值,如下所示

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

在上面的範例中,workers Pod securityContexts 將設定為 runAsUser: 5000fsGroup: 0。containers pod 將設定為 allowPrivilegeEscalation: false

正如您所看到的,當定義本地設定時,本地設定將優先於全域設定。以下說明此 chart 中 securityContexts 選項的優先順序規則

uid: 40000
gid: 0

securityContexts:
  pod:
    runAsUser: 50000
    fsGroup: 0

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

這將產生以下 worker deployment

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 deployment

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 deployment

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 Chart 預設使用 Kubernetes Secrets 來儲存 Airflow 需要的密鑰。這些 secrets 的內容預設會轉換為 Airflow 讀取的環境變數 (某些環境變數有多種變體,以支援舊版本的 Airflow)。

預設情況下,secret 名稱是根據部署 Helm Chart 時使用的 Release Name 確定的,但您也可以使用不同的 secret 來設定變數,或完全停用使用 secrets 並依賴環境變數 (特別是當您想要使用 _CMD__SECRET 變體的環境變數時)。

但是,Airflow 支援其他設定密鑰配置的變體 - 您可以指定一個系統命令來檢索和自動輪換密鑰 (透過定義帶有 _CMD 後綴的變數) 或從 secret backed 檢索變數 (透過定義帶有 _SECRET 後綴的變數)。

如果設定了 <VARIABLE_NAME>>,它將優先於 _CMD_SECRET 變體,因此如果您想要設定 _CMD_SECRET 變體之一,您必須停用從 Kubernetes secrets 檢索的內建變數,方法是將 .Values.enableBuiltInSecretEnvVars.<VARIABLE_NAME> 設定為 false。

例如,為了使用命令檢索 DB 連線,您應該 (在您的 values.yaml 檔案中) 指定

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

以下是可以停用並由 _CMD_SECRET 變體替換的完整 secrets 列表

如果未指定 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

還有許多 secrets,其名稱也由 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

您可以在 設定配置選項 中閱讀更多關於設定配置變數的進階方法。

這個條目有幫助嗎?