この記事では、Helm を使用して Azure Kubernetes Service (AKS) 上で Apache Airflow を構成して展開します。
ワークロード ID を構成する
kubectl create namespace
コマンドを使用して、Airflow クラスターの名前空間を作成します。kubectl create namespace ${AKS_AIRFLOW_NAMESPACE} --dry-run=client --output yaml | kubectl apply -f -
出力例:
namespace/airflow created
kubectl apply
コマンドを使用してサービス アカウントを作成し、ワークロード ID を構成します。export TENANT_ID=$(az account show --query tenantId -o tsv) cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: annotations: azure.workload.identity/client-id: "${MY_IDENTITY_NAME_CLIENT_ID}" azure.workload.identity/tenant-id: "${TENANT_ID}" name: "${SERVICE_ACCOUNT_NAME}" namespace: "${AKS_AIRFLOW_NAMESPACE}" EOF
出力例:
serviceaccount/airflow created
External Secrets Operator をインストールする
このセクションでは、Helm を使用して External Secrets Operator をインストールします。 External Secrets Operator は、Azure Key Vault などの外部シークレット ストアに格納されている外部シークレットのライフサイクルを管理する Kubernetes オペレーターです。
helm repo add
コマンドとhelm repo update
コマンドを使用して、外部シークレット Helm リポジトリを追加し、リポジトリを更新します。helm repo add external-secrets https://charts.external-secrets.io helm repo update
出力例:
Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "external-secrets" chart repository
helm install
コマンドを使用して、External Secrets Operator をインストールします。helm install external-secrets \ external-secrets/external-secrets \ --namespace ${AKS_AIRFLOW_NAMESPACE} \ --create-namespace \ --set installCRDs=true \ --wait
出力例:
NAME: external-secrets LAST DEPLOYED: Thu Nov 7 11:16:07 2024 NAMESPACE: airflow STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: external-secrets has been deployed successfully in namespace airflow! In order to begin using ExternalSecrets, you will need to set up a SecretStore or ClusterSecretStore resource (for example, by creating a 'vault' SecretStore). More information on the different types of SecretStores and how to configure them can be found in our Github: https://github.com/external-secrets/external-secrets
シークレットを作成する
kubectl apply
コマンドを使用して、キー コンテナー内に保存されている Airflow パスワードにアクセスするためのSecretStore
リソースを作成します。kubectl apply -f - <<EOF apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: azure-store namespace: ${AKS_AIRFLOW_NAMESPACE} spec: provider: # provider type: azure keyvault azurekv: authType: WorkloadIdentity vaultUrl: "${KEYVAULTURL}" serviceAccountRef: name: ${SERVICE_ACCOUNT_NAME} EOF
出力例:
secretstore.external-secrets.io/azure-store created
kubectl apply
コマンドを使用してExternalSecret
リソースを作成します。これによってキー コンテナー内に保存されているAirflow
シークレットを使用してairflow
名前空間内に KubernetesSecret
が作成されます。kubectl apply -f - <<EOF apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: airflow-aks-azure-logs-secrets namespace: ${AKS_AIRFLOW_NAMESPACE} spec: refreshInterval: 1h secretStoreRef: kind: SecretStore name: azure-store target: name: ${AKS_AIRFLOW_LOGS_STORAGE_SECRET_NAME} creationPolicy: Owner data: # name of the SECRET in the Azure KV (no prefix is by default a SECRET) - secretKey: azurestorageaccountname remoteRef: key: AKS-AIRFLOW-LOGS-STORAGE-ACCOUNT-NAME - secretKey: azurestorageaccountkey remoteRef: key: AKS-AIRFLOW-LOGS-STORAGE-ACCOUNT-KEY EOF
出力例:
externalsecret.external-secrets.io/airflow-aks-azure-logs-secrets created
az identity federated-credential create
コマンドを使用して、フェデレーション資格情報を作成します。az identity federated-credential create \ --name external-secret-operator \ --identity-name ${MY_IDENTITY_NAME} \ --resource-group ${MY_RESOURCE_GROUP_NAME} \ --issuer ${OIDC_URL} \ --subject system:serviceaccount:${AKS_AIRFLOW_NAMESPACE}:${SERVICE_ACCOUNT_NAME} \ --output table
出力例:
Issuer Name ResourceGroup Subject ----------------------------------------------------------------------------------------------------------------------- ------------------------ ----------------------- ------------------------------------- https://$MY_LOCATION.oic.prod-aks.azure.com/c2c2c2c2-dddd-eeee-ffff-a3a3a3a3a3a3/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/ external-secret-operator $MY_RESOURCE_GROUP_NAME system:serviceaccount:airflow:airflow
az keyvault set-policy
コマンドを使用して、シークレットにアクセスするためのアクセス許可をユーザー割り当て ID に付与します。az keyvault set-policy --name $MY_KEYVAULT_NAME --object-id $MY_IDENTITY_NAME_PRINCIPAL_ID --secret-permissions get --output table
出力例:
Location Name ResourceGroup ------------- ---------------------- ----------------------- $MY_LOCATION $MY_KEYVAULT_NAME $MY_RESOURCE_GROUP_NAME
Apache Airflow ログの永続ボリュームを作成する
kubectl apply
コマンドを使用して永続ボリュームを作成します。kubectl apply -f - <<EOF apiVersion: v1 kind: PersistentVolume metadata: name: pv-airflow-logs labels: type: local spec: capacity: storage: 5Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain # If set as "Delete" container would be removed after pvc deletion storageClassName: azureblob-fuse-premium mountOptions: - -o allow_other - --file-cache-timeout-in-seconds=120 csi: driver: blob.csi.azure.com readOnly: false volumeHandle: airflow-logs-1 volumeAttributes: resourceGroup: ${MY_RESOURCE_GROUP_NAME} storageAccount: ${AKS_AIRFLOW_LOGS_STORAGE_ACCOUNT_NAME} containerName: ${AKS_AIRFLOW_LOGS_STORAGE_CONTAINER_NAME} nodeStageSecretRef: name: ${AKS_AIRFLOW_LOGS_STORAGE_SECRET_NAME} namespace: ${AKS_AIRFLOW_NAMESPACE} EOF
出力例:
persistentvolume/pv-airflow-logs created
Apache Airflow ログの永続ボリューム要求を作成する
kubectl apply
コマンドを使用して永続ボリューム要求を作成します。kubectl apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-airflow-logs namespace: ${AKS_AIRFLOW_NAMESPACE} spec: storageClassName: azureblob-fuse-premium accessModes: - ReadWriteMany resources: requests: storage: 5Gi volumeName: pv-airflow-logs EOF
出力例:
persistentvolumeclaim/pvc-airflow-logs created
Helm を使用して Apache Airflow を展開する
グラフの既定の展開構成を変更し、イメージのコンテナー レジストリを更新するように、
airflow_values.yaml
ファイルを構成します。cat <<EOF> airflow_values.yaml images: airflow: repository: $MY_ACR_REGISTRY.azurecr.io/airflow tag: 2.9.3 # Specifying digest takes precedence over tag. digest: ~ pullPolicy: IfNotPresent # To avoid images with user code, you can turn this to 'true' and # all the 'run-airflow-migrations' and 'wait-for-airflow-migrations' containers/jobs # will use the images from 'defaultAirflowRepository:defaultAirflowTag' values # to run and wait for DB migrations . useDefaultImageForMigration: false # timeout (in seconds) for airflow-migrations to complete migrationsWaitTimeout: 60 pod_template: # Note that `images.pod_template.repository` and `images.pod_template.tag` parameters # can be overridden in `config.kubernetes` section. So for these parameters to have effect # `config.kubernetes.worker_container_repository` and `config.kubernetes.worker_container_tag` # must be not set . repository: $MY_ACR_REGISTRY.azurecr.io/airflow tag: 2.9.3 pullPolicy: IfNotPresent flower: repository: $MY_ACR_REGISTRY.azurecr.io/airflow tag: 2.9.3 pullPolicy: IfNotPresent statsd: repository: $MY_ACR_REGISTRY.azurecr.io/statsd-exporter tag: v0.26.1 pullPolicy: IfNotPresent pgbouncer: repository: $MY_ACR_REGISTRY.azurecr.io/airflow tag: airflow-pgbouncer-2024.01.19-1.21.0 pullPolicy: IfNotPresent pgbouncerExporter: repository: $MY_ACR_REGISTRY.azurecr.io/airflow tag: airflow-pgbouncer-exporter-2024.06.18-0.17.0 pullPolicy: IfNotPresent gitSync: repository: $MY_ACR_REGISTRY.azurecr.io/git-sync tag: v4.1.0 pullPolicy: IfNotPresent # Airflow executor executor: "KubernetesExecutor" # Environment variables for all airflow containers env: - name: ENVIRONMENT value: dev extraEnv: | - name: AIRFLOW__CORE__DEFAULT_TIMEZONE value: 'America/New_York' # Configuration for postgresql subchart # Not recommended for production! Instead, spin up your own Postgresql server and use the `data` attribute in this # yaml file. postgresql: enabled: true # Enable pgbouncer. See https://airflow.apache.org/docs/helm-chart/stable/production-guide.html#pgbouncer pgbouncer: enabled: true dags: gitSync: enabled: true repo: https://github.com/donhighmsft/airflowexamples.git branch: main rev: HEAD depth: 1 maxFailures: 0 subPath: "dags" # sshKeySecret: airflow-git-ssh-secret # knownHosts: | # github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= logs: persistence: enabled: true existingClaim: pvc-airflow-logs storageClassName: azureblob-fuse-premium # We disable the log groomer sidecar because we use Azure Blob Storage for logs, with lifecyle policy set. triggerer: logGroomerSidecar: enabled: false scheduler: logGroomerSidecar: enabled: false workers: logGroomerSidecar: enabled: false EOF
helm repo add
コマンドとhelm repo update
コマンドを使用して、Apache Airflow Helm リポジトリを追加し、リポジトリを更新します。helm repo add apache-airflow https://airflow.apache.org helm repo update
出力例:
"apache-airflow" has been added to your repositories Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "apache-airflow" chart repository
helm search repo
コマンドを使用して、Helm リポジトリで Apache Airflow グラフを検索します。helm search repo airflow
出力例:
NAME CHART VERSION APP VERSION DESCRIPTION apache-airflow/airflow 1.15.0 2.9.3 The official Helm chart to deploy Apache Airflo...
helm install
コマンドを使用して、Apache Airflow グラフをインストールします。helm install airflow apache-airflow/airflow --namespace airflow --create-namespace -f airflow_values.yaml --debug
出力例:
NAME: airflow LAST DEPLOYED: Fri Nov 8 11:59:43 2024 NAMESPACE: airflow STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Thank you for installing Apache Airflow 2.9.3! Your release is named airflow. You can now access your dashboard(s) by executing the following command(s) and visiting the corresponding port at localhost in your browser: Airflow Webserver: kubectl port-forward svc/airflow-webserver 8080:8080 --namespace airflow Default Webserver (Airflow UI) Login credentials: username: admin password: admin Default Postgres connection credentials: username: postgres password: postgres port: 5432 You can get Fernet Key value by running the following: echo Fernet Key: $(kubectl get secret --namespace airflow airflow-fernet-key -o jsonpath="{.data.fernet-key}" | base64 --decode) ########################################################### # WARNING: You should set a static webserver secret key # ########################################################### You are using a dynamically generated webserver secret key, which can lead to unnecessary restarts of your Airflow components. Information on how to set a static webserver secret key can be found here: https://airflow.apache.org/docs/helm-chart/stable/production-guide.html#webserver-secret-key
kubectl get pods
コマンドを使用して、インストールを確認します。kubectl get pods -n airflow
出力例:
NAME READY STATUS RESTARTS AGE airflow-create-user-kklqf 1/1 Running 0 12s airflow-pgbouncer-d7bf9f649-25fnt 2/2 Running 0 61s airflow-postgresql-0 1/1 Running 0 61s airflow-run-airflow-migrations-zns2b 0/1 Completed 0 60s airflow-scheduler-5c45c6dbdd-7t6hv 1/2 Running 0 61s airflow-statsd-6df8564664-6rbw8 1/1 Running 0 61s airflow-triggerer-0 2/2 Running 0 61s airflow-webserver-7df76f944c-vcd5s 0/1 Running 0 61s external-secrets-748f44c8b8-w7qrk 1/1 Running 0 3h6m external-secrets-cert-controller-57b9f4cb7c-vl4m8 1/1 Running 0 3h6m external-secrets-webhook-5954b69786-69rlp 1/1 Running 0 3h6m
Airflow UI にアクセスする
kubectl port-forward
コマンドを使用して、ポート転送経由で Airflow UI に安全にアクセスします。kubectl port-forward svc/airflow-webserver 8080:8080 -n airflow
ブラウザーを開き、
localhost:8080
に移動して Airflow UI にアクセスします。Airflow Helm グラフのインストール時に指定された既定の Web サーバー URL とログイン資格情報を使用してログインします。
Airflow UI を使用して、ワークフローを安全に探索して管理します。
Git と Airflow を統合する
Git と Apache Airflow の統合により、シームレスなバージョン管理とワークフロー定義の効率化された管理が可能になり、すべての DAG が整理され、かつ監査が容易になります。
- DAG 用の Git リポジトリを設定します。 すべての Airflow DAG 定義を格納するための専用 Git リポジトリを作成します。 このリポジトリは、ワークフローの一元化された信頼できる情報源として機能し、DAG の管理、追跡、共同作業を効率よく行うことができます。
- Git から DAG を同期するように Airflow を構成します。 Git リポジトリの URL と必要な認証資格情報を Airflow の構成ファイルで直接設定するか、Helm グラフ値を使用して設定することで、Git リポジトリから DAG を自動的にプルするように、Airflow の構成を更新します。 このセットアップにより、DAG の自動同期が可能になり、最新バージョンのワークフローで Airflow が常に最新の状態に保たれます。
この統合により、完全なバージョン管理を導入し、ロールバックを有効にし、運用グレードのセットアップでチームのコラボレーションをサポートすることで、開発と展開のワークフローが強化されます。
Airflow on Kubernetes を運用グレードにする
次のベスト プラクティスは、Apache Airflow on Kubernetes の展開を運用グレードにするのに役立ちます。
- スケーラビリティ、セキュリティ、信頼性に重点を置いた堅牢なセットアップを確保します。
- 専用の自動スケール ノードを使用し、KubernetesExecutor、CeleryExecutor、CeleryKubernetesExecutor などの回復性がある Executor を選択します。
- MySQL や PostgreSQL などの、マネージド高可用性データベース バックエンドを使用します。
- 包括的な監視と一元的なログ記録を確立して、パフォーマンスの分析情報を維持します。
- ネットワーク ポリシー、SSL、ロールベースのアクセス制御 (RBAC) を使用して環境をセキュリティで保護し、高可用性を確保するために Airflow コンポーネント (スケジューラ、Web サーバー、ワーカー) を構成します。
- スムーズな DAG 配置用に CI/CD パイプラインを実装し、ディザスター リカバリー用に定期的なバックアップを設定します。
次のステップ
Azure Kubernetes Service (AKS) にオープンソース ソフトウェアを展開する方法の詳細については、次の記事を参照してください。
- MongoDB クラスターを Azure Kubernetes Service (AKS) にデプロイする
- Azure Kubernetes Service (AKS) に高可用性 PostgreSQL データベースをデプロイする
- Azure Kubernetes Service (AKS) に Valkey クラスターをデプロイする
共同作成者
Microsoft では、この記事を保持しています。 当初の寄稿者は次のとおりです。
- Don High | プリンシパル カスタマー エンジニア
- Satya Chandragiri | シニア デジタル クラウド ソリューション アーキテクト
- Erin Schaffer |コンテンツ開発者 2
Azure Kubernetes Service