Kubernetes

Kubernetes cluster에 Locust를 올려서 분산 부하 테스트한 후기

mokpolar 2023. 1. 8. 15:48
반응형

TL; DR

helm repo add deliveryhero https://charts.deliveryhero.io/
helm install deliveryhero/locust
kubectl create configmap my-loadtest-locustfile --from-file path/to/your/main.py
helm install locust deliveryhero/locust \
  --set loadtest.name=my-loadtest \
  --set loadtest.locust_locustfile_configmap=my-loadtest-locustfile

 

배경

Locust를 이용한 부하 테스트를 자주해야 하고 그 범위가 다양하다면 worker 수를 scalable 하게 다루고 싶어질 수 있다. 

그러면 역시 Kubernetes 위에 Locust를 올리자는 생각이 들 수 있다. 

 

쉽게 올릴 수 있게 누가 만들어둔 게 있을 것 같아서 찾아보니 역시나 있었다. 

Delivery Hero에서 만들고 유지하고 있는 도구가 있었다. 

 

사용하는 방식이 재미있고 간단해서 한번 써보고 후기를 남긴다. 

 

준비

  • K8S
  • Helm

helm chart를 사용하므로 helm이 준비가 되어있어야 한다. 

 

github repo는 이곳이다.

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

 

금일(23.1.8) 기준으로 1주일 전에도 업데이트가 이루어졌다. 

Locust의 메인테이너들이 관리하는 도구가 아니라는 사실에 유의할 필요가 있다. 

 

Delivery Hero의 public chart를 추가한다. 

helm repo add deliveryhero https://charts.deliveryhero.io/

Locust 네임스페이스를 생성해둔다.

kubectl create ns locust

 

 

설치

이 도구가 간단하고 재미있다고 생각했던 이유는 Configmap에 Python 코드를 넣어두고 데이터 볼륨으로 마운트해서 사용하기 때문이다.

 

이걸 만든 분들이 예시로 올려둔 Locust 파일을 보자. 

https://github.com/deliveryhero/helm-charts/blob/master/stable/locust/locustfiles/example/main.py

 

이렇게 생긴 파일이다.

from locust import HttpUser, task, between
from lib.example_functions import choose_random_page


default_headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}


class WebsiteUser(HttpUser):
    wait_time = between(1, 2)

    @task(1)
    def get_index(self):
        self.client.get("/", headers=default_headers)

    @task(3)
    def get_random_page(self):
        self.client.get(choose_random_page(), headers=default_headers)

이걸 대충 configmap으로 만들어서 올리면

kubectl -n locust create configmap my-loadtest-locustfile --from-file path/to/your/main.py

 

아래와 같이 configmap에 데이터로 들어간 모습을 볼 수 있다. 

kubectl -n locust describe cm example-locustfile

Name:         example-locustfile
Namespace:    locust
Labels:       app.kubernetes.io/instance=locust
              app.kubernetes.io/managed-by=Helm
              app.kubernetes.io/name=locust
              app.kubernetes.io/version=2.12.1
              helm.sh/chart=locust-0.30.0
              load_test=example
Annotations:  meta.helm.sh/release-name: locust
              meta.helm.sh/release-namespace: locust

Data
====
main.py:
----
# -*- coding: utf-8 -*-

from locust import HttpUser, task, between
from lib.example_functions import choose_random_page


default_headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}


class WebsiteUser(HttpUser):
    wait_time = between(1, 2)

    @task(1)
    def get_index(self):
        self.client.get("/", headers=default_headers)

    @task(3)
    def get_random_page(self):
        self.client.get(choose_random_page(), headers=default_headers)


BinaryData
====

Events:  <none>

 

이렇게 Locust 파일을 Configmap으로 다루면 다소 멋지지 못한(?) 모습일 수는 있으나 간단하게 수작업으로 관리하기에는 쉬운 것 같다. 

 

그 다음에는 방금 생성한 configmap을 사용하도록 set 옵션으로 configmap 이름을 넣고 설치하면 된다. 

helm -n locust install locust deliveryhero/locust \
  --set loadtest.name=my-loadtest \
  --set loadtest.locust_locustfile_configmap=my-loadtest-locustfile

 

그럼 이런 식으로 locust-master와 locust-worker pod들이 배포가 된 모습을 볼 수 있을 것이다. 

kubectl get pod -n locust
NAME                             READY   STATUS    RESTARTS      AGE
locust-master-5c95995697-8vv5p   1/1     Running   0             1m
locust-worker-76fd466554-b457f   1/1     Running   0             1m
locust-worker-76fd466554-jf75k   1/1     Running   0             1m
locust-worker-76fd466554-qkg9l   1/1     Running   0             1m

 

그리고 pod에 접근해보면 데이터볼륨으로 사용된 configmap이 해당 pod의 /mnt/locust 경로로 마운트된 모습을 볼 수 있다.

kubectl -n locust exec -it locust-master-5c95995697-8vv5p -- bash

$ ls /mnt/locust/
lib  main.py

 

그리고 locust 라는 이름의 Service도 하나 생성이 될텐데 이걸 통해서 Locust 화면으로 접근하면 된다. 

AWS 등을 사용한다면 로드밸런서로 바꿔줘도 좋겠다. 

kubectl get svc -n locust
NAME     TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                        
locust   LoadBalancer   XXX.XXX.X.X    XXX.XXX.com   5557:30977/TCP,5558:31427/TCP,8089:32441/TCP

 

그러면 아래와 같이 Locust 페이지에 쉽게 접근해서 사용할 수가 있다.

 

설치 옵션

Locust 자체를 다루는 건 다소 제한적일 수는 있다. 

Delivery Hero 분들이 작동하도록 해둔 value들을 사용해야 한다. 

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

 

해당 value를 이용하고 싶다면 아래와 같이 반영하면 된다.

helm install locust deliveryhero/locust \
  --set loadtest.name=my-loadtest \
  --set loadtest.locust_locustfile_configmap=my-loadtest-locustfile \
  --set worker.replicas=3 \
  --set master.logLevel=DEBUG \
  --set worker.logLevel=DEBUG

 

Reference

반응형