バッチ処理をECSに移行した話(GitHubActionsもあるよ)その1
はじめに
こんにちは、ハンズラボの清水です。東急ハンズのECサイトを担当しています。今回はEC2上で動いている外部ECモール連携バッチをAmazon ECS ScheduleTask
に移行しました。そして、GitHubにpushした際にECR
にイメージをpushできるようなGitHubActions
も作成しました。今回はECSのScheduleTask機能を使用してバッチ処理を作成していきます。
※外部ECモールとはyahooや楽天といったショッピングサイトのことです。
既存バッチ処理の内容
既存のバッチ処理ではEC2インスタンス上にバッチサーバーを用意、cronにスケジュールを登録してバッチを叩いています。
処理の内容としては、Aurora
に追加された注文変更情報を取得して、注文情報商品の数量変更、注文キャンセル等を行っています。
今回は注文情報変更処理をECS
に移行しました。
ECSへ移行
移行の理由
移行の理由としては以下の点が挙げられます。
- AWSのサポートを受けられる
- 各バージョンアップに対応できる
- EC2を冗長化したい
- dockerを使用するのでローカルでの開発が楽になる
注文情報変更の処理のみをdockerのイメージとして切り出し,ECR(Amazon Elastic Container Registry)
にpushします。
Amazon ECS ScheduleTask
でスケジュールを指定して、処理を開始します。
ECRの作成
ECR(Amazon Elastic Container Registry)
の作成を行い、ローカル開発環境にあるdockerイメージをECRへpushします。はじめにECRでリポジトリを作成しましょう。作成したらリポジトリ名をコピーしておくと後々楽です。
dockerイメージの作成&ECRへpush
ECR(Amazon Elastic Container Registry)
へpushする用のdockerイメージを作成して,pushしましょう。以下のbashスクリプトで行いました。
#!/usr/bin/env bash
# DCTを有効化
DOCKER_CONTENT_TRUST=1
# ecrにログインする
aws ecr get-login --no-include-email --region ap-northeast-1
# 先ほど作成したリポジトリ名を使用する
docker build -t hogehoge .
docker tag hogehoge:latest <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge:latest
docker push <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge:latest
のちのAmazon ECS ScheduleTask
で説明しますが作成したDockerfile
のENTRYPOINT
を"/bin/ash"
のようにしておくとコンテナの挙動を変更できます。(今回はpython:3.7.3-alpine3.8を使用したのでashです)
クラスターを作成
ECSからクラスターを作成します。クラスターのテンプレートですが、今回は出て行くIPアドレスを固定したいためFargate
を使用せずにEC2
を利用しました。 クラスターの設定は各自お任せします。
後に気づいたのですが、NATGatewayにElasticIPをつけることでFargateでもIPアドレスを固定できます。
タスクを定義
ECSからタスクを定義します。起動タイプはEC2を選択。
コンテナ定義でコンテナの追加します。イメージには先ほど作成したECRのURLのパスを貼り付ければOK。
環境のコマンドに今回はテストとしてecho test
を実行します。
ログ設定のAuto-configure CloudWatch Logs
にチェックを入れておくとCloudWatch Logs
にログを吐いてくれるのでチェックを入れました。
タスクを実行してみる
作成したクラスター→タスク→新しいタスクの実行からタスクを実行する。 先ほど作成したクラスターとタスク定義を選択をして実行しましょう。 実行ログはCLoudWatchLogsに吐かれるので確認しましょう。
成功です。
スケジュールを設定する
作成したクラスター→タスクのスケジューリングから作成します。
スケジュールタイプはCron式でも設定できます。タスク定義を先ほど定義したタスクを設定して作成完了です。
CloudWatchLogsでログを確認したところスケジュール通りに動いてくれています。
ハマったところ
タスクが実行されない(CloudWatchメトリクスにFailedInvocationsが出ている)問題がありました。調査の結果以下の二つが問題の原因でした。
- インターネットに接続出来ていない(ElasticIPを付与したら解決)
- コンテナインスタンス IAM ロールに権限が付与されていない(IAMロールからECSFullAccessつけることで解決)
終わりに
今回はECSのECS ScheduleTask
を利用してバッチ処理を移行しました。次回はGitHubActionsを利用したECRへのpushを紹介できればと思います。