LoginSignup
22
17

More than 3 years have passed since last update.

AWS Fargate の「タスクのスケジューリング」でバッチ用コンテナを定時実行する

Last updated at Posted at 2019-06-24

概要

  • AWS Fargate には、スケジュールルールに従ってタスクを実行できる機能がある。
  • スケジュールルールは次の2通りある。どちらもスケジュールルールに従って毎回新しいコンテナが起動して終了する。
  • 固定された間隔で実行
  • Cron式
  • この「タスクのスケジューリング」機能を使って、これまで EC2 上の crond で起動して実行していたバッチ処理を、コンテナ化して AWS Fargate に移行してみる。

今回 Fargate に移行するバッチの概要

  • Elasticsearch の インデックスを1日1回削除するバッチ。

  • サーバのアクセスログを Fluentd で Elasticsearch に送ってKibanaで可視化している。1日分のアクセスログを1つのインデックスに格納していて、30日前のインデックスファイルを削除するバッチを1日1回実行している。

  • バッチは bash スクリプトでこんな感じで書いている。

#!/bin/bash
ESDOMAIN="hogehoge.ap-northeast-1.es.amazonaws.com"
INDEXNAME=(
    "fastly-accesslog-"
    "varnish-accesslog-"
    "nginx-accesslog-"
)
DATA=`date -d '30 days ago' +"%Y-%m-%d"`
for INDEX in ${INDEXNAME[@]}; do
  echo "Delete: ${INDEX}${DATA}"
  curl -s -X DELETE https://${ESDOMAIN}/${INDEX}${DATA}
  echo -e "\n"
done
echo "Execution Result"
curl -s -X GET ${ESDOMAIN}/_aliases?pretty | grep -v '}' | sort

バッチ処理を行うコンテナの Dockerfile 作成

FROM alpine:latest
RUN apk --no-cache add tzdata && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && apk del tzdata
RUN apk --no-cache add coreutils bash bash-completion curl
COPY del-index.sh /del-index.sh
RUN chmod u+x /del-index.sh
CMD /bin/bash /del-index.sh

Dockerfileの簡単な説明

軽量な Alpine Linux を使う

  • いろいろ削がれて軽量になっている。
  • 今回のシェルスクリプトを実行するために必要なものを追加する。

Alpine Linux の timezone を JST に設定

  • デフォルトは UTC になっているので、JST に設定する。
  • Dockerfile 追加設定

RUN apk --no-cache add tzdata && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && apk del tzdata

dataコマンド

  • Alpine Linux のdataコマンドは、「date -d '30 days ago'」 を解釈してくれない。
    なので、GNU coreutils の date をインストールする。
  • Dockerfile 追加設定

RUN apk --no-cache add coreutils

bash

  • Alpine Linux のデフォルトのシェルは sh なので、配列が使えない。bashで書いた次の部分でエラーになってしまう。

INDEXNAME=(
    "fastly-accesslog-"
    "Varnish-accesslog-"
    "nginx-accesslog-"
)
  • シェルスクリプトを sh 用に書き直すのは面倒なので、bashを入れてしまう。
  • Dockerfile 追加設定

RUN apk --no-cache add bash bash-completion

curl

  • 今回のバッチは、curl で Elasticsearch の API を叩くので、curl をインストールする。
  • Dockerfile 追加設定

RUN apk --no-cache add curl

bashスクリプト本体

  • 今回は del-index.sh という名前で、上記のシェルスクリプトのファイルを作成する。これを Dockerfile と同じディレクトリに置く。
  • docker build 時に del-index.sh ファイルを docker イメージの / にコピーして、実行権限を付与する。
  • コンテナ起動時に、この del-index.sh を実行する。
  • Dockerfile 追加設定

COPY del-index.sh /del-index.sh
RUN chmod u+x /del-index.sh
CMD /bin/bash /del-index.sh

DockerイメージをECRへプッシュして、Fargete の設定を行う

Fargate タスクのスケジューリング 設定

Fargate タスクのスケジューリングの概要

タスクのスケジューリング設定例

  • Amazon ECS クラスター設定画面 ⇒ タスクのスケジューリング ⇒ 作成
    01.png

  • スケジュールルール設定
    今回は、毎日午前 6:00 (JST) に実行したいので、Cron 式は cron(0 21 * * ? *)

04.png

  • ターゲット設定
    起動タイプで「FARGATE」を選択する。
    タスク定義で上記で作成したものを選択する。
    03.png

  • VPC とセキュリティグループ
    AWS Fargate で実行したコンテナに固定のグローバルIPアドレスを割り当てる を参考

  • 作成
    以上で、毎日午前 6:00 (JST) に Elasticsearch のインデックスを削除するコンテナが起動して、処理を終えたらコンテナが消滅する。
    実行ログは CloudWatch ログに送られる。

「タスクのスケジューリング」利用時の注意点

参照:Amazon ECS の「タスクのスケジューリング」利用時の注意点

おまけ

Slack にも実行結果を送りたい場合は、del-index.sh に Slack へ送る設定を追加する

#!/bin/bash
ESDOMAIN="hogehoge.ap-northeast-1.es.amazonaws.com"
INDEXNAME=(
    "fastly-accesslog-"
    "Varnish-accesslog-"
    "nginx-accesslog-"
)
DATA=`date -d '30 days ago' +"%Y-%m-%d"`

exec 3>&1
exec > /exec.log
echo "Elasticsearch delete index"
for INDEX in ${INDEXNAME[@]}; do
    echo "Delete Index: ${INDEX}${DATA}"
    curl -s -X DELETE https://${ESDOMAIN}/${INDEX}${DATA}
    echo -e "\n"
done
echo "curl -X GET https://${ESDOMAIN}/_aliases?pretty"
curl -s -X GET ${ESDOMAIN}/_aliases?pretty | grep -v '}' | sort
exec 1>&3

sed -i -e 's/\"//g' /exec.log

channel="hoge"
username="Container"
text="Elasticsearch delete index"
color="gray"
message=`cat /exec.log`
attachments="
{
    \"color\":\"${color}\",
    \"text\": \"${message}\"
}"
emoji=':envelope:'
url="https://hooks.slack.com/services/hoge/hogehoge"
payload="payload={\"channel\": \"${channel}\", \"username\": \"${username}\", \"text\": \"${text}\", \"attachments\":[${attachments}] , \"icon_emoji\": \"${emoji}\"}"
curl -s -m 5 -d "${payload}" $url

exit
  • 標準出力をファイルへ出力する設定

exec 3>&1
exec > /exec.log
〜
exec 1>&3
  • 実行結果ファイルからダブルクォーテーションを除外(Slack送信時に invalid_payload エラーとなるため)

sed -i -e 's/\"//g' /exec.log

22
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
17