Slide 1

Slide 1 text

スケジュール指定のFargate Spot と友達になれた話 2024/3/7 JAWS-UG コンテナ⽀部 #26 新春⼤LT祭り 🍞 荒⽊ 🍞

Slide 2

Slide 2 text

0 1 2 3 4 5 AWS好き Terraform好き 優しさ 勇気 トーク

Slide 3

Slide 3 text

なぜFargate Spotと 友達になろうとしているか

Slide 4

Slide 4 text

• • • • アジアパシフィック (東京) Fargate Fargate Spot 割引率 1 時間あたりの vCPU 単位 0.05056 USD 0.015168 USD 70% 1 時間あたりの GB 単位 0.00553 USD 0.001659 USD 70%

Slide 5

Slide 5 text

• • 項⽬ 説明 capacity_providers FARGATE or FARGATE_SPOT を指定 base 最⼩実⾏タスク数 weight タスク数⽐率

Slide 6

Slide 6 text

• • • • • • •

Slide 7

Slide 7 text

• • • • •

Slide 8

Slide 8 text

• 本番環境で常時Fargate Spotを使いたい • ただリスクがあるので、アクセスが減る夜間帯であれば安⼼して使えるかも しれない • そのためスケジュール指定のFargate Spotの適⽤ができるか検証したい • •

Slide 9

Slide 9 text

• resource "aws_ecs_service" "service" { name = "hoge" cluster = aws_ecs_cluster.cluster.id desired_count = 2 - launch_type = "FARGATE" platform_version = "1.4.0" enable_execute_command = true + capacity_provider_strategy { + capacity_provider = "FARGATE" + base = 1 + weight = 0 + } + + capacity_provider_strategy { + capacity_provider = "FARGATE_SPOT" + base = 0 + weight = 1 + } + ・・・略 Terraform will perform the following actions: # aws_ecs_service.service must be replaced -/+ resource "aws_ecs_service" "service" { 〜 略 ~ launch_type = "FARGATE" -> (known after apply) + capacity_provider_strategy { # forces replacement + base = 0 + capacity_provider = "FARGATE_SPOT" + weight = 1 } + capacity_provider_strategy { # forces replacement + base = 1 + capacity_provider = "FARGATE" + weight = 0 } 〜 略 } terrafor plan

Slide 10

Slide 10 text

• aws ecs update-service ¥ --capacity-provider-strategy capacityProvider=FARGATE,base=1,weight=0 capacityProvider=FARGATE_SPOT,base=0,weight=1 ¥ --cluster example-ecs-cluster ¥ --service example-ecs-service ¥ --force-new-deployment resource "aws_ecs_service" "service" { name = "hoge" cluster = aws_ecs_cluster.cluster.id desired_count = 2 - launch_type = "FARGATE" platform_version = "1.4.0" enable_execute_command = true + capacity_provider_strategy { + capacity_provider = "FARGATE" + base = 1 + weight = 0 + } + + capacity_provider_strategy { + capacity_provider = "FARGATE_SPOT" + base = 0 + weight = 1 + } + ・・・略 } No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. terrafor plan

Slide 11

Slide 11 text

というのを サンドボックス環境で検証できたので いざ開発環境で実⾏︕

Slide 12

Slide 12 text

❯ aws ecs update-service ¥ --capacity-provider-strategy capacityProvider=FARGATE,base=1,weight=0 capacityProvider=FARGATE_SPOT,base=0,weight=1 ¥ --cluster xxx-clusster ¥ --service xxx-service ¥ --force-new-deployment

Slide 13

Slide 13 text

❯ aws ecs update-service ¥ --capacity-provider-strategy capacityProvider=FARGATE,base=1,weight=0 capacityProvider=FARGATE_SPOT,base=0,weight=1 ¥ --cluster xxx-clusster ¥ --service xxx-service ¥ --force-new-deployment An error occurred (InvalidParameterException) when calling the UpdateService operation: Cannot force a new deployment on services with a CODE_DEPLOY deployment controller. Use AWS CodeDeploy to trigger a new deployment. ︕︕︖︖

Slide 14

Slide 14 text

• • • • • •

Slide 15

Slide 15 text

❯ aws deploy create-deployment ¥ --application-name xxx ¥ --deployment-group-name yyy ¥ --revision '{"revisionType": "AppSpecContent", "appSpecContent": {"content": "{¥"version¥": 0.0, ¥"Resources¥": [{¥"TargetService¥": {¥"Type¥": ¥"AWS::ECS::Service¥", ¥"Properties¥": {¥"TaskDefinition¥": ¥"arn:aws:ecs:ap-northeast-1:123456789012:task-definition/xxx¥", ¥"LoadBalancerInfo¥": {¥"ContainerName¥": ¥"example-api¥", ¥"ContainerPort¥": 8080},¥"CapacityProviderStrategy¥": [{¥"Base¥":0,¥"CapacityProvider¥":¥"FARGATE_SPOT¥",¥"Weight¥":1},{¥"Base¥":0,¥"CapacityProvider¥":¥"FARGATE¥",¥"Weight¥":0}]}}}]} "}}'

Slide 16

Slide 16 text

❯ aws deploy create-deployment ¥ --application-name xxx ¥ --deployment-group-name yyy ¥ --revision '{"revisionType": "AppSpecContent", "appSpecContent": {"content": "{¥"version¥": 0.0, ¥"Resources¥": [{¥"TargetService¥": {¥"Type¥": ¥"AWS::ECS::Service¥", ¥"Properties¥": {¥"TaskDefinition¥": ¥"arn:aws:ecs:ap-northeast-1:123456789012:task-definition/xxx¥", ¥"LoadBalancerInfo¥": {¥"ContainerName¥": ¥"example-api¥", ¥"ContainerPort¥": 8080},¥"CapacityProviderStrategy¥": [{¥"Base¥":0,¥"CapacityProvider¥":¥"FARGATE_SPOT¥",¥"Weight¥":1},{¥"Base¥":0,¥"CapacityProvider¥":¥"FARGATE¥",¥"Weight¥":0}]}}}]} "}}’ { "deploymentId": "d-WA876T2Y1" } Success!

Slide 17

Slide 17 text

resource "aws_ecs_service" "service" { name = "hoge" cluster = aws_ecs_cluster.cluster.id desired_count = 2 - launch_type = "FARGATE" platform_version = "1.4.0" enable_execute_command = true + capacity_provider_strategy { + capacity_provider = "FARGATE" + base = 1 + weight = 0 + } + + capacity_provider_strategy { + capacity_provider = "FARGATE_SPOT" + base = 0 + weight = 1 + } + ・・・略 } No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. terrafor plan •

Slide 18

Slide 18 text

ただこれを数⼗個あるAPI x 複数環境 などに適⽤していくのはしんどいぞ︖

Slide 19

Slide 19 text

そうだ、CodeDeployを使っている アプリケーションリポジトリには AppSpec.yamlがあるぞ︕

Slide 20

Slide 20 text

version: 0.0 Resources: - TargetService: Type: AWS::ECS::Service Properties: TaskDefinition: '' PlatformVersion: '1.4.0' LoadBalancerInfo: ContainerName: 'xxxxxx' ContainerPort: yyyy version: 0.0 Resources: - TargetService: Type: AWS::ECS::Service Properties: TaskDefinition: '' PlatformVersion: '14.0' LoadBalancerInfo: ContainerName: 'xxxxxx' ContainerPort: yyyy CapacityProviderStrategy: - Base: 1 CapacityProvider: 'FARGATE' Weight: 0 - Base: 0 CapacityProvider: 'FARGATE_SPOT' Weight: 1

Slide 21

Slide 21 text

• • AWS Fargate Spot タスクで Spot 終了通知を処理するにはどうすればよいですか? • > Fargate Spot の中断によりタスクが停⽌した場合、stopCode は SpotInterruption として⾔ 及されることに注意してください。 • • •

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

• • • 項⽬ 結果 Fargate Spotの稼働時間割合 99.992% 落ちた回数 106回 MTBF(平均故障間隔) 約9⽇ MTTR(平均復旧時間) 1分

Slide 24

Slide 24 text

• • まさにこれから本番環境でやろうとしています To Be Continued・・・︕

Slide 25

Slide 25 text

Slide 26

Slide 26 text

• 本番環境で常時Fargate Spotを使いたい • • • 開発環境で落ちる頻度を確認しておきたい • 既存のFargateをFargate Spotにして確認する

Slide 27

Slide 27 text

• • • • • •

Slide 28

Slide 28 text

• • • •

Slide 29

Slide 29 text

Terraform will perform the following actions: # aws_ecs_service.service must be replaced -/+ resource "aws_ecs_service" "service" { 〜 略 ~ launch_type = "FARGATE" -> (known after apply) + capacity_provider_strategy { # forces replacement + base = 0 + capacity_provider = "FARGATE_SPOT" + weight = 1 } + capacity_provider_strategy { # forces replacement + base = 1 + capacity_provider = "FARGATE" + weight = 0 } 〜 略 } Plan: 1 to add, 0 to change, 1 to destroy. •

Slide 30

Slide 30 text

• • resource "aws_ecs_service" "this" { ・・・略 lifecycle { ignore_changes = [ launch_type, capacity_provider_strategy ] } } • No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Slide 31

Slide 31 text

という検証ができ 友達になれました

Slide 32

Slide 32 text

• • 構成概要 • EventBridge スケジューラーからECSサービスを更新する • 200以上のAWSサービスをターゲットにできるので夢が広がる • スケジュール指定はcron式とrate式で設定できる • 夜間だけ適⽤したいので、開始と終了のスケジュール設定する

Slide 33

Slide 33 text

• このときもECSサービスのデプロイメントコントローラが「ECS」で検証していた そのため実際には「CODE_DEPLOY」を考慮しなければならない

Slide 34

Slide 34 text

• • デプロイメントコントローラーの「ECS」との違い • EventBridge スケジューラーからCreateDeploymentを⽤いてECSサービ スを更新する

Slide 35

Slide 35 text

ペイロードはAppSpec.yamlと 同じような設定となる

Slide 36

Slide 36 text

こちらも本番環境でやろうとしています To Be Continued・・・︕

Slide 37

Slide 37 text

もはやFargate Spotとは友達以上の関係

Slide 38

Slide 38 text

• Fargate Spotは使える場⾯があるなら積極的に使っていきたい • (作戦 ガンガンいこうぜ︕) • Fargate Spotのリスクを許容しづらいときは夜間などに絞って利⽤ できないか探る • (作戦 いのちをだいじに︕) • ECSサービスのデプロイメントコントローラによって Fargate Spotの適⽤⽅法が異なるので注意 • ECS / CODE_DEPLOY

Slide 39

Slide 39 text

Fargate Spotと パートナーになろうとしている話 ご清聴ありがとうございました