Amazon Web Services ブログ
Locust を用いた Amazon EKS 上で動作するワークロードの負荷テスト
序章
多くの AWS 利用者は、自身のワークロードを実行するために Amazon Elastic Kubernetes Service ( Amazon EKS ) を利用しています。そのため、EKS クラスターをテストするプロセスを用意して、ワークロードを公開する前に弱点を特定し、クラスターを最適化することが不可欠です。負荷テストは、実世界のトラフィックを模倣する人工的な負荷を発生させることによって、ワークロードの性能や信頼性に焦点を当てます。特に、EKS の高い弾力性を期待する場合には有効です。 Locust は、リアルタイムダッシュボード 及び プログラマブルなテストシナリオを備えたオープンソースの負荷試験ツールです。
このブログでは、2 つの Amazon EKS クラスターを構築する手順を説明します。片方の Amazon EKS では Locust を用いて負荷を発生させ、もう片方でサンプルのワークロードを実行します。このブログの内容は、Amazon EKS の性能 及び 信頼性をテストする際の任意の状況に適用できます。
このブログで利用する全てのソースコードとリソースは、こちらの GitHub リポジトリにあります。
ソリューションの概要
下記の図は、このブログ全体で利用するアーキテクチャを示しています。アプリケーションは、EKS クラスター ( ターゲットクラスター ) 内の ポッドグループで実行され、Application Load Balancer を通してパブリックに公開されています。その間、Locust は別の EKS クラスター ( Locust クラスター ) で動作します。今回、ノード数とポッド数をそれぞれスケールアウトさせる必要があるため、Cluster Autoscaler ( CA ) 及び Horizonal Pod Autoscaler ( HPA ) は、両方のクラスターで設定されます。
加えて、Application Load Balancer を作成し、Ingress を介して Kubernetes サービスへ接続するために、AWS Load Balancer Controller は両方のクラスターにインストールします。
注意:今回用意するリソースにかかる料金は、AWS の無料枠でカバーできません。
下準備
本手順では、2 つの EKS クラスターが必要です。負荷を発生させる Locust クラスター と テスト対象のワークロードを動作させる もう一方のクラスターです。下記のガイドを使って、クラスターをセットアップします。
前提条件
CLIツールのインストールと設定
- kubectl ( version release ) 本blogではver1.21を使用
- eksctl ( version release )
- helm ( version release )
- jq
- awscli v2
- AWS Profile の設定 ( 最小権限の IAM Policy )
- git リポジトリーの準備
既にクラスターの用意があるならば、これらの手順をスキップできます。
- Locust のクラスター作成
- ワークロード実行用クラスターの作成 ( オプション )
VPC を 2つ作成可能か確認するために、AWS アカウントのリミットをチェックしてください。もし、当該 AWS アカウントでクォータ以上の数の VPC を作成しようとした場合、クラスターの作成は失敗します。
AWS コンソールで結果を確認してください。
ベーシックアドオンチャートのインストール
EKS で負荷テストをするために、2, 3 の Kubernetes アドオンを追加します。これらのアドオンは、YAML/JSON で記載された Kubernetes マニフェストファイル または Helm チャートを介してインストールできます。今回は、管理が簡単でよく利用される Helm チャートを使います。awsblog-loadtest-locust
と awsblog-loadtest-workload
( または、他のターゲットクラスター ) の準備ができているならば、下記のチャートをインストールするために、こちらを参照してください。
- メトリクスサーバーのデプロイ ( YAML )
- HPA のインストール手順のスキップ
- Cluster Autoscaler のインストール ( チャート )
- AWS Load Balancer Controller のインストール ( チャート)
- Container Insights のインストール ( YAML )
Helm チャートを使ったサンプルアプリケーションのインストール
下準備の最後の手順として、テスト用のサンプルアプリケーションをデプロイする必要があります。これにも Helm を利用します。 ( テスト用のアプリケーションが既に存在するならば、この手順はスキップし、自身のアプリケーションを利用できます )。
サンプルアプリケーションが正常にインストールされると、Helm チャートによって作成された Ingress に関連づけられた Application Load Balancer の DNS 名にアクセスすることで、サンプルアプリケーションからのウェルカムメッセージを確認できます。
ウォークスルー
Kubernetes の準備が整いました。しかし、アプリケーションのテストをする前に設定することが まだいくつか残っています。
ステップ 1 Locust のインストール
Locust クラスターに対してコマンドを発行するため、Kubernetes のコンテキストを切り替えてください。
前のセクションで、ワークロードクラスターにサンプルアプリケーションをインストールしました。アプリケーションをテストするためワークロードクラスターから Locust クラスターへコンテキストを切り替える必要があります。
Delivery Hero 公開チャートリポジトリの追加
locustfile.py の作成
下記コードのファイルを作成し、locustfile.pyとして保存してください。テスト先のエンドポイントを変更したい場合は、下記ファイルの “/” から始まる行を変更してください ( 下準備でデプロイした、 /load-gen/loop?count=50&range=1000 のように )。locustfile.py の書き方詳細は、こちらを参照ください。
locustfile.py を用いた Locust のインストールと設定
下記のコマンドを実行すると、前のセクションで作成した locustfile.py を使って Locust をインストールできます。この時、HPA は有効化されており、5 つのポッドで Locust が起動します。これは、負荷量の上昇に伴って自動的にスケールする負荷テストの良い開始ポイント提供します。
ステップ 2 ALB を介して Locust を公開
Locust のインストールが成功した後、Locust のダッシュボードを公開するために Ingress を作成すると、ブラウザからアクセスできます。
ステップ 3 Locust のダッシュボードのチェック
ステップ 2 で Ingress を作成した後、下記のコマンドを実行することで Application Load Balancer の URL を取得できます。おそらく、Application Load Balancer のエンドポイントを取得するために、少し時間 ( 2 分程度 ) が必要です。
AWS コンソールからも同様の情報を得ることができます。Amazon EC2 のコンソール内のロードバランサーのページに移動し、目的のロードバランサーを選択します。URL は、“Description” タブに “DNS name” として記載があります。
ブラウザからロードバランサーの URL にアクセスします。
もしくは、Locust サービスをローカルポートにポートフォワーディングすることで、Ingress リソースを作成せずに Locust のダッシュボードにアクセスすることもできます。
ブラウザで http://localhost:8089 へ接続してください。
ステップ 4 テストを実行
先程デプロイしたアプリケーションの URL を入力しましょう。“Number of total users to simulate” に 100 を、“Spawn rate” に 1 を入力しましょう。さらに、先程作成したワークロードクラスターの URL エンドポイントを “Host” に入力します。
数分間実行しましょう。実行中に Statistics
タブと Charts
タブを切り替えて、どのようにテストが展開されているか確認しましょう。
statistics タブでは、負荷テストの結果のサマリーを確認できます。また、上の図の赤のライン Failure/s に目立ったスパイクが発生していない点は重要です。
ワークロードクラスターのベーシックメトリクスの断片を確認するために、CloudWatch Container Insights ダッシュボードを参照します。さらに、Prometheus/Grafana ダッシュボードをセットアップすることで EKS コントロールプレーンを含む様々なメトリクスを可視化することができます。EKS Kubernetes コントロールプレーンのパフォーマンスを監視する方法について、こちらのベストプラクティスガイドを参照してください。
EKS で実行されているターゲットワークロードは、100 ユーザからのリクエストを妥当な応答時間以内で処理していることが負荷試験の結果から分かります。また、CloudWatch Container Insights でクラスターのパフォーマンスメトリクスの詳細を見ることができます。
ここで、もう少しだけ負荷を与えます。負荷テストを止め、ユーザ数を増やします。“Number of total users to simulate” の値を 1,000
に、“Spawn rate” の値を 10
にしましょう。そして先ほどのグラフと比べてみましょう。
前回の負荷テストと同様のグラフになりました。ワークロードクラスターは、これらの負荷をカバーできるようです。
ステップ 5 セカンドテスト
ここで、ユーザー数を 100 万人にして、負荷試験時間を長くしてみましょう。“Number of total users to simulate” の値を 1,000,000
に、“Spawn rate” の値を 100 にしましょう。ワークロードクラスター 及び Locust クラスターはこのトラフィックをカバーするための十分なリソースがあります。グラフは、緩やかな右肩上がりとなっています。クラスターのインスタンスが小さかったり、Locust の CPU 負荷が高かったりすると、ノードを追加するために、Cluster Autoscaler が実行されます。グラフにそれが反映されています。
負荷が高くクラスターがスケールを必要とするとき、レスポンスタイムが遅くなり、50X HTTP レスポンスが返答されることもあります。なので、応答性と耐障害性を高めるため、クラスターに対していくつかの手法が必要です。自身で負荷テストをする際の役立つ Tips をここにいくつか記載します。
- 新たにスケールしたポッドの待機時間を最小化するために、最適なポッドの Readiness probe を見つけましょう。
- 許容時間内に Autoscaler によってスケールアウトするようにワークロードに合わせ HPA/CA の設定の微調整しましょう。
- HPA の応答時間 + CA の応答時間 + ノードのプロビジョニングに時間がかかり、ノードのプロビジョニングには通常 最も時間がかかります。それゆえ、Amazon EKS optimized Amazon Linux AMIs をベースとしたより軽量な AMI を利用することや、より高い集積性を確保するために、コンテナのリソースに制限をかけることが有効です。
- ボトルネックがあるかどうか確認するため、スケールしたポッドのライフサイクルを確認しましょう。例えば、メトリクスの抽出遅延、ポッドのスケールアウトのための HPA のトリガー、コンテナイメージのダウンロード、アプリケーションの読み込み時間、 Readiness probe などです。
- オーバープロビジョニングする際は、負の優先度がついた一時的なポッドを採用し、クラスターに十分なリソースを確保しましょう。これにより、ノードのプロビジョニング時間が劇的に削減できます。なぜなら、スケールしたポッドがホストできるノードが既に存在するからです。
- 負荷テスト中にスケールダウンが発生するなら、それを止めましょう。スケールダウンによるノードの排除についての詳細は、こちらを参照ください。
- パフォーマンスとコストのトレードオフを理解しましょう。クラスターに最適なノードタイプ 及び ノード数、スポットインスタンスの割合、オートスケーリングの閾値 及び アルゴリズム等を見つけ、それに合わせるために、定期的に負荷テストをしましょう。
- EKS におけるオートスケーリングについての詳細は、こちらを参照ください。
クリーンアップ
負荷テストが完了したら、テストで利用したリソースを削除します。
完了です。注意点として、上記のスクリプトは、awsblog-loadtest-locust
クラスターを削除するだけです。TARGET_GROUP_NAME に workload
をセットして、awsblog-loadtest-workload
クラスターを削除するために、必ず上記のプロセスを再度繰り返してください。
さいごに
このブログでは、EKS 上で実行されたワークロードの負荷テストをするために、2 つの EKS クラスターとツールをセットアップしました。Cluster Autoscaler が動作していると、予想通り、Locust を用いて発生させた高い負荷はスムーズに処理されたことが分かりました。Locust のダッシュボード 及び CloudWatch Container Insights は、クラスターが耐えられる最大の負荷を特定するのに役立ちます。
実環境に合わせた様々なテストシナリオに沿ってlocustfile.py
をカスタマイズすることで、さらに負荷試験を実施できます。次のブログでは、EKS クラスターが負荷テスト時の高負荷やスパイクした負荷に対処する様々なテクニックを紹介しようと思います。
翻訳はソリューションアーキテクト祖父江が担当しました。原文はこちらです。