클라우드 컴퓨팅 & NoSQL

오픈소스 부하테스트툴 Locust #2 - 분산 부하 테스팅 (with 쿠버네티스)

Terry Cho 2019. 12. 30. 23:17

Locust 와 쿠버네티스를 이용한 분산 부하 테스트

조대협 (http://bcho.tistory.com)

분산 부하 테스트

locust는 여러개의 worker를 이용하여, 부하를 대량으로 발생 시키는 분산 부하 테스트가 가능하다. 특히 분산 클러스터 구성 설정이 매우 간단하다는 장점을 가지고 있다. 


마스터 노드의 경우에는 아래와 같이 --master 옵션을 지정하여 마스터 노드로 구동하면 되고, 

% locust -f {task file name} --host={target host address} --master


워커 노드의 경우에는 실행 모드를 slave로 하고, 마스터 노드의 주소만 명시해주면 된다. 

% locust -f {task file name} --host={target host address} --slave --master-host={master node의 주소}


이렇게 클러스터를 구성하면 아래와 같은 구조를 갖는다


특히 워크노드를 추가할때 별도의 설정이 필요없이 워커노드를 추가하면서 마스터 노드의 주소만 주면 되기 때문에, 스케일링이 편리하다. 

쿠버네티스에서 분산 부하 테스트

설정이 간단하고, 부하 테스트의 특성상 필요할때만 클러스터를 설치했다가 사용이 끝나면 없애는 구조로 사용을 하려면, 쿠버네티스에서 기동하면 매우 편리하다. 


특히 설치 및 설정을 Helm Chart로 만들어놓으면, 필요할때 마다 손쉽게 locust 클러스터를 설치했다가 사용이 끝나면 손쉽게 지울 수 있는데, Helm 공식 리파지토리에 등록된 locust chart는 https://github.com/helm/charts/tree/master/stable/locust 아쉽게도 locust 0.9를 기준으로 한다. 현재는 1.3 버전이 최신 버전인데, 0.9와 1.3은 설정고 TaskSet의 코딩 방식이 다소 변경되서, locust 0.9를 사용하게 되면, 현재 메뉴얼에 있는 일부 코드들을 사용할 수 없다. 

그래서, 스스로 Helm Chart를 만들어서 사용하기를 권장한다. 


좋은 소식중의 하나는 구글 클라우드에서 Locust 를 쿠버네티스에서 분산 부하 테스팅을 할 수 있는 가이드 문서를 제공하고 있으니, 이를 참조하면 손쉽게 사용이 가능하다.

https://cloud.google.com/solutions/distributed-load-testing-using-gke

단, helm chart 형태로는 제공하지 않으니, 스스로 Chart를 만들기를 권장한다. Chart를 만들때 기존 Chart 구조를 참고하기를 권장하는데, https://github.com/helm/charts/tree/master/stable/locust 를 보면, locust의 이미지 버전이나, 설정을 Helm의 values.yaml로 빼거나 또는 CLI parameter로 처리할 수 있게 하였고, 특히 아래 task files를 설정하는 방법이 매우 흥미로운데, 


task file을 도커 이미지 내에 넣는 방식이 아니라 file (또는 directory) 형태의 configmap으로 빼서, locust pod가 기동될때, 이 파일(디렉토리)를 마운트해서 스크립트를 읽어서 적용하는 구조를 가지고 있다.


위에서 언급한 구글 클라우드 플랫폼의 가이드는 task 파일을 docker 이미지로 매번 빌드하기 때문에, 다소 설치가 복잡해질 수 있다는 단점이 있다. 


그러면 구글 클라우드 플랫폼에서 제공하는 예제 파일들을 살펴보자

https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes 리포에 저장이 되어 있는데, 

/docker-image 디렉토리

이 디렉토리에는 locust 도커 컨테이너를 만들기 위한 설정 파일들이 들어 있다. 

Dockerfile의 내용을 보면 아래와 같다.

# Start with a base Python 3.7.2 image

FROM python:3.7.2

 

# Add the licenses for third party software and libraries

ADD licenses /licenses

 

# Add the external tasks directory into /tasks

ADD locust-tasks /locust-tasks

 

# Install the required dependencies via pip

RUN pip install -r /locust-tasks/requirements.txt

 

# Expose the required Locust ports

EXPOSE 5557 5558 8089

 

# Set script to be executable

RUN chmod 755 /locust-tasks/run.sh

 

# Start Locust using LOCUS_OPTS environment variable

ENTRYPOINT ["/locust-tasks/run.sh"]


주의 깊게 살펴볼 부분은 아래 두줄이다. 

ADD locust-tasks /locust-tasks

RUN pip install -r /locust-tasks/requirements.txt


첫번째는 locust task 스크립트를 /locust-tasks 디렉토리에 복사하는 부분이다. 

그리고 두번째는 스크립트에서 사용하는 파이썬 라이브러리를 설치하는 부분이다. 

kubernetes-config 디렉토리


locust-master-controller.yaml

apiVersion: "extensions/v1beta1"

kind: "Deployment"

metadata:

 name: locust-master

 labels:

   name: locust-master

spec:

 replicas: 1

 selector:

   matchLabels:

     app: locust-master

 template:

   metadata:

     labels:

       app: locust-master

   spec:

     containers:

       - name: locust-master

         image: gcr.io/[PROJECT_ID]/locust-tasks:latest

         env:

           - name: LOCUST_MODE

             value: master

           - name: TARGET_HOST

             value: https://[TARGET_HOST]

         ports:

           - name: loc-master-web

             containerPort: 8089

             protocol: TCP

           - name: loc-master-p1

             containerPort: 5557

             protocol: TCP

           - name: loc-master-p2

             containerPort: 5558

             protocol: TCP


이 파일은 master node를 배포하기 위한 deployment 정의다. 주의 깊게 살펴볼 부분은 아래 두 라인이다. image는 앞에서 만든 task 스크립트가 포함된 locust 도커 이미지를 정의 하는 부분이고, 두번째는 부하 테스트 대상이 되는 타겟 호스트 주소를 정의하는 부분이다. 


image: gcr.io/[PROJECT_ID]/locust-tasks:latest

value: https://[TARGET_HOST]


다음은 locust-master-service.yaml 파일이다.

kind: Service

apiVersion: v1

metadata:

 name: locust-master

 labels:

   app: locust-master

spec:

 ports:

   - port: 8089

     targetPort: loc-master-web

     protocol: TCP

     name: loc-master-web

   - port: 5557

     targetPort: loc-master-p1

     protocol: TCP

     name: loc-master-p1

   - port: 5558

     targetPort: loc-master-p2

     protocol: TCP

     name: loc-master-p2

 selector:

   app: locust-master

 type: LoadBalancer


앞서 정의한 master node를 External IP (Load Balancer)로 밖으로 빼서, 웹 콘솔 접속등을 가능하게 하는 설정인데, 주의할점은 locust 웹 콘솔은 별도의 사용자 인증 기능이 없기 때문에, 위의 설정을 그대로 사용하면, 인증 기능이 없는 웹콘솔이 인터넷에 그래도 노출이 되기 때문에, 권장하지 않는다.


ClusterIP로 Service를 정의한 후, kubectl의 port forwarding 기능을 사용하거나 또는 앞에 인증용 프록시 서버를 두는 것을 권장한다. 구글 클라우드의 경우에는 Identity Aware Proxy(IAP)라는 기능을 이용하여, 구글 클라우드 계정으로 로그인을 해야 웹사이트를 접근할 수 있는 프록시 기능을 제공한다. 


마지막으로 locust-worker-controller.yaml 파일을 정의한다.

# Copyright 2015 Google Inc. All rights reserved.

#

# Licensed under the Apache License, Version 2.0 (the "License");

# you may not use this file except in compliance with the License.

# You may obtain a copy of the License at

#

#     http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License.

 

apiVersion: "extensions/v1beta1"

kind: "Deployment"

metadata:

 name: locust-worker

 labels:

   name: locust-worker

spec:

 replicas: 5

 selector:

   matchLabels:

     app: locust-worker

 template:

   metadata:

     labels:

       app: locust-worker

   spec:

     containers:

       - name: locust-worker

         image: gcr.io/[PROJECT_ID]/locust-tasks:latest

         env:

           - name: LOCUST_MODE

             value: worker

           - name: LOCUST_MASTER

             value: locust-master

           - name: TARGET_HOST

             value: https://[TARGET_HOST]

 


이 파일을 worker node 에 대항 설정으로 master node와 마찬가지로 target_host와 locust 이미지 경로만 지정해주면 된다. 


이 파일들을 배포하면, locust 가 실행 준비가 되고, 앞에서 정의한 master node의 서비스 주소로 접속하면 locust 웹 콘솔을 이용하여 부하 테스트를 진행할 수 있다. 


만약 동적으로 locust worker node의 수를 조절하고 싶으면, 

% kubectl scale deployment/locust-worker --replicas=20


명령을 이용하여 worker node pod의 수를 조절할 수 있다.