はじめに
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
です。問題なければ、以下のような一覧画面が表示されます。
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
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
側の修正も必要です。
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
を修正する場合はこうです(今回不要)
[logging]
remote_logging = True
remote_base_log_folder = "s3://examplebucket/airflow_task_logs/"
remote_log_conn_id = aws_default
AWSとの認証
S3にタスクログを送信/取得するためには、以下の権限をウェブサーバー、スケジューラー、ワーカーに割り当てます。
送受信に必要な権限(IAMポリシー)
{
"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 プロファイルにマッピングします。
x-airflow-common:
# ...
environment:
# ...
+ AIRFLOW_CONN_AWS_DEFAULT: "aws://"
volumes:
# ...
+ - $HOME/.aws/:/home/airflow/.aws/
動作確認
docker-compose.yaml
を変更したので docker compose down
と docker compose up
を順番に実行して環境を再起動します。
ウェブサーバーにログインして、任意の DAG を実行します。Graph View からいずれかのタスクのログ画面を開くと、最初の行に「Reading remote log from」のようなメッセージが出てくるはずです。今見ているログが S3 上のファイルから読み込まれているわけです!
さらに AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER
に指定した S3 URL をブラウザーで開くと、タスクログのフォルダー構成が確認できます。
終わりに
この記事で、公式 docker-compose.yaml でサクッと開発環境を作り、タスクログの保存先を S3 に変えました。AWS の認証は、開発環境の AWS CLI の名前付きプロファイルで行い、IAMポリシーの作成は不要でした。(本番環境では上記のIAMポリシーを使ってください。)
Airflowにはまだまだ面白い機能がたくさんのあるので、もっと詳しく知りたい方、以下の記事をおすすめします!