忘れる前にやっとこかなと思って、続きをやることにした。
やりたいこと
この2つでデプロイ時間にどれくらい差があるかなぁってことを見たい
- NLBあり + Service Connectなし
- NLBなし + Service Connectあり
今日のコードはここにある
環境を再構築
OpenTofuで作っておいたから楽ね。
❯ terragrunt apply -auto-approve ... Apply complete! Resources: 18 added, 0 changed, 0 destroyed. Outputs: nlb_dns_name = "<生成されたNLBのDNS名>"
はい。できた。
ECSのTask Execution Roleが必要だった
忘れてたので追加。こんな感じ。
❯ git diff diff --git a/infra/main.tf b/infra/main.tf index 12e0447..0cf5e24 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -161,6 +161,33 @@ resource "aws_service_discovery_http_namespace" "namespace" { name = "${local.main_name}-namespace" } +######################################### +# ECS Role +######################################### + +resource "aws_iam_role" "task_execution" { + name = "${local.main_name}-task-execution-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "" + Effect = "Allow" + Action = "sts:AssumeRole" + Principal = { + Service = "ecs-tasks.amazonaws.com" + } + } + ] + }) +} + +resource "aws_iam_role_policy_attachment" "task_execution" { + role = aws_iam_role.task_execution.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" +} + ######################################### # Output #########################################
ecspressoの設定ファイルを作成
ECSへのサービスとタスクのデプロイにはecspressoを使う。とても便利。
NLBあり + Service Connectなし
じゃ、設定ファイルを作っていく。前回AWSのWebコンソールから手で作ってからecspressoでダウンロードしてきた設定が手元にあったのでそれをごにょごにょして用意した。
まずはNLBにつなぐNginxから。作るファイルは3つ。全体設定、タスク設定、サービス設定。
全体設定 ecspresso.yml
tfstateから設定を読み込みたいので plugins
でtfstateの場所を指定。って、あぁ、カレントディレクトリに main.tf
を置いちゃったので、/./terraform.tfstate
になっちゃってるや。まいっか。tfstateから取ってこれるの便利。
region: ap-northeast-1 cluster: ecs20240121-ecs service: nginx-nlb service_definition: ecs-service-def.json task_definition: ecs-task-def.json timeout: "10m0s" plugins: - name: tfstate config: url: s3://ecs20240121/./terraform.tfstate
タスク設定 ecs-task-def.json
これは普通にコンテナの定義だけ。ECRにコンテナをプッシュして使おうかなぁ?って思ったけど、素のNginxコンテナでいっかと思ったのでそうした。
{ "containerDefinitions": [ { "cpu": 0, "essential": true, "image": "nginx", "name": "nginx-nlb", "portMappings": [ { "appProtocol": "http", "containerPort": 80, "hostPort": 80, "name": "nginx-nlb-80-tcp", "protocol": "tcp" } ], "healthCheck": { "command": [ "CMD-SHELL", "curl -f http://localhost/ || exit 1" ], "interval": 10, "timeout": 5, "retries": 3, "startPeriod": 10 } } ], "cpu": "1024", "executionRoleArn": "{{ tfstate `aws_iam_role.task_execution.arn` }}", "family": "nginx-nlb", "ipcMode": "", "memory": "3072", "networkMode": "awsvpc", "pidMode": "", "requiresCompatibilities": [ "FARGATE" ], "runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" } }
サービス設定 ecs-service-def.json
NLBのターゲットグループにつなぐ設定がはいったサービス。
{ "deploymentConfiguration": { "deploymentCircuitBreaker": { "enable": true, "rollback": true }, "maximumPercent": 200, "minimumHealthyPercent": 100 }, "deploymentController": { "type": "ECS" }, "desiredCount": 2, "enableECSManagedTags": true, "enableExecuteCommand": false, "healthCheckGracePeriodSeconds": 10, "launchType": "FARGATE", "loadBalancers": [ { "containerName": "nginx-nlb", "containerPort": 80, "targetGroupArn": "{{ tfstate `aws_lb_target_group.main.arn` }}" } ], "networkConfiguration": { "awsvpcConfiguration": { "assignPublicIp": "ENABLED", "securityGroups": [ "{{ tfstate `aws_security_group.app.id` }}" ], "subnets": [ "{{ tfstate `aws_subnet.main.id` }}" ] } }, "platformFamily": "Linux", "platformVersion": "LATEST", "propagateTags": "NONE", "schedulingStrategy": "REPLICA" }
NLBなし + Service Connectあり
つぎは、NLBへ接続せずにService Connectを使う設定。↑のと違うのは、細かい名前とかの違いは置いといて、サービス設定だけだな。NLBの設定がなくて、Service Connectの設定が入ってる。
{ "deploymentConfiguration": { "deploymentCircuitBreaker": { "enable": true, "rollback": true }, "maximumPercent": 200, "minimumHealthyPercent": 100 }, "deploymentController": { "type": "ECS" }, "desiredCount": 2, "enableECSManagedTags": true, "enableExecuteCommand": false, "launchType": "FARGATE", "networkConfiguration": { "awsvpcConfiguration": { "assignPublicIp": "ENABLED", "securityGroups": [ "{{ tfstate `aws_security_group.app.id` }}" ], "subnets": [ "{{ tfstate `aws_subnet.main.id` }}" ] } }, "platformFamily": "Linux", "platformVersion": "LATEST", "propagateTags": "NONE", "schedulingStrategy": "REPLICA", "serviceConnectConfiguration": { "enabled": true, "namespace": "ecs20240121-namespace", "services": [ { "clientAliases": [ { "dnsName": "nginx-sc-80-tcp.ecs20240121-namespace", "port": 80 } ], "discoveryName": "nginx-sc-80-tcp", "portName": "nginx-sc-80-tcp" } ] } }
これで、準備できた。
サービスをデプロイ
❯ cd nginx-nlb ❯ \time ecspresso deploy 2024/01/22 22:16:29 nginx-nlb/ecs20240121-ecs Service is stable now. Completed! 65.07 real 0.07 user 0.03 sys
❯ cd nginx-sc ❯ \time ecspresso deploy 2024/01/22 22:30:46 nginx-sc/ecs20240121-ecs Service is stable now. Completed! 98.09 real 0.10 user 0.05 sys
初回デプロイは既存コンテナの処理がないので速い。たまたまかもしれないけど、NLBの方がService Connectの方より速いのは面白いな。NLBへの接続はそんなに遅くなくて、Service Connect用の追加コンテナダウンロードとCloudMapへの登録の方が遅いってことなのかなぁ?
でも、知りたいのは再デプロイにかかる時間の違いなので、そこは今日は気にせずに、それぞれで再度デプロイを実行する。
NLBあり + Service Connectなし
2024/01/22 22:22:30 nginx-nlb/ecs20240121-ecs Service is stable now. Completed! 301.30 real 0.21 user 0.09 sys
2024/01/22 22:37:00 nginx-nlb/ecs20240121-ecs Service is stable now. Completed! 369.54 real 0.22 user 0.09 sys
2024/01/22 22:50:37 nginx-nlb/ecs20240121-ecs Service is stable now. Completed! 326.58 real 0.19 user 0.08 sys
2024/01/22 23:15:20 nginx-nlb/ecs20240121-ecs Service is stable now. Completed! 348.01 real 0.22 user 0.12 sys
2024/01/22 23:34:01 nginx-nlb/ecs20240121-ecs Service is stable now. Completed! 303.46 real 0.21 user 0.09 sys
NLBなし + Service Connectあり
2024/01/22 22:35:35 nginx-sc/ecs20240121-ecs Service is stable now. Completed! 286.73 real 0.18 user 0.08 sys
2024/01/22 22:48:33 nginx-sc/ecs20240121-ecs Service is stable now. Completed! 204.81 real 0.13 user 0.07 sys
2024/01/22 23:16:23 nginx-sc/ecs20240121-ecs Service is stable now. Completed! 225.20 real 0.15 user 0.07 sys
2024/01/22 23:21:03 nginx-sc/ecs20240121-ecs Service is stable now. Completed! 195.17 real 0.13 user 0.08 sys
2024/01/22 23:31:18 nginx-sc/ecs20240121-ecs Service is stable now. Completed! 248.07 real 0.20 user 0.09 sys
んー
単純に平均をとると
- NLBあり + Service Connectなし → 329.78
- NLBなし + Service Connectあり → 232.00
Service Connectの方が100sぐらい速いかなぁってところか。次回はもう少し詳しくどこに時間がかかっているのかを、ログから見てみようかな。
後片付け
ecspressoでサービスをdeleteして、terragruntでインフラをdestroyして今日の実験は終わり。IaCしておくと楽でいいね。
❯ cd ../nginx-nlb ❯ ecspresso delete --force --terminate ... 2024/01/22 23:34:09 (service nginx-nlb) has reached a steady state. 2024/01/22 23:37:35 nginx-nlb/ecs20240121-ecs Service is deleted ❯ cd ../nginx-sc ❯ ecspresso delete --force --terminate ... 2024/01/22 23:31:23 (service nginx-sc) has reached a steady state. 2024/01/22 23:37:47 nginx-sc/ecs20240121-ecs Service is deleted ❯ cd ../../infra ❯ terragrunt destroy -auto-approve ... aws_service_discovery_http_namespace.namespace: Destruction complete after 1m10s Destroy complete! Resources: 20 destroyed.
今日も面白かった。