ecs-cli を利用したAPI サーバーのデプロイ

Adventarを支える技術 Advent Calendar 2019 の12日目です。

今日は API サーバーのデプロイについて書きます。

API サーバーは、4日目の記事 でも書いたように、gRPC のサーバーをたてています。この API サーバーは、Amazon ECS, Fargate を利用してホストしています。

ECS のデプロイツールは色々とあって、仕事で使っているのは hako というツールです。今回は他のツールも使ってみたいというのもあって、AWS 公式が提供している ecs-cli を使ってみました。

https://github.com/aws/amazon-ecs-cli

ecs-cli の他の良い点としては、docker-compose.yml を設定ファイルとして使えるというところじゃないかなと思っています。docker-compose.yml であれば、ツール独自のシンタックスを覚えなくても良いのがいいですね。

ただ、当然のようにdocker-compose.yml だけでは足りなくて、ECS 独自の設定も別途必要になります。それはecs-params.ymlという設定ファルに書くのですが、設定ファイルが分散してしまうのが微妙という見方もありそうです。

Adventar ではそれぞれ以下に設定があります。

ecs-cli のコマンド

compose create service

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cmd-ecs-cli-compose-service-create.html

サービスを作ります。実行するのは初回だけです。ALB と target group は別途 terraform で作っています。

$ ecs-cli compose --project-name adventar --cluster adventar --region ap-northeast-1 service create --create-log-groups --launch-type FARGATE --container-name envoy --container-port 80 --target-group-arn arn:aws:elasticloadbalancing:ap-northeast-1:287379415997:targetgroup/adventar-api/xxx

compose service up

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cmd-ecs-cli-compose-service-up.html

これが実質デプロイコマンドです。

docker-compose.yml と ecs-params.yml の設定を見てタスク定義を作り、新しいタスクをデプロイしてくれます。

$ ecs-cli compose --project-name adventar --cluster adventar service up

なお、ドキュメントには

a combination of the create and start commands

とあるので、start でもいいのかと思いきや、start だと新しいタスクのデプロイは行わません。また、

This command updates the desired count of the service to 1.

とあるので、desired count が 2 以上だった場合は 1 になるのかと思いきや、既存の desired count をそのまま引き継いでくれます。ドキュメントを読んだだけだとこのあたりの挙動はよくわかりませんでした。

compose service scale

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cmd-ecs-cli-compose-service-scale.html

タスク数(desired count)を変更します。

$ ecs-cli compose --project-name adventar --cluster adventar service scale 2

docker push

デプロイする際は、ECS のデプロイの前に docker push する必要があるので、git の HEAD の revision で tag を打って dockdr push してからデプロイしています。こんな感じです。

TAG=$(git rev-parse HEAD)

cd $ROOT_DIR/grpc-server
docker build -t hokaccha/adventar-grpc-server:${TAG} .
docker push hokaccha/adventar-grpc-server:${TAG}

cd $ROOT_DIR/envoy
docker build -t hokaccha/adventar-envoy:${TAG} .
docker push hokaccha/adventar-envoy:${TAG}

今回はコードもオープンですし、ECR は利用せずに Docker Hub の public なところに push しています。

実際のデプロイスクリプトはこんな感じです。

https://github.com/adventar/adventar/blob/fa0714e49ea3aa60888532b60b924af0c12bbc80/api-server/bin/deploy

まとめ

API サーバーを ECS でデプロイする話しを書きました。明日は Lambda と CloudWatch Events を使った定期ジョブについて書きます。