0
Help us understand the problem. What are the problem?

posted at

AirflowのタスクログをS3に保存する方法

はじめに

Airflowのタスクログの保存先は、簡単に S3 や Google Cloud Storage のような外部ストレージに設定することができます。本番環境では、こうした外部ストレージを活用することで、ディスク容量不足による障害を防ぐ予防効果もあります。私はこの理由で、Airflow をクラウド上でデプロイする際に、タスクログを必ず外部ストレージに保存しています。

この記事では、公式 docker-compose.yaml で開発環境を立ち上げて、remote logging 機能で S3 にタスクログを保存するやり方を紹介します!

手順

環境構築

以下のように、公式 docker-compose.yaml をダウンロードして docker compose up で環境を立ち上げます。

mkdir -p ./dags ./logs ./plugins      # Linux のみ
echo -e "AIRFLOW_UID=$(id -u)" > .env # Linux のみ
wget https://airflow.apache.org/docs/apache-airflow/stable/docker-compose.yaml
docker compose up

環境が立ち上がったら http://localhost:8080 にあるウェブサーバーにでログインします。ユーザー名もパスワードも airflow です。問題なければ、以下のような一覧画面が表示されます。
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323532353537392f39373661336635322d303539662d653034662d313436352d3534323565353862323631612e706e67.png

Airflowの設定

Airflowのタスクログを S3 に保存するために、以下の設定を変更する必要があります。

設定項目 説明
remote_logging (True/False) タスクログを外部ストレージに保存するかしないか
remote_base_log_folder 保存先の S3 URL(s3://から始まる必要がある)
remote_log_conn_id 外部ストレージにアクセスするための Connection ID

Airflowの設定変更は、主に環境変数か airflow.cfg の修正で行います。docker-compose を使った開発環境では、環境変数を設定する方が楽です。本番環境では(秘密情報を除いて)変更を加えた airflow.cfg をコンテナイメージに同梱させたりします。(どっちを選ぶかぶっちゃけ好みです。)

今回は環境変数で対応するので docker-compose.yaml と同じディレクトリーに .env ファイルを作り、上記3つの設定項目を指定します。

touch .env
echo '.env' >> .gitignore
.env
AIRFLOW__LOGGING__REMOTE_LOGGING=True
AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER="s3://examplebucket/airflow_task_logs/"
AIRFLOW__LOGGING__REMOTE_LOG_CONN_ID=aws_default

.env ファイルに書いた環境変数は docker compose 実行時に参照されますが、コンテナの中に適用されないため、docker-compose.yaml 側の修正も必要です。

docker-compose.yaml
x-airflow-common:
  # ...
  environment:
    # ...
+   AIRFLOW__LOGGING__REMOTE_LOGGING: "${AIRFLOW__LOGGING__REMOTE_LOGGING:-}"
+   AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER: "${AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER:-}"
+   AIRFLOW__LOGGING__REMOTE_LOG_CONN_ID: "${AIRFLOW__LOGGING__REMOTE_LOG_CONN_ID:-}"

なぜ docker-compose.yaml に直接書かないの?
開発者によって変わる設定や、開発中にon/offを切り替えたい設定は、docker-compose.yaml の外から読み込む形で管理した方がいいです。.env ファイルは .gitignore に追加しているので、開発者AとBが違う設定を使っていてもコンフリクトが起きません。自分の環境だけ、一部の設定をコメントアウトするような対応も不要になります。

airflow.cfg を修正する場合はこうです(今回不要)

airflow.cfg
[logging]
remote_logging = True
remote_base_log_folder = "s3://examplebucket/airflow_task_logs/"
remote_log_conn_id = aws_default

AWSとの認証

S3にタスクログを送信/取得するためには、以下の権限をウェブサーバー、スケジューラー、ワーカーに割り当てます。

送受信に必要な権限(IAMポリシー)
airflow_s3_logging_policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::examplebucket"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject"
      ],
      "Resource": "arn:aws:s3:::examplebucket/*"
    }
  ]
}

ただ、今回は開発環境の話なので、IAMポリシーを使いません。代わりに、ローカル環境の AWS CLI の名前付きプロファイル個人の AWS ユーザーとして認証します

これを実現するためには、ホスト環境の $HOME/.aws ディレクトリーをコンテナの /home/airflow/.aws にマッピングする必要があるため、以下のようにバインドマウントで繋ぎます。そして、環境変数で空っぽな AWS Connection を定義することで、Airflowで使われるデフォルトの AWS Connectionをホスト環境の default AWS プロファイルにマッピングします。

docker-compose.yaml
x-airflow-common:
  # ...
  environment:
    # ...
+   AIRFLOW_CONN_AWS_DEFAULT: "aws://"
  volumes:
    # ...
+   - $HOME/.aws/:/home/airflow/.aws/

動作確認

docker-compose.yaml を変更したので docker compose downdocker compose up を順番に実行して環境を再起動します。

ウェブサーバーにログインして、任意の DAG を実行します。Graph View からいずれかのタスクのログ画面を開くと、最初の行に「Reading remote log from」のようなメッセージが出てくるはずです。今見ているログが S3 上のファイルから読み込まれているわけです!
ui-task-log.png
さらに AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER に指定した S3 URL をブラウザーで開くと、タスクログのフォルダー構成が確認できます。
s3-task-log.png

終わりに

この記事で、公式 docker-compose.yaml でサクッと開発環境を作り、タスクログの保存先を S3 に変えました。AWS の認証は、開発環境の AWS CLI の名前付きプロファイルで行い、IAMポリシーの作成は不要でした。(本番環境では上記のIAMポリシーを使ってください。)

Airflowにはまだまだ面白い機能がたくさんのあるので、もっと詳しく知りたい方、以下の記事をおすすめします!

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?