ECS FargateでSeleniumを実行する

はじめに

こんにちは、GMOソリューションパートナーのTKです。

当社には、AWSの学習用のアカウントがあります。
今回はそれを活用して、ローカルのdocker環境上で動かしていたSeleniumを
ECSのFargateで動作させてみることにしました。

構成

root
 ├ python
 │ └ Dockerfile
 │ └ requirements.txt
 │ └ script.py
 ├ selenium
 │ └ Dockerfile
 └ docker-compose.yml
 

コード

pythonディレクトリ配下
seleniumディレクトリ配下
rootディレクトリ直下

処理の内容としては、当社のテックブログのトップページにアクセスして
タイトルの要素を取得し、標準出力に出力します。

AWSコンソール

ECRのリポジトリを作成

以下の二つのリポジトリを作成します。
xxxxxxxxxxxx.dkr.ecr.region.amazonaws.com/techblog/python
xxxxxxxxxxxx.dkr.ecr.region.amazonaws.com/techblog/selenium



「プッシュコマンドを表示」を押し、手順に従い、ECRのリポジトリへイメージをプッシュします。
※AWS CLI が必要なので、以下のリンクを参考にインストールして、AWS CLI を利用してください。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

ECSのクラスターを作成する

任意の名前でクラスター名を作成します。
ここではtech_blogとします。

ECSのタスク定義を作成する

新しいタスク定義の作成をクリックし、必要な情報を入力します。

  • タスク定義の設定
    タスク定義ファミリーに任意の名前を入力

  • インフラストラクチャの要件の起動タイプ
    Fargateを選択

  • コンテナ – 1
    名前:python
    イメージURI:xxxxxxxxxxxx.dkr.ecr.region.amazonaws.com/techblog/python:latest
    ポートマッピング:不要なので削除
    必須コンテナ:はい
    環境変数 – オプション
    キー:SELENIUM_URL、値:http://localhost:4444/wd/hub
    ※ ECSの同一タスク内のコンテナはlocalhostで通信ができます。
    ▼ Docker 設定 – オプション
    コマンド:python,-u,script.py
    作業ディレクトリ:/app

  • コンテナ – 2
    名前:selenium
    イメージURI:xxxxxxxxxxxx.dkr.ecr.region.amazonaws.com/techblog/selenium:latest
    必須コンテナ:はい
    ポートマッピング
    コンテナポート:4444
    プロトコル:TCP
    ポート名:selenium-4444-tcp
    アプリケーションプロトコルHTTP
    ▼ HealthCheck – オプション
    コマンド:CMD-SHELL, curl -f http://localhost:4444 || exit 1
    間隔、タイムアウト、開始期間、再試行 に任意の値を入力

  • 再びコンテナ – 1
    ▼ スタートアップの依存関係の順序 – オプション
    コンテナ名:selenium
    条件:Healthy

JSONを使用した新しいタスク定義の作成も可能です。

タスクの実行

新しいタスクの実行をクリックします。

必要な項目を入力します。そのほかはデフォルト設定でOKです。

  • 環境
    ▼ コンピューティング設定 ((アドバンスト))
    コンピューティングオプション:起動タイプ
    起動タイプ:FARGATE
    プラットフォームバージョン:LATEST

  • デプロイ設定
    アプリケーションタイプ:タスク
    タスク定義
    ファミリー:作成したタスク
    リビジョン:実行するタスクのバージョン
    必要なタスク:1

  • ネットワーキング
    VPC、サブネット、セキュリティグループの作成は省略します。
    インターネットにアクセスできればOKです。

タスクが作成されたので、タスクをクリックします。

起動するのを少し待ち、ログのタブを開くと、無事実行されていることが確認できました。 

気づき、ポイントなど

個人的なポイントや気がついたことについてです。

コンテナ間の通信方法を悩んでいましたが、以下のように対応することで解決できました。
ローカル環境のコンテナ上では、docker-compose.ymlのenvironmentで環境変数を
「http://selenium:4444/wd/hub」 とコンテナ名を指定するのに対して
ECSのタスクでは、タスク定義で環境変数を
「http://localhost:4444/wd/hub」 とlocalhostで指定します。

また、python側の処理が終了した後、seleniumコンテナが起動し続ける必要がないため、タスクを終了させる方法を検討しました。
コンテナ – 1 pythonコンテナの必須コンテナをはいにすると
処理が停止した際に、タスク自体が停止されます。
一方、必須コンテナをいいえにすると
seleniumコンテナは起動しつづけます。
処理が終了した際にタスクを停止したい場合は、必須コンテナをはいにするとよいかもしれません。
その他、AWS SDKのboto3でタスクを停止する処理を入れる方法も考えました。

実行中のタスクのログタブに標準出力が処理完了まで表示されないことに気が付きました。
リアルタイムに表示させるには、Pythonの標準出力のバッファリングを明示的にオフにする必要があります。
python -u script.py のように -u オプションを使用することで
リアルタイムでログを出力させることができます。

おわりに

ローカルのdocker環境上で動かしていたSeleniumを、ECSのFargateでも動作させることができました。
これを機にサーバーレス化を進めたいと思っています。