Amazon Web Services ブログ

Amazon ECSでAuto Scaling

Amazon EC2 Container Service (Amazon ECS)のClusterを自動的にスケールさせる方法はありましたが、本日Auto ScalingとAmazon CloudWatchのAlarmに追加された新機能により、ECSのServiceにScaling Policyを利用することができます。ServiceのAuto Scalingにより、需要が高まった時にスケールアウトさせて高い可用性を実現したり、需要が下がったらServiceとClusterをスケールインさせることでコストを最適化するのを、全て自動でリアルタイムに行うことができます。

この記事では、Clusterを需要に合わせて自動的にリサイズさせつつ、この新しい機能がどうやって利用できるかをお見せします。

Service Auto Scalingの概要

すぐに利用できるECS Serviceのスケーリング機能はずっと一番要望を受けていて、ついに今日この機能をアナウンスでき嬉しいです。自動でスケールするServiceの作成手順はとても簡単で、ECSコンソールやCLI、SDKでもサポートされています。希望するTaskの数とその最小・最大数を選択し、1つ以上のScaling Policyを作成すると、後はService Auto Scalingが面倒を見てくれます。Service SchedulerはAvailability Zoneを意識してくれるので、ECSのTaskを複数のZoneに渡って分散するように心配する必要もありません。

それに加えて、ECS Taskを複数AZ Cluster上で実行することも非常に簡単です。ECS ClusterのAuto Scaling Groupが、複数Zoneに渡る可用性を管理してくれるので、必要とされる回復力や信頼性を持つことができ、ECSがTaskのZone間の分散を管理してくれるので、皆さんはビジネスロジックに集中することができます。

利点:

  1. 来ているアプリケーションの負荷にキャパシティを対応させる: ECS ServiceとECS ClusterのAuto Scaling Groupを両方にScaling Policyを使います。必要に応じて、Cluster InstanceとService Taskをスケールアウトさせ、需要が落ち着いたら安全にスケールインさせることで、キャパシティの推測ゲームから抜け出せます。これによって、ロングランな環境で低コストな高可用性を実現できます。
  2. 複数AZのClusterでECSの基盤に高い可用性を持たせる: Zone障害という可能性から守ることができます。Availability Zoneを考慮しているECS SchedulerはCluster上のTaskを管理し、スケールし、分散してくれるので、アーキテクチャは高い可用性を持ちます。

Service Auto Scalingのデモ

この記事では、これらの機能を使い真にスケーラブルで高い可用性を持ったMicroservicesアーキテクチャを作成する手順を辿りたいと思います。このゴールに到達するために、以下の様な手順をお見せします:

  1. Auto Scaling Groupで2つ以上のZoneにECS Clusterを作成する。
  2. そのCluster上にECS Serviceを設定し、希望するTaskの数を定義する。
  3. ECS Serviceの前段にElastic Load Balancingのロードバランサを設定する。これが負荷の入り口になります。
  4. ECS Service用のスケールインとスケールアウトのCloudWatch Alarmを設定する。
  5. ECS Cluster用のスケールインとスケールアウトのCloudWatch Alarmを設定する 。(注: 前のステップで作成したものとは別のAlarmになります)
  6. ECS Service用のScaling Policyを作成し、スケールアウトとスケールインする時のScaling Actionを定義する。
  7. ECS Clusterが動いているAuto Scaling Group用のScaling Policyを作成する。これらのPolicyはECS Clusterのスケールイン・アウトで利用されます。
  8. 負荷を徐々に増やしたり減らしたりすることで、スケーラブルなECS ServiceとClusterの高可用性をテストする。

この記事では、Cluster上に1つのECS Serviceを設定する手順をお見せしますが、このパターンは同じCluster上で複数のECS Serviceを実行する時にも適応できます。

注意: この例を実行した結果、発生した如何なるAWSのコストも支払う必要があります。

概念図

ECS ServiceのAuto Scalingを設定する

Auto Scalingを設定する前に、複数AZ (2 Zone)のCluster上で実行されていて、ロードバランサを前段に持つECS Serviceを作っておく必要があります。

CloudWatch Alarmを設定する

  1. Amazon CloudWatchのコンソール上で、ECS Serviceのスケールインとスケールアウト時に使われるCloudWatch Alarmを設定します。このデモではCPUUtilization (ECS, ClusterName, ServiceNameのカテゴリから選びます)を使いますが、他のMetricsを使うこともできます。(注: 他のやり方として、Service用のScaling Policyを設定する時にはECSのコンソール上でこれらのAlarmを設定することもできます。) 
  2. AlarmにECSServiceScaleOutAlarmという名前をつけ、CPUUtilizationの閾値を75に設定します。
  3. Actionの所でNotificationを削除します。このデモではECSとAuto Scalingのコンソールを使ってActionを設定します。
  4. 上記の2ステップを繰り返してスケールインのAlarmを作成し、CPUUtilizationの閾値を25にして、演算子を”<=”に設定します。
  5. Alarmsの所で、スケールインのAlarmがALARM状態にあるはずです。今のところECS Serviceに負荷がかかっていないので、これは期待した状態です。
  6. ECS Cluster用のCloudWatch Alarmを設定するために、前のステップと同じことをします。今度は、CPUReservation (ECS, ClusterNameから選びます)をMetricとして利用します。前のステップの様に2つのAlarmを作成し、1つがECS Clusterのスケールアウト用、他方がスケールイン用とします。それらにECSClusterScaleOutAlarmとECSClusterScaleInAlarm という名前(または自由な名前)を設定します。

注: これはCluster固有のMetricですが(Cluster-Service固有のMetricと対照的)、このパターンでも有効的ですし、複数ECS Serviceのシナリオでも有効です。ECS Clusterはどれが起因であってもClusterの負荷に応じて常にスケールします。

ECS ServiceのスケールはECS Clusterのスケールに比べてとても速いので、ECS ClusterのスケーリングのAlarmをECS ServiceのAlarmよりも敏感にしておくことをお勧めします。こうすることで、スケーリングの間Clusterに余分なキャパシティが常にあることを保証でき、一瞬の負荷のピークに対応することができます。もちろん気をつけるべきは、この余分なEC2のキャパシティでコストは増えるので、Clusterのキャパシティを確保するのとコストの間で良いバランスを見つける必要がありますが、それはアプリケーション毎に異なるでしょう。

ECS ServiceにScaling Policyを追加する

Add a scale out and a scale in policy on the ECS service created earlier.

先ほど作成したECS ServiceにスケールアウトとスケールインのPolicyを追加します。

  1. ECSコンソールにサインインし、Serviceが動いているClusterを選択、Servicesを開いてServiceを選択します
  2. Serviceのページでは、Updateを選択します。
  3. Taskの数が2になっていることを確認します。これはそのServiceが実行する時のデフォルトのTask数です。
  4. Update ServiceのページのOptional configurationsの下にある、Configure Service Auto Scalingを選択します。
  5. Service Auto Scaling (optional)のページのScalingの下にある、Configure Service Auto Scaling to adjust your service’s desired countを選択します。Minimum number of tasksとDesired number of tasksの両方に2と入力します。Maximum number of tasksには10を入力します。ECS Serviceの作成時にホスト(EC2インスタンス)上の80番ポートをECS Containerの80番ポートにマッピングしているので、Auto Scaling GroupとECS Taskが両方共同じ数値になっていることを確認しておいて下さい。
  6. Automatic task scaling policiesセクションの下の、Add Scaling Policyを選択します。
  7. Add Policyのページでは、Policy Nameに値を入力します。Execute policy whenには、前に作成したCloudWatch Alarm (ECSServiceScaleOutAlarm)を入力します。ActionではAdd 100 percentを設定し、Saveを選択します。
  8. 上の2つのステップの繰り返しで、前に作成したスケールインのCloudWatch Alarm (ECSServiceScaleInAlarm)を使ってスケールインのPolicyを作成します。ActionではRemove 50 percentを設定し、Saveを選択します。
  9. Service Auto Scaling (optional)ページで、Saveを選択します。

ECS ClusterにScaling Policyを追加する

ECS Cluster (Auto Scaling Group)にスケールアウトとスケールインのPolicyを追加します。

  1. Auto Scalingのコンソールにサインインしてこのデモ用に作成したAuto Scaling Groupを選択します。
  2. DetailsからEditを選択します。
  3. DesiredとMinが2に、Maxが10に設定されていることを確認して、Saveを選択します。
  4. Scaling PoliciesからAdd Policyを選択します。
  5. まず、スケールアウトのPolicyを作成します。Nameに値を入力し、Execute policy whenは前に作成したスケールアウトのAlarm (ECSClusterScaleOutAlarm)を選択します。ActionではAdd 100 percent of groupを設定し、Createを選択します。
  6. 上のステップを繰り返して、スケールインのPolicyをスケールインのAlarm (ECSClusterScaleInAlarm)を使って、ActionにはRemove 50 percent of groupを設定します。

Auto Scaling Group用のスケールインとスケールアウトのPolicyを見ることができるはずです。これらのPolicyを使って、Auto Scaling GroupはECS Serviceが動いているClusterのサイズを大きくしたり小さくしたりできます。

注: ClusterのScaling Policyをこの様に設定することで、Clusterに幾つかの余分なキャパシティを確保することになります。これによってECS Serviceのスケールアウトはより高速になりますが、同時に、需要に依ってはいくつかのEC2インスタンスが利用されない状態になることがあります。

以上でECS ServiceとAuto Scaling Groupに対して、今回はそれぞれ異なるCloudWatch Alarmによって発動するようにAuto Scalingの設定が完了しました。異なるCloudWatch Alarmsの異なる組み合わせを使ってそれぞれのPolicyをもっと凝ったScaling Policyとすることもできます。

これでスケールアウトできるキャパシティを持ったCluster上で動作するServiceができあがったので、Alarmが発動するようにロードバランサにトラフィックを流してみましょう。

ECS Serviceスケーリングの負荷試験

それでは、Apache abツールを使いECS Serviceに負荷試験をして、スケーリングの設定が動作するかを確認してみます(負荷試験インスタンスの作成の章をご覧ください)。CloudWatchのコンソールで、Serviceがスケールアウト・インする様子が見られます。Auto Scaling Groupが2つのAvailability Zoneを使う用に設定されているので、各Zoneに5つのEC2インスタンスを見ることができるはずです。また、ECS Service SchedulerもAvailability Zoneを意識するので、Taskも2つのZoneに渡って分散しているでしょう。

EC2コンソールから、手動でEC2インスタンスを終了させることで高可用性の試験もできます。Auto Scaling GroupとECS Service Schedulerが、追加のEC2インスタンスを起動しTaskも起動してくれるはずです。

追加で考慮すべきこと

  • キャパシティの確保: 既に書いた様に、ECS Clusterに余分なキャパシティを確保しておくことで、Clusterが新しいインスタンスを準備するのを待たなくて良いので、ECS Serviceのスケールアウトがとても高速になります。こちらはCloudWatch Alarmが発動する値を変更するか、Scaling Policyの値を変更することで簡単に実現できます。
  • インスタンスの終了保護: いくつかのスケールインのケースでは、利用できるECS Clusterのキャパシティが減少することで、強制的にTaskが終了したり他のホストに移動してしまいます。こちらはECS ClusterのスケールインのPolicyを需要に対して敏感に反応しないように調整するか、EC2のホストが終了する前にうまくTaskが終了できるようにすることで軽減できます。そのためには、別の記事で解説されているAuto Scaling Lyfecycle Eventインスタンスの終了保護をご覧頂くと良いと思います。

今回のデモではAWSコーンソールを使いましたが、もちろん同じことをAWS SDKやCLIを使って実現することも可能です。

まとめ

ミッションクリティカルなMicroservicesアーキテクチャを動かす時には、トータルでかかるコストを下げることは非常に重要ですし、加えて負荷を複数のZoneに分散できることや、ECS ServiceとClusterのキャパシティを負荷の変化に合わせて調整できることが必要になります。この記事でご紹介した手順では、2軸でのスケーリングを活用することでこれを実現することができます。

補足

2016年7月21日に全てのリージョンで利用可能となりました。 https://aws.amazon.com/about-aws/whats-new/2016/07/amazon-ec2-container-service-automatic-service-scaling-region-expansion/

原文: https://aws.amazon.com/blogs/compute/automatic-scaling-with-amazon-ecs/ (翻訳: SA岩永)