2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LocustをKubernetes内でUIおよびHeadlessモードで使う

Last updated at Posted at 2023-08-13

LocustはPythonベースの負荷試験ツールで、JMeterやTsungの不満を解消するために作られており、有名どころのサービスの負荷試験にも使われているらしい。
これ、使ってみると非常に便利だが、Kubernetes向けの導入方法が'23/8時点では見当たらなかった
負荷対象がkind: Ingress等で外部にサービスを公開していればいいが、公開されておらずkind: Service+type: ClusterIP経由でアクセスしたい場合とかはクラスタ内部から負荷を掛ける必要がある。
今回はそのための確認を行った時のメモ。
Locustを使うシーンとしては、UIから手動で実行するケースと、UIなし(Headless)で自動で実行するケースが考えられるため、それぞれKubernetesで動かしてみる。

なお、ここでの確認手順はk8sのディストリビューションに依存しないため、どのk8s環境でも利用できる。はず。

WebUIのLocustコンテナを動かす

元々Locustのイメージが提供されているので、それを使う。
最初に、locustfile.pyをConfigMapで定義する。
テストケースに応じて差し替えるとよい、

cat << EOF > ./locustfile.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: locustfile
data:
  locustfile.py: |
    from locust import HttpUser, task
    
    class LocustTest(HttpUser):
        @task
        def test_case1(self):
            self.client.get("/")
EOF

Locust本体をDeploymentServiceで定義する。locustfile.pyConfigMapをmountして-fで渡す。

cat << EOF > ./locust.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: locust
spec:
  replicas: 1
  selector:
    matchLabels:
      app: locust
  template:
    metadata:
      labels:
        app: locust
    spec:
      containers:
      - name: locust
        image: locustio/locust
        args:
        - -f
        - /mnt/locust/locustfile.py
        ports:
        - containerPort: 8089
        volumeMounts:
        - name: locustfile-volume
          mountPath: /mnt/locust
      volumes:
      - name: locustfile-volume
        configMap:
          name: locustfile
---
apiVersion: v1
kind: Service
metadata:
  name: locust
spec:
  selector:
    app: locust
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8089
  type: LoadBalancer
EOF

それぞれデプロイし、LocustのExternalIPを確認する。

kubectl apply -f ./locust.yaml -f ./locustfile.yaml
kubectl get svc locust -o jsonpath={.status.loadBalancer.ingress[0].ip}

ExternalIPにアクセスすると、無事にUIが表示される。ここでは試しにdefaultのNamespaceに立てたnginxに対して負荷を掛けてみる。
1691880405785.png
実行すると、Failsにカウントが増えることなくリクエストが処理されており、問題ないことが確認できた。
1691880447669.png

Headlessモードで動かす

Locustは--headlessを付けて実行すると、Headlessモードとして動作し、指定の負荷を実行した後に終了する。
コマンドとしては以下のような感じになる。

locust --headless -H $TARGET_URL -u $NUM_USERS -r $SPAWN_RATE -t $RUN_TIME

オプションはそれぞれ以下の意味となる。

  • -H: Host
  • -u: 最大ユーザ数
  • -r: 1秒あたりの増加数
  • -t: 実行時間。これを過ぎるとコマンドは終了する。指定しないと無制限。

このオプションや環境変数を最初コマンドに渡そうと思ったが、この手の設定を設定ファイルとして用意して渡すことも出来る。

locust --config=master.conf

master.confには公式の記述によると、以下のような内容を記述でき、環境変数で設定したものがまとめて設定できるようになっている。。

locustfile = locust_files/my_locust_file.py
headless = true
master = true
expect-workers = 5
host = http://target-system
users = 100
spawn-rate = 10
run-time = 10m

ということで、上記のmaster.confをConfigMapで作成し、実行側はJobで作成してmountして利用する。
locustfile.pyとは別に以下のConfigMapを作成する。

cat << EOF > ./locust-master-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: locust-master-config
data:
  master.conf: |
    locustfile = /mnt/locust/locustfile.py
    headless = true
    host = http://nginx.default.svc
    users = 100
    spawn-rate = 10
    run-time = 10m
EOF

Jobは以下のようになる。

cat << 'EOF' > ./locust-headless.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: locust-headless
  labels:
    app: locust-headless
spec:
  backoffLimit: 1
  template:
    metadata:
      labels:
        app: locust-headless
    spec:
      restartPolicy: Never
      containers:
      - name: locust-headless
        image: locustio/locust
        args:
        - --config
        - /mnt/locust-master-config/master.conf
        volumeMounts:
        - name: locustfile-volume
          mountPath: /mnt/locust
        - name: locust-master-config
          mountPath: /mnt/locust-master-config
      volumes:
      - name: locustfile-volume
        configMap:
          name: locustfile
      - name: locust-master-config
        configMap:
          name: locust-master-config
EOF

起動する。ConfigMaplocustfileはUI確認時にデプロイ済みなのでここでは割愛しているが、必要なのでHeadless版から試している人はUI版で実施している内容を実施しておくこと。

kubectl apply -f ./locust-master-config.yaml -f ./locust-headless.yaml

ログを見ると、しっかり負荷が掛かっているようだ。

kubectl logs locust-headless-4sx25
[2023-08-12 23:51:26,093] locust-headless-4sx25/INFO/locust.main: Run time limit set to 600 seconds
[2023-08-12 23:51:26,094] locust-headless-4sx25/INFO/locust.main: Starting Locust 2.16.1
Type     Name                                                                          # reqs      # fails |    Avg     Min     Max    Med |   req/s  failures/s
--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
         Aggregated                                                                         0     0(0.00%) |      0       0       0      0 |    0.00        0.00

[2023-08-12 23:51:26,128] locust-headless-4sx25/INFO/locust.runners: Ramping to 100 users at a rate of 10.00 per second
Type     Name                                                                          # reqs      # fails |    Avg     Min     Max    Med |   req/s  failures/s
--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
GET      /                                                                               1057     0(0.00%) |     13       5      71     10 |    0.00        0.00
--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
         Aggregated                                                                      1057     0(0.00%) |     13       5      71     10 |    0.00        0.00
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?