Talked at AWS Spot x Containers Seminar #SpotLovesContainers
© 2020, Amazon Web Services, Inc. or its Affiliates.Tori Hara / toriclsSr. Product Developer AdvocateContainers Product, Amazon Web ServicesJun. 10, 2020Practical Guide for Amazon EC2 Spot x Containers特性と構築パターンに学ぶ低コスト & ⾼可⽤アーキテクチャ\2020!/
View Slide
© 2020, Amazon Web Services, Inc. or its Affiliates.Tori Hara / toriclsSr. Product Developer AdvocateContainers Product, Amazon Web Services---ERP パッケージベンダー R&D チーム SDE➡ UI ⾃動テスト SaaS➡ クラウド利⽤の SI + MSP にて、コンテナやサーバーレスによる設計・開発・運⽤Web 技術利⽤のゲームやビジネスアプリケーション開発、ML/DL 環境構築運⽤など➡ Sr. Containers Specialist SA, AWS Japan➡ 現ロールAWS Fargate / AWS Lambda が好きです
© 2020, Amazon Web Services, Inc. or its Affiliates.本セッションは…想定される聴講者• コンテナワークロード構築を検討中• コンテナワークロードを運⽤中で、EC2 Spot 活⽤を検討中• コンテナが好き、EC2 Spot が好きゴール• EC2 Spot とコンテナがなぜ相性が良いのか説明できるようになる• EC2 Spot とコンテナの組み合わせ時に推奨されるベストプラクティスを理解する• ベストプラクティスを⾃⾝のワークロードに適⽤できる• もしくは適⽤するためにやるべきことを洗い出せる
© 2020, Amazon Web Services, Inc. or its Affiliates.Agenda1. EC2 Spot の導⼊ & よくある課題2. コンテナと EC2 Spot は本当に相性が良いのか3. EC2 Spot の世界を⽣き抜けるアプリケーションとは4. 具体的構築パターンに学ぶコンテナ x EC2 Spot ワークロード
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot の導⼊ & よくある課題
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot 導⼊ & よくある課題• EC2 Spot Instances の特徴• 最⼤90%OFF• インスタンスの中断が起こりうる• 導⼊にあたってのよくある課題は「中断される」特性によるもの1. 中断によるキャパシティ減少2. いつでも AMI から最新のアプリケーションが⼊ったインスタンスを実⾏できるよう、アプリケーション更新毎に AMI 作成とインスタンス⼊替を⾏う⼿間と時間 (⼿動・⾃動はここでは問題ではない)3. アプリケーションが処理中に⽌まることによる不具合発⽣の可能性4. 「アプリケーション再実⾏」の考慮
© 2020, Amazon Web Services, Inc. or its Affiliates.代表的な課題と解決策の列挙1. 停⽌によるキャパシティ減少• EC2 Auto Scaling / Spot Fleet でキャパシティの維持が可能 (前セッション)2. キャパシティ復旧後のアプリケーション再実⾏の担保• ︖3. アプリケーション、ホストのライフサイクル混在によるオペレーション負荷• ︖4. アプリケーション処理中の停⽌・再開による不具合発⽣の可能性• ︖
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot とコンテナは本当に相性が良いのか
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot とコンテナは本当に相性が良いのか• 本セッションにおける「相性」• システム間の組み合わせの良さ・悪さ• 相性が良い• ⼆つないし複数のコンポーネントがそれぞれの特性を補完、もしくは互いの特性が順応し、相対的に全体がより良いシステムとして稼働できる状態• 相性が悪い• それぞれの特性の衝突により個々の良さが発揮されない、あるいは相対的にシステム全体における機能性や価値が損なわれている状態
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot、コンテナの特性EC2 Spotü 安価に利⽤可能でありながらオンデマンドインスタンスと同じ仮想マシンを利⽤可能 AWS 側のインスタンス需要などに基づきインスタンスを中断されることがあるコンテナü 実⾏環境の Docker エンジンがアプリケーションの動作を担保ü コンテナイメージの送受信が容易ü コンテナ間アイソレーション❤❔
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot と相性が良いのは EC2 Auto ScalingEC2 Spotü 安価に利⽤可能でありながらオンデマンドインスタンスと同じ仮想マシンを利⽤可能 AWS 側のインスタンス需要などに基づきインスタンスを中断されることがあるEC2 Auto Scalingü あらかじめ指定されたインスタンスタイプや購⼊モデルなどをもとに、キャパシティサイズを維持❤
© 2020, Amazon Web Services, Inc. or its Affiliates.❤❔EC2 Auto Scaling とコンテナの相性が良い︖EC2 Auto Scalingü あらかじめ指定されたインスタンスタイプや購⼊モデルなどをもとに、キャパシティサイズを維持コンテナü 実⾏環境の Docker エンジンがアプリケーションの動作を担保ü コンテナイメージの送受信が容易ü コンテナ間アイソレーション
© 2020, Amazon Web Services, Inc. or its Affiliates.AS とコンテナオーケストレータの相性が良いEC2 Auto Scalingü あらかじめ指定されたインスタンスタイプや購⼊モデルなどをもとに、キャパシティサイズを維持Amazon ECS/EKSü あらかじめ指定されたコンテナ実⾏定義をもとに、クラスタ内のコンテナ実⾏状態を維持
© 2020, Amazon Web Services, Inc. or its Affiliates.Amazon EC2 Auto Scaling における⾃動復旧
© 2020, Amazon Web Services, Inc. or its Affiliates.Amazon ECS/EKS における⾃動再実⾏
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Auto Scaling + Amazon ECS/EKS
© 2020, Amazon Web Services, Inc. or its Affiliates.コンテナと EC2 Spot は本当に相性が良いのか• 実は相性が良いのはコンテナと EC2 Spot そのものではない⇨ コンテナや EC2 Spot Instances を実⾏するそれぞれの仕組みの相性が良い• コンテナオーケストレータと EC2 Auto Scaling の相性が良い⇨ ともに「宣⾔的」な挙動であるため⾃動化される EC2 Auto Scaling によるホストの⾃動復旧 + ECS/EKS によるコンテナの再実⾏が⾒込める (AWS Batch については後述) コンテナイメージがアプリケーションとインスタンスのライフサイクルの分界点になるため、AMI 再作成の⼿間も減らせる EC2 Auto Scaling は Spot Instances の起動もサポートしている
© 2020, Amazon Web Services, Inc. or its Affiliates.代表的な課題と解決策の列挙 (再掲)1. 停⽌によるキャパシティ減少• EC2 Auto Scaling / Spot Fleet でキャパシティの維持が可能 (前セッション)2. キャパシティ復旧後のアプリケーション再実⾏の担保• コンテナオーケストレータによる再実⾏3. アプリケーション、ホストのライフサイクル混在によるオペレーション負荷• コンテナイメージと AMI でライフサイクルを分割4. アプリケーション処理中の停⽌・再開による不具合発⽣の可能性• ︖
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot の世界を⽣き抜けるアプリケーションとは
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot の世界を⽣き抜くアプリケーション• 課題『アプリケーション処理中の停⽌・再開で不具合が発⽣するかも』• 外部要因でアプリケーションが停⽌する• アプリケーション観点で考慮すべき点は⼤きく分けて3つ1. 処理中のユーザーリクエストやデータなどを壊すことなく停⽌できるか2. 停⽌後、そのアプリケーションの再実⾏が担保されるか3. 再実⾏によって意図しない副作⽤が発⽣しないか
© 2020, Amazon Web Services, Inc. or its Affiliates.1. 安全に停⽌しやすいアプリケーション• SIGTERM を受け取り Graceful に終了する• ユーザーからのリクエストを返しきる• ログをバッファリングしている場合、出⼒しきる• 計算処理を(適切な待ち時間で)中断する• ステートレスに設計されている• 状態はマネージドサービス(e.g. RDS, S3)に逃し、アプリケーションをステートレスに保つ• コンテナを利⽤している場合、ベストプラクティスに沿ったコンテナイメージを作る/使う• 1コンテナ1プロセス etc.https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
© 2020, Amazon Web Services, Inc. or its Affiliates.1. 安全に停⽌しやすいアプリケーション• 常駐型アプリケーションの場合 (e.g. Web サーバ)• 多くの場合ロードバランサで Connection Draining を⾏う• ステートレス、ステートレス、ステートレス• ログのホストストレージへの出⼒も極⼒避ける (use stdout/stderr)• スタンドアロン型アプリケーション (e.g. バッチジョブ)• 再実⾏される可能性を常に考慮して設計する• 1つの⻑⼤なジョブではなく、細かい並列実⾏のジョブとして設計できると停⽌しやすい• 実装的にも⼼理的にも• アプリケーションのステートレス化も容易に
© 2020, Amazon Web Services, Inc. or its Affiliates.【参考】§ Amazon ECS• Service - https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html• Task - https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html§ AWS Batch• Job - https://docs.aws.amazon.com/batch/latest/userguide/jobs.html• Managed Computing Environment - https://docs.aws.amazon.com/batch/latest/userguide/compute_environments.html§ Amazon EKS (Kubernetes)• Deployment - https://kubernetes.io/docs/concepts/workloads/controllers/deployment/• Jobs - https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/2. 停⽌後のアプリケーション再実⾏を担保する常駐型 (e.g. Web サーバ) スタンドアロン型 (e.g. バッチ処理)Amazon ECS Amazon EKS(Kubernetes)Amazon ECS AWS Batch Amazon EKS(Kubernetes)Service Deployment(ReplicaSet)e.g. Step Functions+ Task (*)Job(Managed ComputeEnvironment backed)Job※ Amazon ECS は単体ではスタンドアロン型タスクの終了保証を⾏わない. Appendix 参照.Appendix は時間の都合で作れなかったので別の機会でご覧ください...
© 2020, Amazon Web Services, Inc. or its Affiliates.3. 再実⾏による意図しない副作⽤を回避する• 常駐型アプリケーションの場合 (e.g. Web サーバ)• Stateless, Stateless, Stateless• このタイプのアプリケーションはそもそも複数個が同時に⾛ることが⼀般的なため、再実⾏⾃体の難易度は低い• スタンドアロン型アプリケーション (e.g. バッチジョブ)• 再実⾏される可能性を常に考慮して設計する (再)• 1つの⻑⼤なジョブではなく、並列実⾏の短いジョブとして設計できると再実⾏しやすい (再)• いわゆる「べき等」な設計が望ましい• 同⼀ジョブの複数回実⾏が外部に与える副作⽤を同じ状態に収束するよう設計する
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Spot の世界を⽣き抜くアプリケーション• 安全に終了・再開できるアプリケーションは EC2 Spot にフィットする• できる限りステートレスであり、いつでも停⽌できること• 再実⾏される可能性を考慮した設計と実装になっていること• これらの実現によるメリットは Spot やコンテナの世界だけに限らない• 継続的デプロイメントの実践が容易• スケールアウト/インがやりやすいダイナミックなアーキテクチャの実現
© 2020, Amazon Web Services, Inc. or its Affiliates.代表的な課題と解決策の列挙 (再掲)1. 停⽌によるキャパシティ減少• EC2 Auto Scaling / Spot Fleet でキャパシティの維持が可能 (前セッション)2. キャパシティ復旧後のアプリケーション再実⾏の担保• コンテナオーケストレータによる再実⾏3. アプリケーション、ホストのライフサイクル混在によるオペレーション負荷• コンテナイメージと AMI でライフサイクルを分割4. アプリケーション処理中の停⽌・再開による不具合発⽣の可能性• アプリケーションごとに、停⽌・再実⾏・べき等を想定した設計と実装を⾏う
© 2020, Amazon Web Services, Inc. or its Affiliates.構築パターンに学ぶコンテナ x EC2 Spot
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Auto Scaling + Amazon ECS/EKS (再掲)
© 2020, Amazon Web Services, Inc. or its Affiliates.EC2 Auto Scaling + Amazon ECS/EKS (再掲)- Q -ECS/EKS に対して配下のインスタンスの登録解除を伝える必要がある⇨ いつ、どうやって伝える︖
© 2020, Amazon Web Services, Inc. or its Affiliates.ECS/EKS へのノード登録解除の伝え⽅• Amazon ECS• DeregisterContainerInstance API• 対象のインスタンスに新しい Task がスケジュールされなくなる• 対象のインスタンス上で⾛る ECS Tasks が ELB のターゲットグループに登録されている場合は⾃動的に登録を解除• インスタンス上のタスクは停⽌されないが、ECS の認知しないタスクとなる。ECSService 配下のタスクは別インスタンス上で再実⾏されるhttps://docs.aws.amazon.com/AmazonECS/latest/developerguide/deregister_container_instance.html
© 2020, Amazon Web Services, Inc. or its Affiliates.ECS/EKS へのノード登録解除の伝え⽅• Amazon EKS (Kubernetes)• `kubectl drain` コマンド• 対象のインスタンス上に新しい Pod がスケジュールされなくなる• 対象のインスタンス上の Pod を別インスタンス上に移動(新規作成と停⽌)• see “Pod Disruption Budget”https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#drainhttps://kubernetes.io/docs/concepts/workloads/pods/disruptions/
© 2020, Amazon Web Services, Inc. or its Affiliates.いつ伝える︖ - EC2 Spot Interruption Warning -• スポットインスタンスの価格は⻑期供給と需要に基づいて徐々に調整される• スポットインスタンスは AWS によって中断されることがある(2018 年のある 3 ヶ⽉間に AWS によって中断された Spot Instances は全体の 5%)• AWS によって中断される際は 2 分前までに通知される⇨ 中断通知を受け取ったら ECS/EKS からインスタンスを登録解除する
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取り⽅1. Amazon EventBridge (旧 CloudWatch Events)• AWS リソースの変更をイベントストリームとして対応するサービスやリソースなどに対して送信• e.g. Interruption Warning → Amazon EventBridge → AWS Lambda2. インスタンスメタデータ• 通常時は 404 Not Found• EC2 Spot によって中断が予約されると中断予定時刻が返ってくる$ curl -sf http://169.254.169.254/latest/meta-data/spot/termination-time2019-04-09T06:30:00Zhttps://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取りと ECS への伝達- 1. Amazon EventBridge -構築パターン
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取り⽅と ECS への伝達- 1. Amazon EventBridge → AWS Lambda → Amazon ECS• 中断通知を Amazon EventBridge 経由で AWS Lambda 関数へhttps://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取り⽅と ECS への伝達- 1. Amazon EventBridge → AWS Lambda → Amazon ECS• AWS Lambda 関数が受け取る JSON 例{"version": "0","id": "12345678-1234-1234-1234-123456789012","detail-type": "EC2 Spot Instance Interruption Warning","source": "aws.ec2","account": "123456789012","time": "yyyy-mm-ddThh:mm:ssZ","region": "us-east-2","resources": ["arn:aws:ec2:us-east-2:123456789012:instance/i-1234567890abcdef0"],"detail": {"instance-id": "i-1234567890abcdef0","instance-action": "action"}}https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取り⽅と ECS への伝達- 1. Amazon EventBridge → AWS Lambda → Amazon ECS• AWS Lambda 関数例 (Python)import boto3# - 省略 -def handler(event, context):instance_id = event['detail']['instance-id’]logger.info('{0} will be terminated in 2 minutes'.format(instance_id))ecs = ECS(region)ecs.deregister(instance_id)https://github.com/awslabs/ec2-spot-labs/tree/master/ecs-ec2-spot-auto-deregister
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取りと EKS への伝達- 1. Amazon EventBridge -構築パターン
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取り⽅と EKS への伝達- 1. Amazon EventBridge → AWS Lambda → Amazon EKS (Kubernetes)• ECS 同様 Amazon EventBridge 経由で AWS Lambda に通知• `kubectl drain ${NODE_NAME} --force --ignore-daemonsets` を実⾏https://github.com/aws-samples/amazon-k8s-node-drainer※ このリポジトリでは drain ではなく cordon + Eviction API が使われている実装例 (このサンプルは Auto Scaling Group のライフサイクルフックとのインテグレーション例)
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取りと ECS への伝達- 2. インスタンスメタデータ -構築パターン
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取り⽅と ECS への伝達- 2. インスタンスメタデータ → Amazon ECS• ECS Agent がインスタンスメタデータのチェックと ECS へのドレイン指⽰を⾏う機能を有効化https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-spot.html#!/bin/bashcat <> /etc/ecs/ecs.configECS_CLUSTER=MyClusterECS_ENABLE_SPOT_INSTANCE_DRAINING=trueEOF※ 上記のような User data スクリプトなどを利⽤して、ECS_ENABLE_SPOT_INSTANCE_DRAINING=true を ECSAgent に設定する
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取りと EKS への伝達- 2. インスタンスメタデータ -構築パターン
© 2020, Amazon Web Services, Inc. or its Affiliates.中断通知の受け取り⽅と EKS への伝達- 2. インスタンスメタデータ → Amazon EKS (Kubernetes)• インスタンスメタデータのチェックと Kubernetes へのドレイン指⽰を⾏う“AWS Node Termination Handler” をデプロイする※ これにより Termination Handler コンテナが Kubernetes DaemonSet として全ノードに配置される※ Windows ノード⾮対応 see https://github.com/aws/aws-node-termination-handler/issues/8※ Helm チャートあり〼 https://github.com/aws/eks-charts# マニフェストをダウンロード$ curl -o node-termination-handler.yaml \https://github.com/aws/aws-node-termination-handler/releases/download/v1.4.0/all-resources.yaml# DaemonSet の環境変数 ENABLE_SPOT_INTERRUPTION_DRAINING を “true” に書き換えてデプロイ$ vi node-termination-handler.yaml$ kubectl apply -f node-termination-handler.yamlhttps://github.com/aws/aws-node-termination-handler(AWS Node Termination Handler のリリースまでは以下を案内することもありました)https://github.com/awslabs/ec2-spot-labs/tree/master/ec2-spot-eks-solution/spot-termination-handler and/or https://github.com/kube-aws/kube-spot-termination-notice-handler
© 2020, Amazon Web Services, Inc. or its Affiliates.Fargate Spot (ECS) での中断通知ハンドリング- SIGTERM -構築パターン
© 2020, Amazon Web Services, Inc. or its Affiliates.Fargate Spot (ECS) での中断通知ハンドリング- SIGTERM• EC2 Spot 同様、2分前の警告がある• 警告は以下の2種類の形式• 1. Amazon EventBridge へのタスク状態変更イベント• 2. ECS タスクで実⾏されているアプリケーションへの SIGTERM シグナル• Graceful な終了が実装できているアプリケーションであれば、特段の⼼配なく安全に停⽌可能• ECS はデフォルトでは SIGTERM シグナルの30秒後に SIGKILL シグナルを発⾏• タスク定義内コンテナ定義の stopTimeout 値を 120 などに設定しておけば中断通知後のアプリケーション内の終了処理に時間的余裕を与えられるhttps://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-capacity-providers.html#fargate-capacity-providers-terminationhttps://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_timeout
© 2020, Amazon Web Services, Inc. or its Affiliates.本⽇のまとめ1. 停⽌によるキャパシティ減少• EC2 Auto Scaling / Spot Fleet でキャパシティの維持が可能 (前セッション)2. キャパシティ復旧後のアプリケーション再実⾏の担保• コンテナオーケストレータによる再実⾏3. アプリケーション、ホストのライフサイクル混在によるオペレーション負荷• コンテナイメージと AMI でライフサイクルを分割4. アプリケーション処理中の停⽌・再開による不具合発⽣の可能性• アプリケーションごとに、停⽌・再実⾏・べき等を想定した設計と実装を⾏う+ インスタンス中断時にコンテナオーケストレータから登録解除する
© 2020, Amazon Web Services, Inc. or its Affiliates.Thank you!Tori Haratoricls
© 2020, Amazon Web Services, Inc. or its Affiliates.Appendix
© 2020, Amazon Web Services, Inc. or its Affiliates.ECS スタンドアロンタスクの成功終了保証 w/ Step Functions{"StartAt": "Run an ECS Task and wait for it to complete successfully","States":{"Run an ECS Task and wait for it to complete successfully":{"Type":"Task","Resource":"arn:aws:states:::ecs:runTask.sync","Parameters":{"LaunchType":"FARGATE","Cluster":"arn:aws:ecs:us-west-2:123456789012:cluster/my-cluster","TaskDefinition":"arn:aws:ecs:us-west-2:123456789012:task-definition/my-task:1","Overrides":{"ContainerOverrides":[{"Name":"my-container","Environment":[{"Name":"SOME_VALUE","Value.$":"$.some_value"}]}]}},"Retry":[{"ErrorEquals":["States.TaskFailed"],"IntervalSeconds":3,"MaxAttempts":3,"BackoffRate":1.5 }],"End":true }}}1. Manage Amazon ECS or Fargate Tasks with Step Functions: https://docs.aws.amazon.com/step-functions/latest/dg/connect-ecs.html2. Error Handling in Step Functions: https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html例: ECS タスクの処理が失敗した際に最⼤3回までリトライする Step Functions のステートマシンの定義