Edited at

AWS ECS(Fargate)を本番運用する時に、気にしないといけないあれこれについてのまとめ

Fargateを本番運用するにあたって、気にしなければいけない下記の点についてまとめました。


  • デプロイ

  • ログ

  • 環境変数

  • バッチ処理(Cron)

  • 監視

CIは CircleCI を使いました。


Fargateとは

AWSが提供している、サーバの管理が不要なコンテナタイプです。

https://aws.amazon.com/jp/fargate/

そもそものFargateの概念とかはこちらを参考にしてみてください

AmazonECS / Fargate 本番運用のための構築とデプロイ方法まとめ


注意点

Fargateはsshでサーバにログインすることができません。

本番サーバでバグがおきたからといって、サーバに直接入ってファイルを修正、なんていうことできないです(やりませんけど... :rolling_eyes:

そのためサーバ上で何かしらのコマンドを実行する場合は ecs-cli compose run コマンドを実行します。

これを実行すると任意のコマンドを実行するための一時的なコンテナを立てて、その中でコマンドを実行させることができます。


デプロイ

AWS ECSをコマンドラインから操作できる、ecs-cli を使ってデプロイします。

AWSの公式です。

作成するコンテナの定義に、docker-compose.ymlをそのまま使うこともできるので、コンテナ定義の設定が一元管理できて嬉しい :smiley:

コマンドの例

ecs-cli compose -f docker-composer.yml -p <プロジェクト名> service up

これでECSのサービスに紐づいたコンテナを更新することができます

オプションについて詳しい説明はこちら

ecs-cliのドキュメント


ecs-params.yml

ecs-cli compose コマンドを実行するには、ecs-params.ymlを作成しておく必要があります。

デフォルトでカレントディレクトリの ecs-params.yml を読み込みます。

設定内容はこちらを参考にしてください

Amazon ECS パラメータの使用


DBマイグレーション

DBのマイグレーション処理は、デプロイ(ecs-cli compose)とは別にコマンドを実行します。

注意点で書いた通りFargate上でコマンドを実行するには、コマンド実行用のコンテナを立てて実行 することになります。

コマンド例

※php artisan migrate はLaravelのmigrationコマンドです

ecs-cli compose -f docker-compose.yml run <コンテナ名> "php artisan migrate"

これでコンテナ名に指定したコンテナに対して、コマンドを実行できます。


ログ

ログ収集はCloudWatchに流すのがとりあえず一番楽でした。

まず最初に各コンテナで出力するログを、標準出力にするように変更します。

Nginxの場合

error_log  /dev/stderr;   # /var/log/nginx/error.log;

access_log /dev/stdout; # /var/log/nginx/access.log;

CloudWatchにログを流すには、デプロイ時に使用する docker-composer.yml に設定を書きます。


docker-compose.yml


Services:
<コンテナ名>:
image: <ECRに登録してあるイメージURL>
logging:
driver: awslogs
options:
awslogs-region: ap-northeast-1
awslogs-group: <ロググループ名>
awslogs-stream-prefix: <ログにつけるプレフィックス>

こうするとCloudWatchにログが流れます。

ロググループはあらかじめ作成しておかないと、エラーになってしまったかもしれません。


環境変数

環境変数管理には Amazon System Manger(以下SSM)を使うのが良さそうです。

ecs-params.ymlの secrets 属性を使うことでSSMに設定をした値をコンテナで使う環境変数として読み込ませることができます。


ecs-params.yml

task_definition:

中略
services:
<コンテナ名>:
essential: true
secrets:
- value_from: APP_ENV
name: APP_ENV
- value_from: APP_DEBUG
name: APP_DEBUG
- value_from: APP_KEY
name: APP_KEY

value_from がSSMで設定をしている名前です

name がコンテナで実際に使う環境変数名になります。

SSMを使うことでKMS(AWS Key Management Service)を使って値を暗号化して保存することもできるので、秘匿情報の管理が楽になります。

SSMの使い方に関しては、こちらを参考にしてみてください

【祝!】FargateでもECSにごっつ簡単に環境変数に機密情報を渡せるようになりました!


バッチ処理(Cron)

Cronを使うようなバッチ処理は、ECSのコンソール画面から設定をすることができます。

スクリーンショット 2019-06-16 15.43.40.png

注意点としてはCronの時刻設定がUTCであることと、コマンドの上書きの設定がスペース区切りではなくカンマ区切りになるところです。

スクリーンショット 2019-06-16 15.45.24.png

スクリーンショット 2019-06-16 15.46.42.png


監視

サービス
理由

Mackerel
デプロイする度にコンテナが生成される関係上
ホストがどんどん追加されてしまい
大変なことになるので辞めた

datadog
デプロイ時にコンテナを生成するタイミングで
過去のメトリクス情報が見れなくなってしまい断念。
表示されているCPU使用率とかもなんかちゃんと
とれているのか怪しかった(設定の問題かも)

上記の2つしか試してませんが、どちらもちょっといまいちだったので、素直にCloudWatchで監視をするようにしています。


本番で運用してみた感想と課題

特にトラブルもなくいい感じです。

今の所Fargateならではの恩恵は受けていないのですが、そのうちFargateでよかったと思う場面があることでしょう。


課題: デプロイが遅い

正確にはALBのdraining処理がめちゃくちゃ遅いです。

新しくコンテナを作ってALBに紐づけるところまでは、普通なのですが紐づけたあと古いコンテナを切り離す、drainingが時間がかかってしまっています。時間にして8〜9分ほど... :sob:

ここの解決策は模索中です。

ecs-cli composeのタイムアウトがデフォルト5分なので、今はオプションでtimeout時間を伸ばしてどうにかしているところです。:thermometer_face:

ecs-cli compose -f docker-composer.yml -p <プロジェクト名> service up --timeout 10