次の方法で共有


Azure Kubernetes Service (AKS) 上で Airflow を構成して展開する

この記事では、Helm を使用して Azure Kubernetes Service (AKS) 上で Apache Airflow を構成して展開します。

ワークロード ID を構成する

  1. kubectl create namespace コマンドを使用して、Airflow クラスターの名前空間を作成します。

    kubectl create namespace ${AKS_AIRFLOW_NAMESPACE} --dry-run=client --output yaml | kubectl apply -f -
    

    出力例:

    namespace/airflow created
    
  2. 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 オペレーターです。

  1. 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
    
  2. 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
    

シークレットを作成する

  1. 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
    
  2. kubectl apply コマンドを使用して ExternalSecret リソースを作成します。これによってキー コンテナー内に保存されている Airflow シークレットを使用して airflow 名前空間内に Kubernetes Secret が作成されます。

    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
    
  3. 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
    
  4. 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 を展開する

  1. グラフの既定の展開構成を変更し、イメージのコンテナー レジストリを更新するように、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
    
  2. 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
    
  3. 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...
    
  4. 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
    
  5. 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 にアクセスする

  1. kubectl port-forward コマンドを使用して、ポート転送経由で Airflow UI に安全にアクセスします。

    kubectl port-forward svc/airflow-webserver 8080:8080 -n airflow
    
  2. ブラウザーを開き、localhost:8080 に移動して Airflow UI にアクセスします。

  3. Airflow Helm グラフのインストール時に指定された既定の Web サーバー URL とログイン資格情報を使用してログインします。

  4. Airflow UI を使用して、ワークフローを安全に探索して管理します。

Git と Airflow を統合する

Git と Apache Airflow の統合により、シームレスなバージョン管理とワークフロー定義の効率化された管理が可能になり、すべての DAG が整理され、かつ監査が容易になります。

  1. DAG 用の Git リポジトリを設定します。 すべての Airflow DAG 定義を格納するための専用 Git リポジトリを作成します。 このリポジトリは、ワークフローの一元化された信頼できる情報源として機能し、DAG の管理、追跡、共同作業を効率よく行うことができます。
  2. Git から DAG を同期するように Airflow を構成します。 Git リポジトリの URL と必要な認証資格情報を Airflow の構成ファイルで直接設定するか、Helm グラフ値を使用して設定することで、Git リポジトリから DAG を自動的にプルするように、Airflow の構成を更新します。 このセットアップにより、DAG の自動同期が可能になり、最新バージョンのワークフローで Airflow が常に最新の状態に保たれます。

この統合により、完全なバージョン管理を導入し、ロールバックを有効にし、運用グレードのセットアップでチームのコラボレーションをサポートすることで、開発と展開のワークフローが強化されます。

Airflow on Kubernetes を運用グレードにする

次のベスト プラクティスは、Apache Airflow on Kubernetes の展開を運用グレードにするのに役立ちます。

  • スケーラビリティ、セキュリティ、信頼性に重点を置いた堅牢なセットアップを確保します。
  • 専用の自動スケール ノードを使用し、KubernetesExecutorCeleryExecutorCeleryKubernetesExecutor などの回復性がある Executor を選択します。
  • MySQL や PostgreSQL などの、マネージド高可用性データベース バックエンドを使用します。
  • 包括的な監視と一元的なログ記録を確立して、パフォーマンスの分析情報を維持します。
  • ネットワーク ポリシー、SSL、ロールベースのアクセス制御 (RBAC) を使用して環境をセキュリティで保護し、高可用性を確保するために Airflow コンポーネント (スケジューラ、Web サーバー、ワーカー) を構成します。
  • スムーズな DAG 配置用に CI/CD パイプラインを実装し、ディザスター リカバリー用に定期的なバックアップを設定します。

次のステップ

Azure Kubernetes Service (AKS) にオープンソース ソフトウェアを展開する方法の詳細については、次の記事を参照してください。

共同作成者

Microsoft では、この記事を保持しています。 当初の寄稿者は次のとおりです。

  • Don High | プリンシパル カスタマー エンジニア
  • Satya Chandragiri | シニア デジタル クラウド ソリューション アーキテクト
  • Erin Schaffer |コンテンツ開発者 2