AWSの分散負荷テストを異なるアカウント間で実施する方法
1. はじめに
現在SDBでは、非機能の品質保証のため負荷対策に取り組んでいます。その中で、AWSが提供しているDistributed Load Testing on AWS ソリューションを用いて異なるアカウント間で負荷試験を行いました。(以後DLTと訳します)
今回はその負荷を実施する際に、問題となった点について解説したいと思います。
2. DLTとは?
DLTとはAWSが提供している負荷試験用のサービスとなります。ネット上でCloudFormationのテンプレートが公開されていますので、利用したい場合はそのテンプレートを読み込むだけで実施可能となります。
AWSの負荷サービスページ
こちらのテンプレートを読み込むと以下環境が動き、JMeterの利用やEndpointのテストなどができます。(構築方法については、すでにいろいろな記事がありますので割愛します。)
負荷環境の全体図
3. SDBの開発環境
SDBでは以下のようなAWS環境をとっており、各環境ごとにAWSアカウントを作成しています。
- 本番環境
- 実際にLiny(弊社サービス)が動作している環境。特定の権限を持っていないと操作できない。
- 検証環境(ステージング環境)
- リリース前に一度検証するための環境。大体の権限が開発者に付与されている。
- for-me環境
- 開発者個人に割り当てられた環境。実証実験など、一定金額を超えなければ好きに使っていい。
今回は実証実験を兼ねていますので、
- for-me環境でDLTを構築
- 検証環境に負荷をかける
こちらの流れで実施しました。
4. 負荷をかけてハマったところ
さて、さっそく負荷をかけてみることにしました。負荷はJMeterを用いて、検証環境のLinyに「アクセス→ログイン→ログアウト」するだけの単純なものです。
しかし、実際に動かしたところ以下のエラーが発生しました。
どうやら検証環境に接続できなかった様子。エラーの内容から、おそらくネットワークやセキュリティ周りと考え調査しました。その結果、検証環境のロードバランサーにアクセス許可がされていないため、弾かれていることがわかりました。
原因がわかったので、負荷を発生させている場所を公式ドキュメントから調べてみました。その結果、以下のECSで負荷のタスクを生成していることがわかりました。
DLTの負荷はECSで生成
しかし、ECS内のクラスターを確認しましたがタスクが存在しませんでした...
(本来はクラスター>タスクの順で見ていくと、タスクのところにIPアドレスが記載されている)
何故?と思い調査したところ、どうやらDLTは、
- 負荷をツール上で実施する
- LambdaがECSのタスクを作成
- 終わったらLambdaがECSのタスクを削除
という流れで実施していました。つまり、負荷をかけるまでタスクがないので、どのIPでアクセスするのか動作するまで不明である、ということでした。
DLTを動かすとタスクが発生する
NATゲートウェイでIPを固定する
上記課題の解決策がわからなかったため、AWSのサポートに問い合わせてみました。その結果、以下の記事と解決策を聞くことができました。
つまり、NATゲートウェイを作成し、対象の負荷をNATゲートウェイを通るようにすれば負荷のIPを固定にできます。さっそく以下のような環境を構築し、実施してみました。
DLTでIPを固定する方法
作成方法は、
- 負荷環境が起動するVPC内にSubnetを新規作成する(IPv4 subnet CIDR blockの値は一旦任意で設定)
- NATゲートウェイを作成し、[1]で作成したSubnetに配置。また、接続タイプは「パブリック」、Elastic IPを割り当てる
- 「Private Subnet」に対し、NATゲートウェイを通るようにルートテーブルを編集する(送信先「0.0.0.0/0」、ターゲットが「NATゲートウェイ」)
- [1]で作成したサブネットから、IGWを通るルートデーブルを編集する(送信先「0.0.0.0/0」、ターゲットが「IGW」)
- [2]のElastic IPを、接続先のセキュリティグループに登録する(インバウンドルールに記載すればOK)
上記対応の結果、以下のように負荷をかけることができました。
DLTで負荷をかけた結果
5. まとめ
今回DLTを用いて検証環境に負荷をかけてみました。ネットワークの知識が浅いため、負荷をかけるまでだいぶ時間を使ってしまいました...
しかし、各サービスに触れて様々な知識を学べたことは良い経験になったと思います。今後は、各案件ごとに対応した負荷をかけられるよう、DLTの使い方をまとめて行きます。
Discussion