生產指南¶
以下是在生產環境中使用此 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 後端¶
如果您使用 CeleryExecutor 或 CeleryKubernetesExecutor,您可以使用自己的 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 可以透過多種方式進行配置
uid (配置全域性 uid 或 RunAsUser)
gid (配置全域性 gid 或 fsGroup)
securityContexts (與
uid相同,但允許設定所有 Pod securityContext 選項 和 Container securityContext 選項)
與配置全域性 securityContexts 的方式相同,也可以透過設定特定工作負載的本地 securityContexts 如下所示配置不同的值
workers:
securityContexts:
pod:
runAsUser: 5000
fsGroup: 0
containers:
allowPrivilegeEscalation: false
在上面的示例中,worker Pod 的 securityContexts 將設定為 runAsUser: 5000 和 fsGroup: 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
如果我們從上面的示例中同時刪除 securityContexts 和 workers.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 環境變數 |
|---|---|---|
|
|
AIRFLOW_CONN_AIRFLOW_DBAIRFLOW__DATABASE__SQL_ALCHEMY_CONN |
|
|
|
|
|
|
|
|
AIRFLOW__CELERY__CELERY_RESULT_BACKENDAIRFLOW__CELERY__RESULT_BACKEND |
|
|
|
|
|
AIRFLOW__ELASTICSEARCH__HOSTAIRFLOW__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 環境變數 |
|---|---|---|
|
|
|
|
|
|
|
||
|
|
|
|
||
|
|
|
您可以在 設定配置選項 中閱讀有關設定配置變數的高階方法的更多資訊。