LocustをKubernetesに構築して大規模な負荷テストをする
TL;DR
locustはhelmで簡単にapplyできる
$ helm repo add deliveryhero https://charts.deliveryhero.io/
$ helm install locust deliveryhero/locust
大規模な負荷テストをしたい
システムに負荷をかける際にvegetaを使うことが多いのですが、数千rpsでファイルディスクリプタの枯渇やCPUなどクライアントがボトルネックになることが多い
複数インスタンス立てればいいんだけど、環境構築が面倒だしテスト結果の集計などもっと楽をしたかった
locustを触ってみて、シンプルな使い勝手やGUI、レポート機能、workerをスケールできることなどからk8sに構築することにした
locustの使い方
まずはlocustの紹介
インストール$ brew install locust # pip3 install locust でもOK
タスクを記述したファイルを用意(詳細はこちら)
from locust import HttpUser, task
class HelloWorldUser(HttpUser):
@task
def hello_world(self):
self.client.get("/")
起動
$ locust
$ open http://0.0.0.0:8089
- Number of users (peak concurrency):リクエストを投げるクライアントの最大数
- Spawn rate (users started/second):秒間何クライアント増加させるか
- Host (e.g. http://www.example.com):リクエスト先のホスト
負荷をかけてる最中にリアルタイムでグラフが見れるのがいいです
1userでリクエストを投げたところ10rps程度を正常に処理できていることがわかります
userを増やしていけばリクエスト数も増えます
ローカルで実施するとおそらく数百rpsが限界になりますが、HTTPクライアントを差し替えることで数倍は伸びます
Kubernetesにデプロイする
helm chartがあるのでデプロイ手順を紹介します
デプロイ$ helm repo add deliveryhero https://charts.deliveryhero.io/
$ helm install locust deliveryhero/locust
$ kubectl get po
NAME READY STATUS RESTARTS AGE
locust-master-5f49f8dbb5-zbgjh 1/1 Running 0 4m5s
locust-worker-6467b4d58b-4kvxp 1/1 Running 0 4m5s
GUIにアクセス
$ kubectl port-forward service/locust 8089:8089
$ open http://0.0.0.0:8089
workerのCPUが確認できるのも便利
このままだとサンプルのタスクが反映されてたりするので、使いやすいようにカスタマイズ
$ kubectl create cm locustfile --from-file=locustfile.py
$ helm upgrade locust deliveryhero/locust \
--set loadtest.locust_locustfile=locustfile.py \
--set loadtest.locust_locustfile_configmap=locustfile \
--set loadtest.locust_host=https://foo.bar
# ingressもsetできるのでやっておくとport-forwardしなくて良くなる
タスクに変更があればこれで反映できる
$ kubectl create cm locustfile --from-file=locustfile.py --dry-run -o yaml | kubectl apply -f -
$ kubectl rollout restart deploy locust-master # workerもrestartする
あとはworkerを好きな数にスケールして負荷をかけていけばOK
$ kubectl scale deploy locust-worker --replicas=4
注意点としてはuserを増やしていくと一定数から線形にリクエスト数が増えないことがあったので、workerはCPUを見て多めにしておいてuser数はどんどん増やして試してみると良さそうです
failureが発生するようになれば負荷対象のシステムが耐えれなかったと判断できます
自分の環境で試したところ数万rpsはリクエストが投げれました
適切にスケールすればそれ以上も可能だと思います
Special Thanks
この記事を見てlocustを試すことにしました
感謝🙏
Discussion