Fargateを本番運用するにあたって、気にしなければいけない下記の点についてまとめました。
- デプロイ
- ログ
- 環境変数
- バッチ処理(Cron)
- 監視
CIは CircleCI
を使いました。
Fargateとは
AWSが提供している、サーバの管理が不要なコンテナタイプです。
https://aws.amazon.com/jp/fargate/
そもそものFargateの概念とかはこちらを参考にしてみてください
AmazonECS / Fargate 本番運用のための構築とデプロイ方法まとめ
注意点
Fargateはsshでサーバにログインすることができません。
本番サーバでバグがおきたからといって、サーバに直接入ってファイルを修正、なんていうことできないです(やりませんけど... )
そのためサーバ上で何かしらのコマンドを実行する場合は ecs-cli compose run
コマンドを実行します。
これを実行すると任意のコマンドを実行するための一時的なコンテナを立てて、その中でコマンドを実行させることができます。
デプロイ
AWS ECSをコマンドラインから操作できる、ecs-cli
を使ってデプロイします。
AWSの公式です。
作成するコンテナの定義に、docker-compose.ymlをそのまま使うこともできるので、コンテナ定義の設定が一元管理できて嬉しい
コマンドの例
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 に設定を書きます。
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に設定をした値をコンテナで使う環境変数として読み込ませることができます。
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のコンソール画面から設定をすることができます。
注意点としてはCronの時刻設定がUTCであることと、コマンドの上書きの設定がスペース区切りではなくカンマ区切りになるところです。
監視
サービス | 理由 |
---|---|
Mackerel | デプロイする度にコンテナが生成される関係上 ホストがどんどん追加されてしまい 大変なことになるので辞めた |
datadog | デプロイ時にコンテナを生成するタイミングで 過去のメトリクス情報が見れなくなってしまい断念。 表示されているCPU使用率とかもなんかちゃんと とれているのか怪しかった(設定の問題かも) |
上記の2つしか試してませんが、どちらもちょっといまいちだったので、素直にCloudWatchで監視をするようにしています。
本番で運用してみた感想と課題
特にトラブルもなくいい感じです。
今の所Fargateならではの恩恵は受けていないのですが、そのうちFargateでよかったと思う場面があることでしょう。
課題: デプロイが遅い
※解決しました。
これが問題だったようです。
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-target-groups.html#deregistration-delay
ターゲットグループの登録解除の遅延がデフォルト300秒になっているので、これを短くしておけば、drainingのスピードが早くなります。
正確にはALBのdraining処理がめちゃくちゃ遅いです。
新しくコンテナを作ってALBに紐づけるところまでは、普通なのですが紐づけたあと古いコンテナを切り離す、drainingが時間がかかってしまっています。時間にして8〜9分ほど...
ここの解決策は模索中です。
ecs-cli composeのタイムアウトがデフォルト5分なので、今はオプションでtimeout時間を伸ばしてどうにかしているところです。
ecs-cli compose -f docker-composer.yml -p <プロジェクト名> service up --timeout 10