この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データアナリティクス事業本部のnkhrです。タイトルの通りApache AirflowのQuickStartをやってみたブログです。
Quick Startでは、以下の2つの実行方法を試すことができます。
- Running Airflow locally
- Running Airflow in Docker
本ブログでは、1のQuickStartを手順に従ってEC2上で実行するCloudformationコードを作成し、動作を確認します。
1のQuick Startの構成では、DBとしてサーバ上のSqliteを利用し、タスク実行はSequential Executor(ユーザが1度に実行できるタスクが1つのみ)を利用しているため、Test利用を想定しています。Production環境で利用する場合は、Databaseを別に構成し(RDSなど)、ExecuterはLocal Executor(シングルマシンの場合)やCelery Executor、Kubernetes Executorの利用が推奨されています。Productionでのデプロイ方法は公式サイトをご確認ください。
Running Airflow locally (EC2上での起動)
EC2上でAirflowを起動するためのテンプレートを作りました。
「▶EC2の起動とAirflowのインストールCfnコード」の「▶」をクリックすると、コードを表示できます。AirflowをインストールするEC2は、Public Subnetに配置し、特定のIPアドレスから接続できるようにします。Airflowのインストールは、QuickStartではpipによるインストール方法が記載されているため、EC2にはpython(今回はVersion 3.8を利用)の設定も行います。
コードを実行する前提として下記のインフラリソースを作成済みとします。
- VPC 1つ(Cfn実行時にVPC IDを指定)
- Public Subnet 1つ(Cfn実行時にSubnet IDを指定)
- Internet Gateway
- Routing Table(Public Subnetのルーティングテーブル。0.0.0.0/0はInternet Gatewayにルーティング)
- Key Pair
EC2の起動とAirflowのインストールCfnコード
AWSTemplateFormatVersion: 2010-09-09
Parameters:
VpcId:
Type: String
Default: vpc-xxxx
SubnetId:
Type: String
Default: subnet-xxxx
AccessCidr:
Type: String
Default: x.x.x.x/32
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: test-key
AirflowPort:
Type: String
Default: 8080
AmazonLinuxImageId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Description: The AmazonLinux2 image id at least.
InstanceType:
Type: String
Default: t3.micro
AllowedValues:
- t3.nano
- t3.micro
- t3.small
TimeZone:
Type: String
Default: Asia/Tokyo
Locale:
Type: String
Default: ja_JP.utf8
AirflowVersion:
Type: String
Default: 2.2.3
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Airflow init parameters
Parameters:
- VpcId
- SubnetId
- AccessCidr
- KeyName
Resources:
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VpcId
GroupName: airflow-localaccess-sg
GroupDescription: !Sub localaccess-sg-${AWS::StackName}
Tags:
- Key: Name
Value: airflow-localaccess-sg
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref AirflowPort
ToPort: !Ref AirflowPort
CidrIp: !Ref AccessCidr
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref AccessCidr
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: 'sts:AssumeRole'
Effect: Allow
Principal:
Service: ec2.amazonaws.com
MaxSessionDuration: 36000
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Tags:
- Key: Name
Value: role-ec2-airflow
IAMInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref EC2Role
Path: "/"
AirflowServer:
Type: AWS::EC2::Instance
CreationPolicy:
ResourceSignal:
Timeout: PT20M
Properties:
IamInstanceProfile: !Ref IAMInstanceProfile
ImageId: !Ref AmazonLinuxImageId
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
InstanceInitiatedShutdownBehavior: stop
DisableApiTermination: false
Monitoring: False
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeType: gp3
DeleteOnTermination: true
Encrypted: true
VolumeSize: 10
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: 0
SubnetId: !Ref SubnetId
GroupSet:
- !Ref SecurityGroup
Tags:
- Key: Name
Value: airflow-server
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo "--------- Change Timezone/Locale ------------------------"
timedatectl set-timezone ${TimeZone}
localectl set-locale LANG=${Locale}
echo "--------- Install & Configure Python --------------------"
amazon-linux-extras enable python3.8
yum -y install python3.8
update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1
/usr/bin/pip3.8 install --upgrade pip
update-alternatives --install /usr/bin/pip pip /usr/local/bin/pip3 1
python -V
pip -V
echo "--------- Change yum configuration ----------------------"
sed -i -e '1s/python/python2/g' /bin/yum
sed -i -e '1s/python/python2/g' /usr/libexec/urlgrabber-ext-down
yum update -y
echo "--------- Update Sqlite for airflow requirement ---------"
yum install -y gcc-c++ python-devel python-setuptools
wget https://www.sqlite.org/2021/sqlite-autoconf-3370000.tar.gz
tar xzvf sqlite-autoconf-3370000.tar.gz
cd sqlite-autoconf-3370000
./configure --prefix=/opt/sqlite/sqlite3
make
make install
echo "--------- Install Airflow -------------------------------"
groupadd airflow
useradd airflow -g airflow
passwd -d airflow
su airflow
cd ~
echo 'export PATH="$PATH:/home/airflow/.local/bin"' >> ~/.bashrc
echo 'export AIRFLOW_HOME=~/airflow' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH="/opt/sqlite/sqlite3/lib"' >> ~/.bashrc
echo 'export LD_RUN_PATH="/opt/sqlite/sqlite3/lib"' >> ~/.bashrc
source ~/.bashrc
sqlite3 --version
python -c "import sqlite3; print(sqlite3.sqlite_version)"
mkdir ~/airflow
AIRFLOW_VERSION=${AirflowVersion}
PYTHON_VERSION="$(python --version | cut -d " " -f 2 | cut -d "." -f 1-2)"
CONSTRAINT_URL="https://raw.githubusercontent.com/apache/airflow/constraints-$AIRFLOW_VERSION/constraints-$PYTHON_VERSION.txt"
pip install "apache-airflow==$AIRFLOW_VERSION" --constraint "$CONSTRAINT_URL"
echo "<EXECUTE> /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AirflowServer --region ${AWS::Region}"
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AirflowServer --region ${AWS::Region}
Outputs:
AccessPublicIp:
Value: !GetAtt AirflowServer.PublicIp
AirflowURL:
Value: !Sub "http://${AirflowServer.PublicIp}:${AirflowPort}"
Cfnでは以下のパラメータを実行環境に合わせて修正します。EC2サーバの起動処理は「/var/log/」配下の「cfn-init-xxx.log」または「cloud-init-xxx.log」に出力されます。
- VpcId
- SubnetId
- AccessCidr :EC2に接続するInboundのIPアドレス範囲を指定します
- KeyName:EC2にアタッチするKey Pairの名前
Standaloneでインストールした場合、DatabaseとしてEC2サーバ上のSQLLightを使用します。SQLLiteの利用はテスト環境でのみ推奨されており、Production環境でAirflowを利用する場合は、Standaloneモードを利用しないことが推奨されています。
Amazon Linux上でのAirflow Standalone構築Tips
- pythonのパスをPython3系に変更した場合、yumはPython2系のみ対応しているためyumが利用できなくなります。今回は、yumがPython2を使うように設定ファイルのヘッダーを変更しています。その他の対応としては、python3コマンドのまま利用する(pythonとpython3を共存させる)方法があります。
- AmazonLinux(2021/12時点)で利用できるSqliteのバージョンは、Airflowで必要とされるバージョンを満たしていません。そのため、Sqliteをソースコードからインストール・設定しています。
Airflow standaloneの起動・接続
Standaloneコマンドを実行した場合は、Adminユーザが自動で作成されます。
- EC2サーバに接続し、airflowユーザに切り替える
sudo su - airflow
- Standaloneコマンド(All in One)を実行
$ airflow standalone
-
adminユーザが自動で作成され、パスワードが自動生成されるためメモする
-
CfnのOutputに表示される「AirflowURL」にアクセスする(http://x.x.x.x:8080)
-
上記3でメモしたユーザ名、パスワードでアクセスできることを確認する
standaloneではなく、個別に各コンポーネントを設定・実行する場合は、以下のコマンドを実行する(standaloneの場合は、以下の処理が実行される)
## db initは初回実行時のみ必要(standaloneコマンドにはdb initも含まれる)
$ airflow db init
$ airflow users create \
--username admin \
--firstname Peter \
--lastname Parker \
--role Admin \
--email admin[@](mailto:spiderman@superhero.org)example.com
## バックグラウンド実行を行う場合は-Dを付ける
$ airflow webserver --port 8080 -D
$ airflow scheduler -D
Airflowで利用するファイル
Airflowをインストールすると以下のファイルが作成されます。
- $AIRFLOW_HOME :デフォルトは「~/airflow」フォルダ
- $AIRFLOW_HOME/airflow.cfg:設定ファイル
- $AIRFLOW_HOME/airflow-webserver.pid:Webサーバ実行時のPIDファイル。systemdで起動した場合は「/run/airflow/webserver.pid」に作成される
Executorの変更方法
Airflowの設定ファイル「$AIRFLOW_HOME/airflow.cfg」の[core]セクションで利用するExecutorを指定する。Airflowが提供するExecutorタイプを設定するか、独自実装のカスタムExecutorを設定することもできる。
現在設定されているExecutorの確認には、以下のコマンドを実行する。
[airflow@ip-x-x-x-x ~]$ airflow config get-value core executor
SequentialExecutor
最後に
今回はApache Airflowの概要をつかむためにQuickStartを実行してみました。QuickStartの構成はProductionでは推奨されませんが、AirflowのPoCやテスト利用で活用する機会はあるかもしれません。AWSではManagedのAirflow(MWAA)が使えるためProductionでの利用を検討されてもよいかもしれません。
以上、nkhrでした。