生產指南¶
以下是在生產環境中使用此 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 文件。
指標¶
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¶
如果您使用 CeleryExecutor
或 CeleryKubernetesExecutor
,您可以自備 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
可以透過幾種方式設定
uid (設定全域 uid 或 RunAsUser)
gid (設定全域 gid 或 fsGroup)
securityContexts (與
uid
相同,但允許設定所有 Pod securityContext 選項 和 Container securityContext 選項)
與可以設定全域 securityContexts 相同的方式,也可以透過設定其本地 securityContexts
為特定 workloads 設定不同的值,如下所示
workers:
securityContexts:
pod:
runAsUser: 5000
fsGroup: 0
containers:
allowPrivilegeEscalation: false
在上面的範例中,workers Pod securityContexts
將設定為 runAsUser: 5000
和 fsGroup: 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
如果我們從上面的範例中移除 securityContexts
和 workers.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 環境變數 |
---|---|---|
|
|
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 |
還有許多 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 環境變數 |
---|---|---|
|
|
|
|
|
|
|
||
|
|
|
|
||
|
|
|
您可以在 設定配置選項 中閱讀更多關於設定配置變數的進階方法。