💪

LocustをKubernetesに構築して大規模な負荷テストをする

2022/05/15に公開

TL;DR

locustはhelmで簡単にapplyできる

$ helm repo add deliveryhero https://charts.deliveryhero.io/
$ helm install locust deliveryhero/locust

https://github.com/deliveryhero/helm-charts/tree/master/stable/locust

大規模な負荷テストをしたい

システムに負荷をかける際にvegetaを使うことが多いのですが、数千rpsでファイルディスクリプタの枯渇やCPUなどクライアントがボトルネックになることが多い
複数インスタンス立てればいいんだけど、環境構築が面倒だしテスト結果の集計などもっと楽をしたかった
locustを触ってみて、シンプルな使い勝手やGUI、レポート機能、workerをスケールできることなどからk8sに構築することにした

locustの使い方

まずはlocustの紹介
https://docs.locust.io/en/stable/
インストール

$ brew install locust # pip3 install locust でもOK

タスクを記述したファイルを用意(詳細はこちら

locustfile.py
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クライアントを差し替えることで数倍は伸びます
https://docs.locust.io/en/stable/increase-performance.html

Kubernetesにデプロイする

helm chartがあるのでデプロイ手順を紹介します
https://github.com/deliveryhero/helm-charts/tree/master/stable/locust
デプロイ

$ 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を試すことにしました
感謝🙏
https://zenn.dev/empenguin/articles/eda7535aeb0977

Discussion